foreman_openscap 0.10.4 → 0.11.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/compliance/scap_contents_controller.rb +2 -1
  3. data/app/controllers/api/v2/compliance/tailoring_files_controller.rb +2 -1
  4. data/app/controllers/concerns/foreman_openscap/body_log_extensions.rb +18 -0
  5. data/app/controllers/concerns/foreman_openscap/hosts_controller_extensions.rb +1 -1
  6. data/app/controllers/openscap_proxies_controller.rb +2 -11
  7. data/app/controllers/policies_controller.rb +2 -2
  8. data/app/helpers/arf_reports_helper.rb +6 -0
  9. data/app/lib/proxy_api/openscap.rb +8 -0
  10. data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +72 -11
  11. data/app/models/concerns/foreman_openscap/host_extensions.rb +48 -2
  12. data/app/models/concerns/foreman_openscap/log_extensions.rb +4 -0
  13. data/app/models/concerns/foreman_openscap/openscap_proxy_core_extensions.rb +1 -1
  14. data/app/models/foreman_openscap/arf_report.rb +2 -0
  15. data/app/services/proxy_status/openscap_spool.rb +13 -0
  16. data/app/validators/concerns/foreman_openscap/bookmark_controller_validator_extensions.rb +19 -0
  17. data/app/views/arf_reports/_output.html.erb +5 -3
  18. data/app/views/compliance_hosts/show.html.erb +9 -7
  19. data/app/views/smart_proxies/_openscap_spool.html.erb +4 -4
  20. data/app/views/smart_proxies/plugins/_openscap.html.erb +1 -1
  21. data/lib/foreman_openscap/engine.rb +11 -2
  22. data/lib/foreman_openscap/version.rb +1 -1
  23. data/locale/action_names.rb +69 -0
  24. data/locale/de/LC_MESSAGES/foreman_openscap.mo +0 -0
  25. data/locale/de/foreman_openscap.edit.po +1419 -0
  26. data/locale/de/foreman_openscap.po +263 -17
  27. data/locale/de/foreman_openscap.po.time_stamp +0 -0
  28. data/locale/en_GB/LC_MESSAGES/foreman_openscap.mo +0 -0
  29. data/locale/en_GB/foreman_openscap.edit.po +1419 -0
  30. data/locale/en_GB/foreman_openscap.po +263 -17
  31. data/locale/en_GB/foreman_openscap.po.time_stamp +0 -0
  32. data/locale/es/LC_MESSAGES/foreman_openscap.mo +0 -0
  33. data/locale/es/foreman_openscap.edit.po +1419 -0
  34. data/locale/es/foreman_openscap.po +263 -17
  35. data/locale/es/foreman_openscap.po.time_stamp +0 -0
  36. data/locale/foreman_openscap.pot +438 -97
  37. data/locale/fr/LC_MESSAGES/foreman_openscap.mo +0 -0
  38. data/locale/fr/foreman_openscap.edit.po +1419 -0
  39. data/locale/fr/foreman_openscap.po +263 -17
  40. data/locale/fr/foreman_openscap.po.time_stamp +0 -0
  41. data/locale/gl/LC_MESSAGES/foreman_openscap.mo +0 -0
  42. data/locale/gl/foreman_openscap.edit.po +1419 -0
  43. data/locale/gl/foreman_openscap.po +263 -17
  44. data/locale/gl/foreman_openscap.po.time_stamp +0 -0
  45. data/locale/it/LC_MESSAGES/foreman_openscap.mo +0 -0
  46. data/locale/it/foreman_openscap.edit.po +1419 -0
  47. data/locale/it/foreman_openscap.po +263 -17
  48. data/locale/it/foreman_openscap.po.time_stamp +0 -0
  49. data/locale/ja/LC_MESSAGES/foreman_openscap.mo +0 -0
  50. data/locale/ja/foreman_openscap.edit.po +1419 -0
  51. data/locale/ja/foreman_openscap.po +263 -17
  52. data/locale/ja/foreman_openscap.po.time_stamp +0 -0
  53. data/locale/ko/LC_MESSAGES/foreman_openscap.mo +0 -0
  54. data/locale/ko/foreman_openscap.edit.po +1419 -0
  55. data/locale/ko/foreman_openscap.po +263 -17
  56. data/locale/ko/foreman_openscap.po.time_stamp +0 -0
  57. data/locale/pt_BR/LC_MESSAGES/foreman_openscap.mo +0 -0
  58. data/locale/pt_BR/foreman_openscap.edit.po +1419 -0
  59. data/locale/pt_BR/foreman_openscap.po +263 -17
  60. data/locale/pt_BR/foreman_openscap.po.time_stamp +0 -0
  61. data/locale/ru/LC_MESSAGES/foreman_openscap.mo +0 -0
  62. data/locale/ru/foreman_openscap.edit.po +1420 -0
  63. data/locale/ru/foreman_openscap.po +263 -17
  64. data/locale/ru/foreman_openscap.po.time_stamp +0 -0
  65. data/locale/sv_SE/LC_MESSAGES/foreman_openscap.mo +0 -0
  66. data/locale/sv_SE/foreman_openscap.edit.po +1419 -0
  67. data/locale/sv_SE/foreman_openscap.po +263 -17
  68. data/locale/sv_SE/foreman_openscap.po.time_stamp +0 -0
  69. data/locale/zh_CN/LC_MESSAGES/foreman_openscap.mo +0 -0
  70. data/locale/zh_CN/foreman_openscap.edit.po +1419 -0
  71. data/locale/zh_CN/foreman_openscap.po +263 -17
  72. data/locale/zh_CN/foreman_openscap.po.time_stamp +0 -0
  73. data/locale/zh_TW/LC_MESSAGES/foreman_openscap.mo +0 -0
  74. data/locale/zh_TW/foreman_openscap.edit.po +1419 -0
  75. data/locale/zh_TW/foreman_openscap.po +263 -17
  76. data/locale/zh_TW/foreman_openscap.po.time_stamp +0 -0
  77. data/test/factories/compliance_log_factory.rb +7 -0
  78. data/test/functional/api/v2/compliance/arf_reports_controller_test.rb +91 -0
  79. data/test/functional/openscap_proxies_controller_test.rb +3 -3
  80. data/test/test_plugin_helper.rb +16 -0
  81. data/test/unit/arf_report_test.rb +13 -0
  82. data/test/unit/concerns/host_extensions_test.rb +52 -0
  83. metadata +32 -4
  84. data/app/assets/javascripts/foreman_openscap/openscap_proxy.js +0 -7
  85. data/app/helpers/concerns/foreman_openscap/lookup_keys_helper_extensions.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b441309459cd62b0c525d1b51dd856b28bf3b2e
