foreman_openscap 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/foreman_openscap/load_report.js +1 -1
  3. data/app/assets/javascripts/foreman_openscap/policy_edit.js +0 -2
  4. data/app/controllers/api/v2/compliance/arf_reports_controller.rb +7 -22
  5. data/app/controllers/api/v2/compliance/policies_controller.rb +5 -5
  6. data/app/controllers/api/v2/compliance/scap_contents_controller.rb +3 -3
  7. data/app/controllers/arf_reports_controller.rb +62 -0
  8. data/app/controllers/{scaptimony_dashboard_controller.rb → compliance_dashboard_controller.rb} +1 -1
  9. data/app/controllers/compliance_hosts_controller.rb +5 -0
  10. data/app/controllers/{scaptimony_policies_controller.rb → policies_controller.rb} +13 -13
  11. data/app/controllers/{scaptimony_policy_dashboard_controller.rb → policy_dashboard_controller.rb} +3 -3
  12. data/app/controllers/{scaptimony_scap_contents_controller.rb → scap_contents_controller.rb} +11 -11
  13. data/app/helpers/{scaptimony_report_dashboard_helper.rb → arf_report_dashboard_helper.rb} +3 -5
  14. data/app/helpers/arf_reports_helper.rb +21 -0
  15. data/app/helpers/compliance_hosts_helper.rb +25 -0
  16. data/app/helpers/concerns/foreman_openscap/hosts_helper_extensions.rb +2 -32
  17. data/app/helpers/{scaptimony_policies_helper.rb → policies_helper.rb} +6 -2
  18. data/app/helpers/{scaptimony_policy_dashboard_helper.rb → policy_dashboard_helper.rb} +8 -8
  19. data/app/lib/proxy_api/available_proxy.rb +26 -0
  20. data/app/lib/proxy_api/openscap.rb +40 -0
  21. data/app/mailers/foreman_openscap/policy_mailer.rb +42 -0
  22. data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +91 -0
  23. data/app/models/concerns/foreman_openscap/host_extensions.rb +73 -17
  24. data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +3 -5
  25. data/app/models/foreman_openscap/arf_report.rb +165 -0
  26. data/app/models/foreman_openscap/asset.rb +27 -0
  27. data/app/models/foreman_openscap/asset_policy.rb +6 -0
  28. data/app/models/foreman_openscap/compliance_status.rb +50 -0
  29. data/app/models/{concerns/foreman_openscap/policy_extensions.rb → foreman_openscap/policy.rb} +72 -45
  30. data/app/models/foreman_openscap/policy_arf_report.rb +8 -0
  31. data/app/models/foreman_openscap/policy_revision.rb +6 -0
  32. data/app/models/foreman_openscap/scap_content.rb +112 -0
  33. data/app/models/foreman_openscap/scap_content_profile.rb +6 -0
  34. data/app/overrides/hosts/overview/host_compliance_status.rb +4 -4
  35. data/app/services/foreman_openscap/arf_report_status_calculator.rb +45 -0
  36. data/app/services/{scaptimony → foreman_openscap}/host_report_dashboard/data.rb +12 -6
  37. data/app/services/{scaptimony → foreman_openscap}/policy_dashboard/data.rb +5 -5
  38. data/app/services/{scaptimony → foreman_openscap}/report_dashboard/data.rb +4 -4
  39. data/app/views/api/v2/compliance/policies/create.json.rabl +3 -0
  40. data/app/views/{scaptimony_arf_reports → arf_reports}/_list.html.erb +4 -4
  41. data/app/views/arf_reports/_metrics.html.erb +37 -0
  42. data/app/views/arf_reports/_output.html.erb +23 -0
  43. data/app/views/{scaptimony_arf_reports → arf_reports}/index.html.erb +0 -0
  44. data/app/views/arf_reports/show.html.erb +14 -0
  45. data/app/views/{scaptimony_arf_reports/show.html.erb → arf_reports/show_html.html.erb} +2 -3
  46. data/app/views/compliance_hosts/_compliance_status.erb +6 -0
  47. data/app/views/{scaptimony_hosts → compliance_hosts}/show.html.erb +9 -2
  48. data/app/views/dashboard/{_foreman_openscap_host_reports_widget.html.erb → _compliance_host_reports_widget.html.erb} +3 -3
  49. data/app/views/dashboard/{_foreman_openscap_reports_breakdown_widget.html.erb → _compliance_reports_breakdown_widget.html.erb} +1 -1
  50. data/app/views/foreman_openscap/policy_mailer/_dashboard.erb +21 -0
  51. data/app/views/foreman_openscap/policy_mailer/_hosts.erb +44 -0
  52. data/app/views/foreman_openscap/policy_mailer/_list.erb +10 -0
  53. data/app/views/foreman_openscap/policy_mailer/_policy.erb +7 -0
  54. data/app/views/foreman_openscap/policy_mailer/policy_summary.erb +19 -0
  55. data/app/views/{scaptimony_policies → policies}/_form.html.erb +2 -8
  56. data/app/views/{scaptimony_policies → policies}/_list.html.erb +5 -5
  57. data/app/views/policies/_scap_content_results.html.erb +3 -0
  58. data/app/views/policies/create.html.erb +2 -0
  59. data/app/views/{scaptimony_policies → policies}/disassociate_multiple_hosts.html.erb +2 -2
  60. data/app/views/{scaptimony_policies → policies}/edit.html.erb +0 -0
  61. data/app/views/{scaptimony_policies → policies}/index.html.erb +1 -1
  62. data/app/views/policies/new.html.erb +2 -0
  63. data/app/views/{scaptimony_policies → policies}/select_multiple_hosts.html.erb +2 -2
  64. data/app/views/{scaptimony_policies → policies}/show.html.erb +1 -1
  65. data/app/views/{scaptimony_policies → policies}/steps/_create_policy_form.html.erb +0 -0
  66. data/app/views/{scaptimony_policies → policies}/steps/_hostgroups_form.html.erb +0 -0
  67. data/app/views/{scaptimony_policies → policies}/steps/_locations_form.html.erb +0 -0
  68. data/app/views/{scaptimony_policies → policies}/steps/_organizations_form.html.erb +0 -0
  69. data/app/views/policies/steps/_scap_content_form.html.erb +9 -0
  70. data/app/views/{scaptimony_policies → policies}/steps/_schedule_form.html.erb +1 -1
  71. data/app/views/{scaptimony_policies → policies}/steps/_step_form.html.erb +3 -3
  72. data/app/views/{scaptimony_policies → policies}/welcome.html.erb +2 -2
  73. data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/_policy_chart_widget.html.erb +0 -0
  74. data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/_policy_reports.html.erb +2 -2
  75. data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/_policy_status_widget.html.erb +3 -3
  76. data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/index.html.erb +0 -0
  77. data/app/views/{scaptimony_scap_contents → scap_contents}/_form.html.erb +5 -6
  78. data/app/views/{scaptimony_scap_contents → scap_contents}/_list.html.erb +3 -3
  79. data/app/views/{scaptimony_scap_contents → scap_contents}/edit.html.erb +0 -0
  80. data/app/views/{scaptimony_scap_contents → scap_contents}/index.html.erb +1 -1
  81. data/app/views/{scaptimony_scap_contents → scap_contents}/new.html.erb +0 -0
  82. data/app/views/{scaptimony_scap_contents → scap_contents}/welcome.html.erb +2 -2
  83. data/config/routes.rb +15 -11
  84. data/db/migrate/20141013172051_create_scaptimony_policies.rb +9 -0
  85. data/db/migrate/20141014105333_create_scaptimony_assets.rb +10 -0
  86. data/db/migrate/20141015092642_create_scaptimony_arf_reports.rb +13 -0
  87. data/db/migrate/20141015115511_add_arf_report_unique_constraint.rb +6 -0
  88. data/db/migrate/20141104164201_create_scaptimony_scap_contents.rb +7 -0
  89. data/db/migrate/20141104171545_create_scaptimony_policy_revisions.rb +14 -0
  90. data/db/migrate/20141105174625_add_description_to_scaptimony_policy_revisions.rb +5 -0
  91. data/db/migrate/20141105174834_add_columns_to_scaptimony_policies.rb +12 -0
  92. data/db/migrate/20141107091756_add_columns_to_scaptimony_scap_contents.rb +8 -0
  93. data/db/migrate/20141111104519_add_constraint_to_scaptimony_scap_contents.rb +5 -0
  94. data/db/migrate/20141113221054_create_scaptimony_scap_content_profiles.rb +12 -0
  95. data/db/migrate/20141116170632_remove_xccdf_profile_from_scaptimony_policies.rb +5 -0
  96. data/db/migrate/20141116171305_add_profile_to_scaptimony_policies.rb +6 -0
  97. data/db/migrate/20141118142954_add_constraint_to_scaptimony_policies.rb +5 -0
  98. data/db/migrate/20141119164918_create_scaptimony_xccdf_results.rb +8 -0
  99. data/db/migrate/20141119175434_create_scaptimony_xccdf_rules.rb +8 -0
  100. data/db/migrate/20141119182606_create_scaptimony_xccdf_rule_results.rb +9 -0
  101. data/db/migrate/20141121120326_create_scaptimony_arf_report_breakdowns.rb +24 -0
  102. data/db/migrate/20141121164042_replace_arf_report_breakdown_view.rb +25 -0
  103. data/db/migrate/20141206211151_create_scaptimony_assets_policies.rb +9 -0
  104. data/db/migrate/20141214112917_add_scap_file_to_scap_content.rb +5 -0
  105. data/db/migrate/20141216154502_rename_scaptimony_asset_policies.rb +5 -0
  106. data/db/migrate/20150111085317_polymorph_asset.rb +8 -0
  107. data/db/migrate/20150112152944_create_scaptimony_arf_report_raws.rb +10 -0
  108. data/db/migrate/20150114210634_rename_scaptimony_arf_report_raw_raw.rb +5 -0
  109. data/db/migrate/20150115155947_add_scaptimony_scap_content_digest.rb +21 -0
  110. data/db/migrate/20150116083129_add_day_of_month_and_cron_line_to_scaptimony_policy.rb +6 -0
  111. data/db/migrate/20150821100137_migrate_from_scaptimony.rb +59 -0
  112. data/db/migrate/20150827123826_remove_scaptimony_permissions.rb +21 -0
  113. data/db/migrate/20150925124959_create_policy_arf_reports.rb +13 -0
  114. data/db/migrate/20150929124853_add_result_to_logs.rb +9 -0
  115. data/db/migrate/20150929152345_move_arf_reports_to_reports_table.rb +179 -0
  116. data/db/migrate/20151023131950_link_arf_report_directly_to_host.rb +17 -0
  117. data/db/seeds.d/openscap_policy_notification.rb +9 -0
  118. data/lib/foreman_openscap/bulk_upload.rb +3 -1
  119. data/lib/foreman_openscap/engine.rb +53 -42
  120. data/lib/foreman_openscap/helper.rb +8 -0
  121. data/lib/foreman_openscap/version.rb +1 -1
  122. data/lib/tasks/foreman_openscap_tasks.rake +14 -0
  123. data/test/factories/arf_report_factory.rb +9 -6
  124. data/test/factories/asset_factory.rb +1 -1
  125. data/test/factories/compliance_host_factory.rb +9 -0
  126. data/test/factories/compliance_log_factory.rb +11 -0
  127. data/test/factories/policy_arf_report_factory.rb +6 -0
  128. data/test/factories/policy_factory.rb +3 -2
  129. data/test/factories/scap_content_related.rb +2 -2
  130. data/test/functional/api/v2/compliance/arf_reports_controller_test.rb +4 -3
  131. data/test/functional/api/v2/compliance/policies_controller_test.rb +2 -2
  132. data/test/functional/api/v2/compliance/scap_contents_controller_test.rb +3 -1
  133. data/test/lib/foreman_openscap/bulk_upload_test.rb +1 -1
  134. data/test/test_plugin_helper.rb +30 -0
  135. data/test/unit/arf_report_status_calculator_test.rb +11 -0
  136. data/test/unit/arf_report_test.rb +148 -0
  137. data/test/unit/compliance_status_test.rb +71 -0
  138. data/test/unit/openscap_host_test.rb +38 -7
  139. data/test/unit/policy_mailer_test.rb +38 -0
  140. data/test/unit/scap_content_test.rb +32 -0
  141. metadata +130 -74
  142. data/app/controllers/scaptimony_arf_reports_controller.rb +0 -34
  143. data/app/controllers/scaptimony_hosts_controller.rb +0 -5
  144. data/app/models/concerns/foreman_openscap/arf_report_extensions.rb +0 -50
  145. data/app/models/concerns/foreman_openscap/asset_extensions.rb +0 -34
  146. data/app/models/concerns/foreman_openscap/scap_content_extensions.rb +0 -40
  147. data/app/overrides/hosts/index/host_arf_report.rb +0 -5
  148. data/app/views/scaptimony_arf_reports/_host_report.html.erb +0 -8
  149. data/app/views/scaptimony_hosts/_host_status.html.erb +0 -17
  150. data/app/views/scaptimony_policies/_scap_content_results.html.erb +0 -7
  151. data/app/views/scaptimony_policies/create.html.erb +0 -2
  152. data/app/views/scaptimony_policies/new.html.erb +0 -2
  153. data/app/views/scaptimony_policies/steps/_scap_content_form.html.erb +0 -17
