foreman_openscap 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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