4
- data.tar.gz: 2b98addfa0d16368c3f9d9be4af017047ba56036
3
+ metadata.gz: ae4c20b57b85e1366a7e2b07e46bffbbdc4cab02
4
+ data.tar.gz: c9afcc7dd78320e4479487c23dc232f27a04a3b4
5
5
  SHA512:
6
- metadata.gz: ddae8417386fa6877ce9b2873b94f1750dde15217cf29cc2fbb3d2e5e2ae7f07ee4905da0702a45c00d26b6ad8c20c5b0aa43d89b11becf04344feabba1d7af5
7
- data.tar.gz: 6b843df78415ac1c53ee199e06abba468f0d3e0c121c890b0565aec35c38a788d9fde4092fcdd59a4410b97eb6f8c3039b2cc8228787e34866f7d5829e95b630
6
+ metadata.gz: 2c712c0f895f97a2a4154a23940da478ab7b1dc63fec766de9b667cac17c1e81998bcaaba4da69a105c2d93ce61f47d7709c08fd589661fdee91c9b51cd34745
7
+ data.tar.gz: 3dd60521f98b6fc961bb55f68e381442a1f8b8fe8f2a5403e8b3ccbca31d2cf8b6af2b8b2e3498605647e8ef1d5422efc3a823590b4d82a05b904f811c1c5ce4
@@ -2,6 +2,7 @@ module Api::V2
2
2
  module Compliance