@@ -0,0 +1,25 @@
1
+ module ComplianceHostsHelper
2
+
3
+ def host_policy_breakdown_chart(report, options = {})
4
+ data = []
5
+ [[:passed, _('Passed')],
6
+ [:failed, _('Failed')],
7
+ [:othered, _('Other')],
8
+ ].each { |i|
9
+ data << {:label => i[1], :data => report[i[0]], :color => ArfReportDashboardHelper::COLORS[i[0]]}
10
+ }
11
+ flot_pie_chart 'overview', _('Compliance reports breakdown'), data, options
12
+ end
13
+
14
+ def host_arf_reports_chart(policy_id)
15
+ passed, failed, othered, = [], [], []
16
+ @host.arf_reports.of_policy(policy_id).each do |report|
17
+ passed << [report.created_at.to_i*1000, report.passed]
18
+ failed << [report.created_at.to_i*1000, report.failed]
19
+ othered << [report.created_at.to_i*1000, report.othered]
20
+ end
21
+ [{:label => _("Passed"), :data => passed, :color => ArfReportDashboardHelper::COLORS[:passed]},
22
+ {:label => _("Failed"), :data => failed, :color => ArfReportDashboardHelper::COLORS[:failed]},
23
+ {:label => _("Othered"), :data => othered, :color => ArfReportDashboardHelper::COLORS[:othered]}]
24
+ end
25
+ end
@@ -7,39 +7,9 @@ module ForemanOpenscap
7
7
  alias_method_chain :name_column, :scap
