module ForemanOpenscap module ComplianceStatusScopedSearch extend ActiveSupport::Concern module ClassMethods def policy_search(search_alias) scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => search_alias, :only_explicit => true end def search_by_comply_with(_key, _operator, policy_name) search_by_policy_results policy_name, &:passed end def search_by_not_comply_with(_key, _operator, policy_name) search_by_policy_results policy_name, &:failed end def search_by_inconclusive_with(_key, _operator, policy_name) search_by_policy_results policy_name, &:othered end def search_by_policy_results(policy_name, &selection) scope = ArfReport.of_policy(Policy.find_by(:name => policy_name).id) .instance_eval(&selection) query_conditions_from_scope scope end def search_by_rule_failed(key, operator, rule_name) search_by_rule rule_name, "fail" end def search_by_rule_passed(key, operator, rule_name) search_by_rule rule_name, "pass" end def search_by_rule_othered(key, operator, rule_name) search_by_rule rule_name, LogExtensions.othered_result_constants end def search_by_last_for(key, operator, by) by.gsub!(/[^[:alnum:]]/, '') case by.downcase when 'host' { :conditions => "reports.id IN ( SELECT MAX(id) FROM reports sub WHERE sub.type = 'ForemanOpenscap::ArfReport' AND sub.host_id = reports.host_id )" } when 'policy' { :conditions => 'reports.id IN ( SELECT latest.id FROM foreman_openscap_policies INNER JOIN (SELECT policy_id, MAX(reports.id) AS id FROM reports INNER JOIN foreman_openscap_policy_arf_reports ON reports.id = foreman_openscap_policy_arf_reports.arf_report_id GROUP BY policy_id ) latest ON foreman_openscap_policies.id = latest.policy_id)' } else raise "Cannot search last by #{by}" end end def search_by_compliance_status(key, operator, value) scope = case value when 'compliant' ArfReport.passed when 'incompliant' ArfReport.failed when 'inconclusive' ArfReport.othered end query_conditions_from_scope scope end def search_by_host_collection_name(key, operator, value) scope = apply_condition(::Host.joins(:host_collections), operator == '<>', :katello_host_collections => { :name => value }) query_conditions_from_scope ForemanOpenscap::ArfReport.where(:host_id => scope) end private def query_conditions_from_scope(scope) query = scope.select(ArfReport.arel_table[:id]).to_sql query_conditions query end def query_conditions(query) { :conditions => "reports.id IN (#{query})" } end def search_by_rule(rule_name, rule_result) query = ArfReport.by_rule_result(rule_name, rule_result) .select(ArfReport.arel_table[:id]).to_sql query_conditions query end def apply_condition(scope, negate, conditions) if negate scope.where.not(conditions) else scope.where(conditions) end end end included do if ForemanOpenscap.with_katello? has_one :lifecycle_environment, :through => :host has_many :host_collections, :through => :host scoped_search :relation => :lifecycle_environment, :on => :name, :complete_value => true, :rename => :lifecycle_environment scoped_search :relation => :host_collections, :on => :name, :complete_value => true, :rename => :host_collection, :operators => ['= ', '!= '], :ext_method => :search_by_host_collection_name end policy_search :compliance_policy policy_search :policy scoped_search :on => :id, :rename => :last_for, :complete_value => { :host => 0, :policy => 1 }, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_last_for scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :comply_with, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_comply_with scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :not_comply_with, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_not_comply_with scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :inconclusive_with, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_inconclusive_with scoped_search :relation => :openscap_proxy, :on => :name, :complete_value => true, :only_explicit => true, :rename => :openscap_proxy scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_name, :only_explicit => true, :operators => ['= '] scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_failed, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_failed scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_passed, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_passed scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_othered, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_othered scoped_search :on => :status, :rename => :compliance_status, :operators => ['= '], :ext_method => :search_by_compliance_status, :complete_value => { :compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT, :incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT, :inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE }, :validator => ->(value) { ['compliant', 'incompliant', 'inconclusive'].reduce(false) { |memo, item| memo || (item == value) } } end end end