3
3
  class ScapContentsController < ::Api::V2::BaseController
4
4
  include Foreman::Controller::Parameters::ScapContent
5
+ include ForemanOpenscap::BodyLogExtensions
5
6
  before_action :find_resource, :except => %w[index create]
6
7
 
7
8
  def resource_name(resource = '::ForemanOpenscap::ScapContent')
@@ -19,7 +20,7 @@ module Api::V2
19
20
  @scap_contents = resource_scope_for_index(:permission => :view_scap_contents)
20
21
  end
21
22
 
22
- api :GET, '/compliance/scap_contents/:id/xml', N_('Show an SCAP content as XML')
23
+ api :GET, '/compliance/scap_contents/:id/xml', N_('Download an SCAP content as XML')
23
24
  param :id, :identifier, :required => true
24
25
 
25
26
  def xml
@@ -2,6 +2,7 @@ module Api::V2
2
2
  module Compliance
3
3
  class TailoringFilesController < ::Api::V2::BaseController
4
4
  include Foreman::Controller::Parameters::TailoringFile
5
+ include ForemanOpenscap::BodyLogExtensions
5
6
  before_action :find_resource, :except => %w[index create]
6
7
  before_action :openscap_proxy_check, :only => %w[create]
7
8
 
@@ -20,7 +21,7 @@ module Api::V2
20
21
  @tailoring_files = resource_scope_for_index(:permission => :view_tailoring_files)
21
22
  end
22
23
 
23
- api :GET, '/compliance/tailoring_files/:id/xml', N_('Show a Tailoring file as XML')
24
+ api :GET, '/compliance/tailoring_files/:id/xml', N_('Download a Tailoring file as XML')
24
25
  param :id, :identifier, :required => true
25
26
 
26
27
  def xml
@@ -0,0 +1,18 @@
1
+ module ForemanOpenscap
2
+ module BodyLogExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ def log_response_body
6
+ return super unless skip_body_log.include?(action_name)
7
+ logger.debug { logger_msg }
8
+ end
9
+
10
+ def skip_body_log
11
+ ['xml']
12
+ end
13
+
14
+ def logger_msg
15
+ "Logging response body of #{response.body.length} characters skipped when downloading DS files"
16
+ end
17
+ end
18
+ end
@@ -23,7 +23,7 @@ module ForemanOpenscap
23
23
  host.openscap_proxy = smart_proxy
24
24
  host.save!
25
25
  end
26
- notice _("Updated hosts: Assigned with OpenSCAP Proxy: %s") % smart_proxy.name
26
+ success _("Updated hosts: Assigned with OpenSCAP Proxy: %s") % smart_proxy.name
27
27
  redirect_to hosts_path
28
28
  else
29
29
  error _('No OpenSCAP Proxy selected.')
@@ -2,8 +2,8 @@ class OpenscapProxiesController < ApplicationController
2
2
  before_action :find_proxy, :only => [:openscap_spool]
3
3
 
4
4
  def openscap_spool
5
- last_error = @smart_proxy ? find_spool_error : nil
6
- render :partial => 'smart_proxies/openscap_spool', :locals => { :last_error => last_error }
5
+ spool_errors = @smart_proxy ? @smart_proxy.statuses[:openscap].spool_status : nil
6
+ render :partial => 'smart_proxies/openscap_spool', :locals => { :spool_errors => spool_errors }
7
7
  end
8
8
 
9
9
  private
@@ -20,13 +20,4 @@ class OpenscapProxiesController < ApplicationController
20
20
  def find_proxy
21
21
  @smart_proxy = SmartProxy.find params[:id]
22
22
  end