8
8
  end
9
9
 
10
- Colors = {
11
- :passed => '#89A54E',
12
- :failed => '#AA4643',
13
- :othered => '#DB843D',
14
- }
15
-
16
10
  def multiple_actions_with_scap
17
- multiple_actions_without_scap + [[_('Assign Compliance Policy'), select_multiple_hosts_scaptimony_policies_path],
18
- [_('Unassign Compliance Policy'), disassociate_multiple_hosts_scaptimony_policies_path]]
19
-
20
- end
21
-
22
- def host_policy_breakdown_chart(report, options = {})
23
- data = []
24
- [[:passed, _('Passed')],
25
- [:failed, _('Failed')],
26
- [:othered, _('Other')],
27
- ].each { |i|
28
- data << {:label => i[1], :data => report[i[0]], :color => Colors[i[0]]}
29
- }
30
- flot_pie_chart 'overview', _('Compliance reports breakdown'), data, options
31
- end
32
-
33
- def host_arf_reports_chart(policy_id)
34
- passed, failed, othered, = [], [], []
35
- @host.arf_reports.of_policy(policy_id).each do |report|
36
- passed << [report.created_at.to_i*1000, report.passed]
37
- failed << [report.created_at.to_i*1000, report.failed]
38
- othered << [report.created_at.to_i*1000, report.othered]
39
- end
40
- [{:label => _("Passed"), :data => passed, :color => Colors[:passed]},
41
- {:label => _("Failed"), :data => failed, :color => Colors[:failed]},
42
- {:label => _("Othered"), :data => othered, :color => Colors[:othered]}]
11
+ multiple_actions_without_scap + [[_('Assign Compliance Policy'), select_multiple_hosts_policies_path],
12
+ [_('Unassign Compliance Policy'), disassociate_multiple_hosts_policies_path]]
43
13
  end
