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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/foreman_openscap/load_report.js +1 -1
- data/app/assets/javascripts/foreman_openscap/policy_edit.js +0 -2
- data/app/controllers/api/v2/compliance/arf_reports_controller.rb +7 -22
- data/app/controllers/api/v2/compliance/policies_controller.rb +5 -5
- data/app/controllers/api/v2/compliance/scap_contents_controller.rb +3 -3
- data/app/controllers/arf_reports_controller.rb +62 -0
- data/app/controllers/{scaptimony_dashboard_controller.rb → compliance_dashboard_controller.rb} +1 -1
- data/app/controllers/compliance_hosts_controller.rb +5 -0
- data/app/controllers/{scaptimony_policies_controller.rb → policies_controller.rb} +13 -13
- data/app/controllers/{scaptimony_policy_dashboard_controller.rb → policy_dashboard_controller.rb} +3 -3
- data/app/controllers/{scaptimony_scap_contents_controller.rb → scap_contents_controller.rb} +11 -11
- data/app/helpers/{scaptimony_report_dashboard_helper.rb → arf_report_dashboard_helper.rb} +3 -5
- data/app/helpers/arf_reports_helper.rb +21 -0
- data/app/helpers/compliance_hosts_helper.rb +25 -0
- data/app/helpers/concerns/foreman_openscap/hosts_helper_extensions.rb +2 -32
- data/app/helpers/{scaptimony_policies_helper.rb → policies_helper.rb} +6 -2
- data/app/helpers/{scaptimony_policy_dashboard_helper.rb → policy_dashboard_helper.rb} +8 -8
- data/app/lib/proxy_api/available_proxy.rb +26 -0
- data/app/lib/proxy_api/openscap.rb +40 -0
- data/app/mailers/foreman_openscap/policy_mailer.rb +42 -0
- data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +91 -0
- data/app/models/concerns/foreman_openscap/host_extensions.rb +73 -17
- data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +3 -5
- data/app/models/foreman_openscap/arf_report.rb +165 -0
- data/app/models/foreman_openscap/asset.rb +27 -0
- data/app/models/foreman_openscap/asset_policy.rb +6 -0
- data/app/models/foreman_openscap/compliance_status.rb +50 -0
- data/app/models/{concerns/foreman_openscap/policy_extensions.rb → foreman_openscap/policy.rb} +72 -45
- data/app/models/foreman_openscap/policy_arf_report.rb +8 -0
- data/app/models/foreman_openscap/policy_revision.rb +6 -0
- data/app/models/foreman_openscap/scap_content.rb +112 -0
- data/app/models/foreman_openscap/scap_content_profile.rb +6 -0
- data/app/overrides/hosts/overview/host_compliance_status.rb +4 -4
- data/app/services/foreman_openscap/arf_report_status_calculator.rb +45 -0
- data/app/services/{scaptimony → foreman_openscap}/host_report_dashboard/data.rb +12 -6
- data/app/services/{scaptimony → foreman_openscap}/policy_dashboard/data.rb +5 -5
- data/app/services/{scaptimony → foreman_openscap}/report_dashboard/data.rb +4 -4
- data/app/views/api/v2/compliance/policies/create.json.rabl +3 -0
- data/app/views/{scaptimony_arf_reports → arf_reports}/_list.html.erb +4 -4
- data/app/views/arf_reports/_metrics.html.erb +37 -0
- data/app/views/arf_reports/_output.html.erb +23 -0
- data/app/views/{scaptimony_arf_reports → arf_reports}/index.html.erb +0 -0
- data/app/views/arf_reports/show.html.erb +14 -0
- data/app/views/{scaptimony_arf_reports/show.html.erb → arf_reports/show_html.html.erb} +2 -3
- data/app/views/compliance_hosts/_compliance_status.erb +6 -0
- data/app/views/{scaptimony_hosts → compliance_hosts}/show.html.erb +9 -2
- data/app/views/dashboard/{_foreman_openscap_host_reports_widget.html.erb → _compliance_host_reports_widget.html.erb} +3 -3
- data/app/views/dashboard/{_foreman_openscap_reports_breakdown_widget.html.erb → _compliance_reports_breakdown_widget.html.erb} +1 -1
- data/app/views/foreman_openscap/policy_mailer/_dashboard.erb +21 -0
- data/app/views/foreman_openscap/policy_mailer/_hosts.erb +44 -0
- data/app/views/foreman_openscap/policy_mailer/_list.erb +10 -0
- data/app/views/foreman_openscap/policy_mailer/_policy.erb +7 -0
- data/app/views/foreman_openscap/policy_mailer/policy_summary.erb +19 -0
- data/app/views/{scaptimony_policies → policies}/_form.html.erb +2 -8
- data/app/views/{scaptimony_policies → policies}/_list.html.erb +5 -5
- data/app/views/policies/_scap_content_results.html.erb +3 -0
- data/app/views/policies/create.html.erb +2 -0
- data/app/views/{scaptimony_policies → policies}/disassociate_multiple_hosts.html.erb +2 -2
- data/app/views/{scaptimony_policies → policies}/edit.html.erb +0 -0
- data/app/views/{scaptimony_policies → policies}/index.html.erb +1 -1
- data/app/views/policies/new.html.erb +2 -0
- data/app/views/{scaptimony_policies → policies}/select_multiple_hosts.html.erb +2 -2
- data/app/views/{scaptimony_policies → policies}/show.html.erb +1 -1
- data/app/views/{scaptimony_policies → policies}/steps/_create_policy_form.html.erb +0 -0
- data/app/views/{scaptimony_policies → policies}/steps/_hostgroups_form.html.erb +0 -0
- data/app/views/{scaptimony_policies → policies}/steps/_locations_form.html.erb +0 -0
- data/app/views/{scaptimony_policies → policies}/steps/_organizations_form.html.erb +0 -0
- data/app/views/policies/steps/_scap_content_form.html.erb +9 -0
- data/app/views/{scaptimony_policies → policies}/steps/_schedule_form.html.erb +1 -1
- data/app/views/{scaptimony_policies → policies}/steps/_step_form.html.erb +3 -3
- data/app/views/{scaptimony_policies → policies}/welcome.html.erb +2 -2
- data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/_policy_chart_widget.html.erb +0 -0
- data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/_policy_reports.html.erb +2 -2
- data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/_policy_status_widget.html.erb +3 -3
- data/app/views/{scaptimony_policy_dashboard → policy_dashboard}/index.html.erb +0 -0
- data/app/views/{scaptimony_scap_contents → scap_contents}/_form.html.erb +5 -6
- data/app/views/{scaptimony_scap_contents → scap_contents}/_list.html.erb +3 -3
- data/app/views/{scaptimony_scap_contents → scap_contents}/edit.html.erb +0 -0
- data/app/views/{scaptimony_scap_contents → scap_contents}/index.html.erb +1 -1
- data/app/views/{scaptimony_scap_contents → scap_contents}/new.html.erb +0 -0
- data/app/views/{scaptimony_scap_contents → scap_contents}/welcome.html.erb +2 -2
- data/config/routes.rb +15 -11
- data/db/migrate/20141013172051_create_scaptimony_policies.rb +9 -0
- data/db/migrate/20141014105333_create_scaptimony_assets.rb +10 -0
- data/db/migrate/20141015092642_create_scaptimony_arf_reports.rb +13 -0
- data/db/migrate/20141015115511_add_arf_report_unique_constraint.rb +6 -0
- data/db/migrate/20141104164201_create_scaptimony_scap_contents.rb +7 -0
- data/db/migrate/20141104171545_create_scaptimony_policy_revisions.rb +14 -0
- data/db/migrate/20141105174625_add_description_to_scaptimony_policy_revisions.rb +5 -0
- data/db/migrate/20141105174834_add_columns_to_scaptimony_policies.rb +12 -0
- data/db/migrate/20141107091756_add_columns_to_scaptimony_scap_contents.rb +8 -0
- data/db/migrate/20141111104519_add_constraint_to_scaptimony_scap_contents.rb +5 -0
- data/db/migrate/20141113221054_create_scaptimony_scap_content_profiles.rb +12 -0
- data/db/migrate/20141116170632_remove_xccdf_profile_from_scaptimony_policies.rb +5 -0
- data/db/migrate/20141116171305_add_profile_to_scaptimony_policies.rb +6 -0
- data/db/migrate/20141118142954_add_constraint_to_scaptimony_policies.rb +5 -0
- data/db/migrate/20141119164918_create_scaptimony_xccdf_results.rb +8 -0
- data/db/migrate/20141119175434_create_scaptimony_xccdf_rules.rb +8 -0
- data/db/migrate/20141119182606_create_scaptimony_xccdf_rule_results.rb +9 -0
- data/db/migrate/20141121120326_create_scaptimony_arf_report_breakdowns.rb +24 -0
- data/db/migrate/20141121164042_replace_arf_report_breakdown_view.rb +25 -0
- data/db/migrate/20141206211151_create_scaptimony_assets_policies.rb +9 -0
- data/db/migrate/20141214112917_add_scap_file_to_scap_content.rb +5 -0
- data/db/migrate/20141216154502_rename_scaptimony_asset_policies.rb +5 -0
- data/db/migrate/20150111085317_polymorph_asset.rb +8 -0
- data/db/migrate/20150112152944_create_scaptimony_arf_report_raws.rb +10 -0
- data/db/migrate/20150114210634_rename_scaptimony_arf_report_raw_raw.rb +5 -0
- data/db/migrate/20150115155947_add_scaptimony_scap_content_digest.rb +21 -0
- data/db/migrate/20150116083129_add_day_of_month_and_cron_line_to_scaptimony_policy.rb +6 -0
- data/db/migrate/20150821100137_migrate_from_scaptimony.rb +59 -0
- data/db/migrate/20150827123826_remove_scaptimony_permissions.rb +21 -0
- data/db/migrate/20150925124959_create_policy_arf_reports.rb +13 -0
- data/db/migrate/20150929124853_add_result_to_logs.rb +9 -0
- data/db/migrate/20150929152345_move_arf_reports_to_reports_table.rb +179 -0
- data/db/migrate/20151023131950_link_arf_report_directly_to_host.rb +17 -0
- data/db/seeds.d/openscap_policy_notification.rb +9 -0
- data/lib/foreman_openscap/bulk_upload.rb +3 -1
- data/lib/foreman_openscap/engine.rb +53 -42
- data/lib/foreman_openscap/helper.rb +8 -0
- data/lib/foreman_openscap/version.rb +1 -1
- data/lib/tasks/foreman_openscap_tasks.rake +14 -0
- data/test/factories/arf_report_factory.rb +9 -6
- data/test/factories/asset_factory.rb +1 -1
- data/test/factories/compliance_host_factory.rb +9 -0
- data/test/factories/compliance_log_factory.rb +11 -0
- data/test/factories/policy_arf_report_factory.rb +6 -0
- data/test/factories/policy_factory.rb +3 -2
- data/test/factories/scap_content_related.rb +2 -2
- data/test/functional/api/v2/compliance/arf_reports_controller_test.rb +4 -3
- data/test/functional/api/v2/compliance/policies_controller_test.rb +2 -2
- data/test/functional/api/v2/compliance/scap_contents_controller_test.rb +3 -1
- data/test/lib/foreman_openscap/bulk_upload_test.rb +1 -1
- data/test/test_plugin_helper.rb +30 -0
- data/test/unit/arf_report_status_calculator_test.rb +11 -0
- data/test/unit/arf_report_test.rb +148 -0
- data/test/unit/compliance_status_test.rb +71 -0
- data/test/unit/openscap_host_test.rb +38 -7
- data/test/unit/policy_mailer_test.rb +38 -0
- data/test/unit/scap_content_test.rb +32 -0
- metadata +130 -74
- data/app/controllers/scaptimony_arf_reports_controller.rb +0 -34
- data/app/controllers/scaptimony_hosts_controller.rb +0 -5
- data/app/models/concerns/foreman_openscap/arf_report_extensions.rb +0 -50
- data/app/models/concerns/foreman_openscap/asset_extensions.rb +0 -34
- data/app/models/concerns/foreman_openscap/scap_content_extensions.rb +0 -40
- data/app/overrides/hosts/index/host_arf_report.rb +0 -5
- data/app/views/scaptimony_arf_reports/_host_report.html.erb +0 -8
- data/app/views/scaptimony_hosts/_host_status.html.erb +0 -17
- data/app/views/scaptimony_policies/_scap_content_results.html.erb +0 -7
- data/app/views/scaptimony_policies/create.html.erb +0 -2
- data/app/views/scaptimony_policies/new.html.erb +0 -2
- 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'),
|
|
18
|
-
[_('Unassign Compliance Policy'),
|
|
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
|
|
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 =
|
|
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
|
|
12
|
-
|
|
13
|
-
:compliant_hosts =>
|
|
14
|
-
:incompliant_hosts =>
|
|
15
|
-
:inconclusive_hosts =>
|
|
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
|
-
|
|
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 =>
|
|
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(' '), :class=>'label', :style => 'background-color:' +
|
|
37
|
+
content_tag(:i, raw(' '), :class=>'label', :style => 'background-color:' + COLORS[label]) +
|
|
38
38
|
raw(' ') +
|
|
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 => "::
|
|
10
|
-
has_many :asset_policies, :through => :asset, :class_name => "::
|
|
11
|
-
has_many :policies, :through => :asset_policies, :class_name => "::
|
|
12
|
-
has_many :arf_reports, :
|
|
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
|
-
|
|
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(["
|
|
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(["
|
|
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(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|