23
-
24
- def find_spool_error
25
- log_status = @smart_proxy.statuses[:logs]
26
- return {} unless log_status
27
- log_status.logs
28
- .log_entries
29
- .reverse
30
- .find { |entry| entry["level"] == "ERROR" && entry["message"].start_with?("Failed to parse Arf Report") }
31
- end
32
23
  end
@@ -80,7 +80,7 @@ class PoliciesController < ApplicationController
80
80
  if (id = params['policy']['id'])
81
81
  policy = ::ForemanOpenscap::Policy.find(id)
82
82
  policy.assign_hosts(@hosts)
83
- notice _("Updated hosts: Assigned with compliance policy: %s") % policy.name
83
+ success _("Updated hosts: Assigned with compliance policy: %s") % policy.name
84
84
  # We prefer to go back as this does not lose the current search
85
85
  redirect_to hosts_path
86
86
  else
@@ -96,7 +96,7 @@ class PoliciesController < ApplicationController
96
96
  if (id = params.fetch(:policy, {})[:id])
97
97
  policy = ::ForemanOpenscap::Policy.find(id)
98
98
  policy.unassign_hosts(@hosts)
99
- notice _("Updated hosts: Unassigned from compliance policy '%s'") % policy.name
99
+ success _("Updated hosts: Unassigned from compliance policy '%s'") % policy.name
100
100
  else
101
101
  error _('No valid policy ID provided')
102
102
  end
@@ -78,4 +78,10 @@ module ArfReportsHelper
78
78
  msg += _(" through %s") % openscap_proxy_link(arf_report)
79
79
  msg.html_safe
80
80
  end
81
+
82
+ def host_search_by_rule_result_buttons(source)
83
+ action_buttons(display_link_if_authorized(_('Hosts failing this rule'), hash_for_hosts_path(:search => "fails_xccdf_rule = #{source}")),
84
+ display_link_if_authorized(_('Hosts passing this rule'), hash_for_hosts_path(:search => "passes_xccdf_rule = #{source}")),
85
+ display_link_if_authorized(_('Hosts othering this rule'), hash_for_hosts_path(:search => "others_xccdf_rule = #{source}")))
86
+ end
81
87
  end
@@ -61,6 +61,14 @@ module ::ProxyAPI
61
61
  end
62
62
  end
63
63
 
64
+ def spool_status
65
+ parse(get('spool_errors'))
66
+ rescue => e
67
+ msg = "Failed to get spool status from proxy, cause: #{e.message}"
68
+ logger.error msg
69
+ {}
70
+ end
71
+
64
72
  private
65
73
 
66
74
  def timeout
@@ -9,9 +9,9 @@ module ForemanOpenscap
9
9
  end
10
10
 
11
11
  def search_by_policy_name(_key, _operator, policy_name)
12
- query = PolicyArfReport.of_policy(Policy.find_by(:name => policy_name))
12
+ scope = PolicyArfReport.of_policy(Policy.find_by(:name => policy_name))
13
13
  .select(PolicyArfReport.arel_table[:arf_report_id]).to_sql
14
- query_conditions query
14
+ query_conditions scope
15
15
  end
16
16
 
17
17
  def search_by_comply_with(_key, _operator, policy_name)
@@ -27,9 +27,21 @@ module ForemanOpenscap
27
27
  end
28
28
 
29
29
  def search_by_policy_results(policy_name, &selection)
30
- query = ArfReport.of_policy(Policy.find_by(:name => policy_name).id)
31
- .instance_eval(&selection).select(ArfReport.arel_table[:id]).to_sql
32
- query_conditions query
30
+ scope = ArfReport.of_policy(Policy.find_by(:name => policy_name).id)
31
+ .instance_eval(&selection)
32
+ query_conditions_from_scope scope
33
+ end
34
+
35
+ def search_by_rule_failed(key, operator, rule_name)
36
+ search_by_rule rule_name, "fail"
37
+ end
38
+
39
+ def search_by_rule_passed(key, operator, rule_name)
40
+ search_by_rule rule_name, "pass"
41
+ end
42
+
43
+ def search_by_rule_othered(key, operator, rule_name)
44
+ search_by_rule rule_name, LogExtensions.othered_result_constants
33
45
  end