44
14
 
45
15
  def name_column_with_scap(record)
@@ -1,4 +1,4 @@
1
- module ScaptimonyPoliciesHelper
1
+ module PoliciesHelper
2
2
  def profiles_selection
3
3
  return @scap_content.scap_content_profiles unless @scap_content.blank?
4
4
  return @policy.scap_content.scap_content_profiles unless @policy.scap_content.blank?
@@ -6,7 +6,7 @@ module ScaptimonyPoliciesHelper
6
6
  end
7
7
 
8
8
  def scap_content_selector(form)
9
- scap_contents = Scaptimony::ScapContent.all
9
+ scap_contents = ::ForemanOpenscap::ScapContent.all
10
10
  if scap_contents.length > 1
11
11
  select_f form, :scap_content_id, scap_contents, :id, :title,
12
12
  {:include_blank => _("Choose existing SCAP Content")} ,
@@ -65,4 +65,8 @@ module ScaptimonyPoliciesHelper
65
65
  link_to((previous).html_safe, '#', :class => 'btn btn-default', :onclick => "previous_step('#{@policy.previous_step}')")
66
66
  end
67
67
  end
68
+
69
+ def days_of_week_hash
70
+ Hash[*Date::DAYNAMES.map{ |day| [day.downcase, day]}.flatten]
71
+ end
68
72
  end
