foreman_openscap 0.10.4 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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>