34
46
 
35
47
  def search_by_last_for(key, operator, by)
@@ -64,17 +76,54 @@ module ForemanOpenscap
64
76
  when 'inconclusive'
65
77
  ArfReport.othered
66
78
  end
67
- query_conditions scope.select(ArfReport.arel_table[:id]).to_sql
79
+ query_conditions_from_scope scope
80
+ end
81
+
82
+ def search_by_host_collection_name(key, operator, value)
83
+ scope = apply_condition(Host.joins(:host_collections),
84
+ operator == '!= ',
85
+ :katello_host_collections => { :name => value })
86
+ query_conditions_from_scope ForemanOpenscap::ArfReport.where(:host_id => scope)
68
87
  end
69
88
 
70
89
  private
71
90
 
91
+ def query_conditions_from_scope(scope)
92
+ query = scope.select(ArfReport.arel_table[:id]).to_sql
93
+ query_conditions query
94
+ end
95
+
72
96
  def query_conditions(query)
73
97
  { :conditions => "reports.id IN (#{query})" }
74
98
  end
99
+
100
+ def search_by_rule(rule_name, rule_result)
101
+ query = ArfReport.by_rule_result(rule_name, rule_result)
102
+ .select(ArfReport.arel_table[:id]).to_sql
103
+
104
+ query_conditions query
105
+ end
106
+
107
+ def apply_condition(scope, negate, conditions)
108
+ if negate
109
+ scope.where.not(conditions)
110
+ else
111
+ scope.where(conditions)
112
+ end
113
+ end
75
114
  end
76
115
 
77
116
  included do
117
+ if ForemanOpenscap.with_katello?
118
+ has_one :lifecycle_environment, :through => :host
119
+
120
+ has_many :host_collections, :through => :host
121
+
122
+ scoped_search :relation => :lifecycle_environment, :on => :name, :complete_value => true, :rename => :lifecycle_environment
123
+ scoped_search :relation => :host_collections, :on => :name, :complete_value => true, :rename => :host_collection,
124
+ :operators => ['= ', '!= '], :ext_method => :search_by_host_collection_name
125
+ end
126
+
78
127
  policy_search :compliance_policy
79
128
 
80
129
  policy_search :policy
@@ -93,12 +142,24 @@ module ForemanOpenscap
93
142
 
94
143
  scoped_search :relation => :openscap_proxy, :on => :name, :complete_value => true, :only_explicit => true, :rename => :openscap_proxy
95
144
 
145
+ scoped_search :relation => :sources, :on => :value, :complete_value => true, :rename => :xccdf_rule_name,
146
+ :only_explicit => true, :operators => ['= ']
147
+
148
+ scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_failed,
149
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_failed
150
+
151
+ scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_passed,
152
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_passed
153
+
154
+ scoped_search :relation => :sources, :on => :value, :rename => :xccdf_rule_othered,
155
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_othered
156
+
96
157
  scoped_search :on => :status, :rename => :compliance_status, :operators => ['= '],
97
- :ext_method => :search_by_compliance_status,
98
- :complete_value => { :compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT,
99
- :incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT,
100
- :inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE },
101
- :validator => ->(value) { ['compliant', 'incompliant', 'inconclusive'].reduce(false) { |memo, item| memo || (item == value) } }
158
+ :ext_method => :search_by_compliance_status,
159
+ :complete_value => { :compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT,
160
+ :incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT,
161
+ :inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE },
162
+ :validator => ->(value) { ['compliant', 'incompliant', 'inconclusive'].reduce(false) { |memo, item| memo || (item == value) } }
102
163
  end
103
164
  end
104
165
  end
@@ -22,6 +22,20 @@ module ForemanOpenscap
22
22
  :complete_value => { :compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT,
23
23
  :incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT,
24
24
  :inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE }
25
+
26
+ base.scoped_search :relation => :policies, :on => :name, :complete_value => { :true => true, :false => false },
27
+ :only_explicit => true, :rename => :is_compliance_host, :operators => ['= '], :ext_method => :search_for_any_with_policy,
28
+ :validator => ->(value) { ['true', 'false'].include? value }
29
+
30
+ base.scoped_search :on => :id, :rename => :passes_xccdf_rule,
31
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_passed
32
+
33
+ base.scoped_search :on => :id, :rename => :fails_xccdf_rule,
34
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_failed
35
+
36
+ base.scoped_search :on => :id, :rename => :others_xccdf_rule,
37
+ :only_explicit => true, :operators => ['= '], :ext_method => :search_by_rule_othered
38
+
25
39
  base.after_update :puppetrun!, :if => ->(host) { Setting[:puppetrun] && host.changed.include?('openscap_proxy_id') }
26
40
 
27
41
  base.scope :comply_with, lambda { |policy|
@@ -100,6 +114,33 @@ module ForemanOpenscap
100
114
  end
101
115
 
102
116
  module ClassMethods
117
+ def search_by_rule_passed(key, operator, rule_name)
118
+ search_by_rule rule_name, 'pass'
119
+ end
120
+
121
+ def search_by_rule_failed(key, operator, rule_name)
122
+ search_by_rule rule_name, 'fail'
123
+ end
124
+
125
+ def search_by_rule_othered(key, operator, rule_name)
126
+ search_by_rule rule_name, LogExtensions.othered_result_constants
127
+ end
128
+
129
+ def search_by_rule(rule_name, rule_result)
130
+ query = Host.joins(:arf_reports)
131
+ .merge(ArfReport.latest
132
+ .by_rule_result(rule_name, rule_result)
133
+ .unscope(:order))
134
+ .distinct
135
+ .select(Host.arel_table[:id]).to_sql
136
+
137
+ query_conditions query
138
+ end
139
+
140
+ def query_conditions(query)
141
+ { :conditions => "hosts.id IN (#{query})" }
142
+ end
143
+
103
144
  def search_by_policy_name(key, operator, policy_name)
104
145
  cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
105
146
 
@@ -125,11 +166,16 @@ module ForemanOpenscap
125
166
  search_assigned_all cond, host_ids_from_arf_of_policy
126
167
  end
127
168
 
128
- def search_assigned_all(condition, not_in_host_ids)
169
+ def search_for_any_with_policy(key, operator, value)
170
+ search_assigned_all nil, [], (value == "false")
171
+ end
172
+
173
+ def search_assigned_all(condition, not_in_host_ids, negate = false)
174
+ sql_not = negate ? "NOT" : ""
129
175
  direct_result = policy_assigned_directly_host_ids condition, not_in_host_ids
130
176
  hg_result = policy_assigned_using_hostgroup_host_ids condition, not_in_host_ids
131
177
  result = (direct_result + hg_result).uniq
132
- { :conditions => "hosts.id IN (#{result.empty? ? 'NULL' : result.join(',')})" }
178
+ { :conditions => "hosts.id #{sql_not} IN (#{result.empty? ? 'NULL' : result.join(',')})" }
133
179
  end
134
180
 
135
181
  def policy_assigned_directly_host_ids(condition, host_ids_from_arf)
@@ -6,6 +6,10 @@ module ForemanOpenscap
6
6
  validate :scap_result
7
7
  end
8
8
 
9
+ def self.othered_result_constants
10
+ SCAP_RESULT.reject { |item| item == "pass" || item == "fail" }
11
+ end
12
+
9
13
  private
10
14
 
11
15
  def scap_result
@@ -40,7 +40,7 @@ module ForemanOpenscap
40
40
  end
41
41
 
42
42
  def destroy_scap_client_lookup_values(pairs)
43
- pairs.values.map(&:destroy)
43
+ pairs.values.compact.map(&:destroy)
44
44
  end
45
45
 
46
46
  def update_scap_client_lookup_values(pairs, model_match, mapping)
@@ -59,6 +59,8 @@ module ForemanOpenscap
59
59
 
60
60
  scope :passed, lambda { where("(#{report_status_column} >> #{bit_mask 'passed'}) > 0").merge(not_failed).merge(not_othered) }
61
61
 
62
+ scope :by_rule_result, lambda { |rule_name, rule_result| joins(:sources).where(:sources => { :value => rule_name }, :logs => { :result => rule_result }) }
63
+
62
64
  def self.bit_mask(status)
63
65
  ComplianceStatus.bit_mask(status)
64
66
  end
@@ -0,0 +1,13 @@
1
+ module ProxyStatus
2
+ class OpenscapSpool < Base
3
+ def spool_status
4
+ fetch_proxy_data do
5
+ api.spool_status
6
+ end
7
+ end
8
+
9
+ def self.humanized_name
10
+ 'Openscap'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module ForemanOpenscap
2
+ module BookmarkControllerValidatorExtensions
3
+ module ClassMethods
4
+ def valid_controllers_list
5
+ super + ActiveRecord::Base.connection
6
+ .tables
7
+ .map(&:to_s)
8
+ .select { |table| table.start_with? 'foreman_openscap_' }
9
+ .map { |table| table.sub('foreman_openscap_', '') }
10
+ end
11
+ end
12
+
13
+ def self.prepended(base)
14
+ class << base
15
+ prepend ClassMethods
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,8 +3,9 @@
3
3
  <tr>
4
4
  <th><%= _("Severity") %></th>
5
5
  <th><%= _("Message") %></th>
6
- <th><%= _("Resource") %></th>
7
- <th><%= _("Result") %></th>
6
+ <th class="col-md-4"><%= _("Resource") %></th>
7
+ <th class="col-md-1"><%= _("Result") %></th>
8
+ <th class="col-md-1"><%= _("Actions") %></th>
8
9
  </tr>
9
10
  </thead>
10
11
  <tbody>
@@ -14,8 +15,9 @@
14
15
  <td>
15
16
  <%= render :partial => 'detailed_message', :locals => { :message => log.message } %>
16
17
  </td>
17
- <td><%= h trunc_with_tooltip(log.source) %></td>
18
+ <td><%= log.source %></td>
18
19
  <td><span <%= result_tag log.result %>><%= h log.result %></span></td>
20
+ <td><%= host_search_by_rule_result_buttons(log.source) %></td>
19
21
  </tr>
20
22
  <% end %>
21
23
  <tr id='ntsh' <%= "style='display: none;'".html_safe if logs.size > 0%>>
@@ -1,14 +1,16 @@
1
1
  <% javascript 'charts', 'dashboard', 'foreman_openscap/scap_hosts_show' %>
2
2
 
3
3
  <%= breadcrumbs(:resource_url => api_hosts_path,
4
- :name_field => 'name',
5
- :switchable => false,
6
- :items => [
7
- { :caption => _('Compliance Hosts') },
8
- { :caption => (N_("%s compliance reports by policy") % @host.to_label) }
9
- ])
4
+ :resource_filter => "is_compliance_host = true",
5
+ :name_field => 'name',
6
+ :switchable => true,
7
+ :items => [
8
+ { :caption => _('Compliance Hosts'),
9
+ :url => url_for(hosts_path(:search => "is_compliance_host = true")) },
10
+ { :caption => ((N_("%s compliance reports by policy") % @host.to_label)),
11
+ :url => (host_path(@host) if authorized_for(hash_for_host_path(@host))) }
12
+ ])
10
13
  %>
11
-
12
14
  <% title n_("%s compliance report by policy", "%s compliance reports by policy" , @host.combined_policies.length) % @host.to_label %>
13
15
  <% @host.combined_policies.each do |policy| %>
14
16
  <h2 class="center-block"><%= _('Policy %s') % policy %></h2>