@@ -8,16 +8,16 @@
8
8
  # along with this software; if not, see http://www.gnu.org/licenses/gpl.txt
9
9
  #
10
10
 
11
- module ScaptimonyPolicyDashboardHelper
12
- Colors = {
13
- :compliant_hosts => '#89A54E',
14
- :incompliant_hosts => '#AA4643',
15
- :inconclusive_hosts => '#DB843D',
11
+ module PolicyDashboardHelper
12
+ COLORS = {
13
+ :compliant_hosts => ArfReportDashboardHelper::COLORS[:passed],
14
+ :incompliant_hosts => ArfReportDashboardHelper::COLORS[:failed],
15
+ :inconclusive_hosts => ArfReportDashboardHelper::COLORS[:othered],
16
16
  :report_missing => '#92A8CD',
17
17
  }
18
18
 
19
19
  def policy_widget_list
20
- Scaptimony::PolicyDashboard::Manager.widgets
20
+ ForemanOpenscap::PolicyDashboard::Manager.widgets
21
21
  end
22
22
 
23
23
  def host_breakdown_chart(report, options = {})
@@ -27,14 +27,14 @@ module ScaptimonyPolicyDashboardHelper
27
27
  [:inconclusive_hosts, _('Inconclusive')],
28
28
  [:report_missing, _('Not audited')],
29
29
  ].each { |i|
30
- data << {:label => i[1], :data => report[i[0]], :color => Colors[i[0]]}
30
+ data << {:label => i[1], :data => report[i[0]], :color => COLORS[i[0]]}
31
31
  }
32
32
  flot_pie_chart 'overview', _('Compliance Status'), data, options
33
33
  end
34
34
 
35
35
  def status_link(name, label, path)
36
36
  content_tag :li do
37
- content_tag(:i, raw('&nbsp;'), :class=>'label', :style => 'background-color:' + Colors[label]) +
37
+ content_tag(:i, raw('&nbsp;'), :class=>'label', :style => 'background-color:' + COLORS[label]) +
38
38
  raw('&nbsp;') +
39
39
  link_to(name, path, :class=>'dashboard-links') +
40
40
  content_tag(:h4, @report[label])
@@ -0,0 +1,26 @@
1
+ module ::ProxyAPI
2
+ class AvailableProxy
3
+
4
+ HTTP_ERRORS = [
5
+ EOFError,
6
+ Errno::ECONNRESET,
7
+ Errno::EINVAL,
8
+ Net::HTTPBadResponse,
9
+ Net::HTTPHeaderSyntaxError,
10
+ Net::ProtocolError,
11
+ Timeout::Error
12
+ ]
13
+
14
+ def initialize(args)
15
+ @features = ::ProxyAPI::Features.new(args).features
16
+ end
17
+
18
+ def available?
19
+ begin
20
+ return true if @features.include?('openscap')
21
+ rescue *HTTP_ERRORS
22
+ return false
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ module ::ProxyAPI
2
+ class Openscap < ::ProxyAPI::Resource
3
+ def initialize(args)
4
+ @url = args[:url] + '/compliance/'
5
+ super args
6
+ @connect_params[:headers].merge!(:content_type => :xml)
7
+ end
8
+
9
+ def fetch_policies_for_scap_content(scap_file)
10
+ parse(post(scap_file, "scap_content/policies"))
11
+ end
12
+
13
+ def validate_scap_content(scap_file)
14
+ parse(post(scap_file, "scap_content/validator"))
15
+ end
16
+
17
+ def policy_html_guide(scap_file, policy)
18
+ guide = parse(post(scap_file, "scap_content/guide/#{policy}"))
19
+ guide['html']
20
+ end
21
+
22
+ def arf_report_html(report, cname)
23
+ begin
24
+ @connect_params[:headers] = { :accept => 'application/html' }
25
+ get "/arf/#{report.id}/#{cname}/#{report.reported_at.to_i}/#{report.policy_arf_report.digest}/html"
26
+ rescue => e
27
+ raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to get html version of requested report from Smart Proxy"))
28
+ end
29
+ end
30
+
31
+ def arf_report_bzip(report, cname)
32
+ begin
33
+ @connect_params[:headers] = { :content_type => 'application/arf-bzip2', :content_encoding => 'x-bzip2' }
34
+ get "/arf/#{report.id}/#{cname}/#{report.reported_at.to_i}/#{report.policy_arf_report.digest}/xml"
35
+ rescue => e
36
+ raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to get xml version of requested report from Smart Proxy"))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,42 @@
1
+ module ForemanOpenscap
2
+ class PolicyMailer < ::ApplicationMailer
3
+
4
+ def policy_summary(options = {})
5
+ set_url
6
+ user = ::User.find(options[:user])
7
+ @time = options[:time] || 1.day.ago
8
+
9
+ @policies = ::ForemanOpenscap::Policy.all.reject {|policy| policy.assets.map(&:host).compact.empty?}
10
+ @compliant_hosts = @policies.map { |policy| Host.where(:id => policy.assets.comply_with(policy).map(&:assetable_id)) }.flatten
11
+ @incompliant_hosts = @policies.map { |policy| Host.where(:id => policy.assets.incomply_with(policy).map(&:assetable_id)) }.flatten
12
+ changed_hosts_of_policies(@policies)
13
+
14
+ if user.nil? || user.mail.nil?
15
+ logger.warn "User with valid email not supplied, mail report will not be sent"
16
+ else
17
+ set_locale_for(user) do
18
+ subject = _("Scap policies summary")
19
+ mail(:to => user.mail, :subject => subject)
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def changed_hosts_of_policies(policies)
27
+ hash = @policies.inject({}) do |result, policy|
28
+ result[policy.id] = policy.hosts
29
+ result
30
+ end
31
+
32
+ @changed_hosts = []
33
+ hash.each do |key, values|
34
+ values.each do |host|
35
+ @changed_hosts << host if host.scap_status_changed?(::ForemanOpenscap::Policy.find key)
36
+ end
37
+ end
38
+ @changed_hosts.uniq
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,91 @@
1
+ module ForemanOpenscap
2
+ module ComplianceStatusScopedSearch
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def compliance_status_scoped_search(status, options = {})
7
+ options.merge!(:offset => ArfReport::METRIC.index(status.to_s), :word_size => ArfReport::BIT_NUM)
8
+ scoped_search options
9
+ end
10
+
11
+ def search_by_policy_name(_key, _operator, policy_name)
12
+ cond = sanitize_policy_name(policy_name)
13
+ { :conditions => ArfReport.arel_table[:id].in(
14
+ PolicyArfReport.select(PolicyArfReport.arel_table[:arf_report_id])
15
+ .of_policy(Policy.find_by_name(cond).id).ast
16
+ ).to_sql
17
+ }
18
+ end
19
+
20
+ def search_by_comply_with(_key, _operator, policy_name)
21
+ search_by_policy_results policy_name, &:passed
22
+ end
23
+
24
+ def search_by_not_comply_with(_key, _operator, policy_name)
25
+ search_by_policy_results policy_name, &:failed
26
+ end
27
+
28
+ def search_by_inconclusive_with(_key, _operator, policy_name)
29
+ search_by_policy_results policy_name, &:othered
30
+ end
31
+
32
+ def search_by_policy_results(policy_name, &selection)
33
+ cond = sanitize_policy_name(policy_name)
34
+ { :conditions => ArfReport.arel_table[:id].in(
35
+ ArfReport.select(ArfReport.arel_table[:id])
36
+ .latest_of_policy(Policy.find_by_name cond).instance_eval(&selection).ast
37
+ ).to_sql
38
+ }
39
+ end
40
+
41
+ def search_by_last_for(key, operator, by)
42
+ by.gsub!(/[^[:alnum:]]/, '')
43
+ case by.downcase
44
+ when 'host'
45
+ { :conditions => 'reports.id IN (
46
+ SELECT MAX(id) FROM reports sub
47
+ WHERE sub.host_id = reports.host_id)' }
48
+ when 'policy'
49
+ { :conditions => 'reports.id IN (
50
+ SELECT latest.id
51
+ FROM foreman_openscap_policies
52
+ INNER JOIN (SELECT policy_id, MAX(reports.id) AS id
53
+ FROM reports INNER JOIN foreman_openscap_policy_arf_reports
54
+ ON reports.id = foreman_openscap_policy_arf_reports.arf_report_id
55
+ GROUP BY policy_id
56
+ ) latest
57
+ ON foreman_openscap_policies.id = latest.policy_id)' }
58
+ else
59
+ fail "Cannot search last by #{by}"
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def sanitize_policy_name(policy_name)
66
+ sanitize_sql_for_conditions('foreman_openscap_policies.name' => policy_name)
67
+ end
68
+ end
69
+
70
+ included do
71
+ scoped_search :in => :policy, :on => :name, :complete_value => true, :rename => :compliance_policy,
72
+ :ext_method => :search_by_policy_name
73
+
74
+ scoped_search :on => :id, :rename => :last_for, :complete_value => { :host => 0, :policy => 1 },
75
+ :only_explicit => true, :ext_method => :search_by_last_for
76
+
77
+ scoped_search :in => :policy, :on => :name, :complete_value => true, :rename => :comply_with,
78
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_comply_with
79
+
80
+ scoped_search :in => :policy, :on => :name, :complete_value => true, :rename => :not_comply_with,
81
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_not_comply_with
82
+
83
+ scoped_search :in => :policy, :on => :name, :complete_value => true, :rename => :inconclusive_with,
84
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_inconclusive_with
85
+
86
+ compliance_status_scoped_search 'passed', :on => :status, :rename => :compliance_passed
87
+ compliance_status_scoped_search 'failed', :on => :status, :rename => :compliance_failed
88
+ compliance_status_scoped_search 'othered', :on => :status, :rename => :compliance_othered
89
+ end
90
+ end
91
+ end
@@ -1,24 +1,53 @@
1
- require 'scaptimony/asset'
2
-
3
1
  module ForemanOpenscap
4
2
  module HostExtensions
5
3
  extend ActiveSupport::Concern
6
4
  ::Host::Managed::Jail.allow :policies_enc
7
5
 
8
6
  included do
9
- has_one :asset, :as => :assetable, :class_name => "::Scaptimony::Asset"
10
- has_many :asset_policies, :through => :asset, :class_name => "::Scaptimony::AssetPolicy"
11
- has_many :policies, :through => :asset_policies, :class_name => "::Scaptimony::Policy"
12
- has_many :arf_reports, :through => :asset, :class_name => '::Scaptimony::ArfReport'
7
+ has_one :asset, :as => :assetable, :class_name => "::ForemanOpenscap::Asset"
8
+ has_many :asset_policies, :through => :asset, :class_name => "::ForemanOpenscap::AssetPolicy"
9
+ has_many :policies, :through => :asset_policies, :class_name => "::ForemanOpenscap::Policy"
10
+ has_many :arf_reports, :class_name => '::ForemanOpenscap::ArfReport', :foreign_key => :host_id
11
+ has_one :compliance_status_object, :class_name => '::ForemanOpenscap::ComplianceStatus', :foreign_key => 'host_id'
13
12
 
14
13
  scoped_search :in => :policies, :on => :name, :complete_value => true, :rename => :'compliance_policy',
15
14
  :only_explicit => true, :operators => ['= ', '!= '], :ext_method => :search_by_policy_name
15
+
16
16
  scoped_search :in => :policies, :on => :name, :complete_value => true, :rename => :'compliance_report_missing_for',
17
17
  :only_explicit => true, :operators => ['= ', '!= '], :ext_method => :search_by_missing_arf
18
+
19
+ scoped_search :in => :compliance_status_object, :on => :status, :rename => :compliance_status,
20
+ :complete_value => {:compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT,
21
+ :incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT,
22
+ :inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE}
23
+
24
+ scope :comply_with, lambda { |policy|
25
+ joins(:arf_reports).merge(ArfReport.latest_of_policy policy).merge(ArfReport.passed)
26
+ }
27
+
28
+ scope :incomply_with, lambda { |policy|
29
+ joins(:arf_reports).merge(ArfReport.latest_of_policy policy).merge(ArfReport.failed)
30
+ }
31
+
32
+ scope :inconclusive_with, lambda { |policy|
33
+ joins(:arf_reports).merge(ArfReport.latest_of_policy policy).merge(ArfReport.othered)
34
+ }
35
+
36
+ scope :policy_reports_missing, lambda { |policy|
37
+ where("id NOT IN (SELECT host_id
38
+ FROM reports INNER JOIN foreman_openscap_policy_arf_reports
39
+ ON reports.id = foreman_openscap_policy_arf_reports.arf_report_id
40
+ WHERE policy_id = #{policy.id})
41
+ AND id IN (SELECT assetable_id
42
+ FROM foreman_openscap_asset_policies INNER JOIN foreman_openscap_assets
43
+ ON foreman_openscap_asset_policies.asset_id = foreman_openscap_assets.id
44
+ WHERE foreman_openscap_assets.assetable_type = 'Host::Base'
45
+ AND foreman_openscap_asset_policies.policy_id = '#{policy.id}')")
46
+ }
18
47
  end
19
48
 
20
49
  def get_asset
21
- Scaptimony::Asset.where(:assetable_type => 'Host::Base', :assetable_id => id).first_or_create!
50
+ ForemanOpenscap::Asset.where(:assetable_type => 'Host::Base', :assetable_id => id).first_or_create!
22
51
  end
23
52
 
24
53
  def policies_enc
@@ -30,30 +59,57 @@ module ForemanOpenscap
30
59
  combined.uniq
31
60
  end
32
61
 
62
+ def scap_status_changed?(policy)
63
+ last_reports = reports_for_policy(policy, 2)
64
+ return false if last_reports.length != 2
65
+ !last_reports.first.equal? last_reports.last
66
+ end
67
+
68
+ def last_report_for_policy(policy)
69
+ reports_for_policy(policy, 1)
70
+ end
71
+
72
+ def reports_for_policy(policy, limit = nil)
73
+ if limit
74
+ ForemanOpenscap::ArfReport.joins(:policy_arf_report)
75
+ .merge(ForemanOpenscap::PolicyArfReport.of_policy policy.id).where(:host_id => id).limit limit
76
+ else
77
+ ForemanOpenscap::ArfReport.joins(:policy_arf_report)
78
+ .merge(ForemanOpenscap::PolicyArfReport.of_policy policy.id).where(:host_id => id)
79
+ end
80
+ end
81
+
82
+ def compliance_status(options = {})
83
+ @compliance_status ||= get_status(ForemanOpenscap::ComplianceStatus).to_status(options)
84
+ end
85
+
86
+ def compliance_status_label(options = {})
87
+ @compliance_status_label ||= get_status(ForemanOpenscap::ComplianceStatus).to_label(options)
88
+ end
89
+
33
90
  module ClassMethods
34
91
  def search_by_policy_name(key, operator, policy_name)
35
- cond = sanitize_sql_for_conditions(["scaptimony_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
92
+ cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
36
93
  { :conditions => Host::Managed.arel_table[:id].in(
37
94
  Host::Managed.select(Host::Managed.arel_table[:id]).joins(:policies).where(cond).ast
38
95
  ).to_sql }
39
96
  end
40
97
 
41
98
  def search_by_missing_arf(key, operator, policy_name)
42
- cond = sanitize_sql_for_conditions(["scaptimony_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
99
+ cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
43
100
  { :conditions => Host::Managed.arel_table[:id].in(
44
101
  Host::Managed.select(Host::Managed.arel_table[:id])
45
102
  .joins(:policies)
46
103
  .where(cond)
47
- .where('scaptimony_assets.id not in (
48
- SELECT distinct scaptimony_arf_reports.asset_id
49
- FROM scaptimony_arf_reports
50
- WHERE scaptimony_arf_reports.asset_id = scaptimony_assets.id
51
- AND scaptimony_arf_reports.policy_id = scaptimony_policies.id)
52
- ')
53
- .ast
54
- ).to_sql
104
+ .where("foreman_openscap_assets.id NOT IN (
105
+ SELECT DISTINCT foreman_openscap_arf_reports.asset_id
106
+ FROM foreman_openscap_arf_reports
107
+ WHERE foreman_openscap_arf_reports.asset_id = foreman_openscap_assets.id
108
+ AND foreman_openscap_arf_reports.policy_id = foreman_openscap_policies.id)
109
+ ").ast).to_sql
55
110
  }
56
111
  end
112
+
57
113
  end
58
114
  end
59
115
  end