foreman_openscap 0.6.4 → 0.6.5
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/controllers/api/v2/compliance/arf_reports_controller.rb +20 -5
- data/app/controllers/arf_reports_controller.rb +15 -3
- data/app/controllers/concerns/foreman_openscap/arf_reports_controller_common_extensions.rb +8 -0
- data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +4 -4
- data/app/models/concerns/foreman_openscap/host_extensions.rb +14 -15
- data/app/models/foreman_openscap/arf_report.rb +9 -5
- data/app/models/foreman_openscap/policy.rb +6 -2
- data/app/services/foreman_openscap/openscap_proxy_assigned_version_check.rb +14 -0
- data/app/services/foreman_openscap/openscap_proxy_version_check.rb +1 -1
- data/app/views/arf_reports/show.html.erb +2 -1
- data/app/views/job_templates/run_openscap_scans.erb +21 -0
- data/config/routes.rb +2 -0
- data/db/seeds.d/75-job_templates.rb +10 -0
- data/lib/foreman_openscap/engine.rb +21 -2
- data/lib/foreman_openscap/version.rb +1 -1
- data/test/files/arf_report/arf_report.html +815 -0
- data/test/functional/arf_reports_controller_test.rb +26 -7
- data/test/unit/concerns/host_extensions_test.rb +25 -0
- data/test/unit/policy_test.rb +24 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af14c957ab312cad9a1af665492c7684fbd4483f
|
4
|
+
data.tar.gz: 7085d5dd248a19fa3c746cc37756630bba065429
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bae574807e8c53cffa7e3cf1273aacf1c01c102c89cd2a5b9128042b394fb05ad60cfe6a55f7fdfcb6ef5e1c5ef621e9c8f048ab51e7047676c4cffbb362ffcc
|
7
|
+
data.tar.gz: db89e1a4e868dca5482d468985cac76eba3935b9bdebc9f1e16c3eac1f30dfa4e02c59373113950d559c1cbe0d5a332f8ac0dcf55f45426573931993d6c145d3
|
@@ -7,11 +7,12 @@ module Api
|
|
7
7
|
class ArfReportsController < V2::BaseController
|
8
8
|
include Api::Version2
|
9
9
|
include Foreman::Controller::SmartProxyAuth
|
10
|
+
include ForemanOpenscap::ArfReportsControllerCommonExtensions
|
10
11
|
|
11
12
|
add_smart_proxy_filters :create, :features => 'Openscap'
|
12
13
|
|
13
|
-
before_filter :find_resource, :only => %w(show destroy download)
|
14
|
-
skip_after_filter :log_response_body, :only => %w(download)
|
14
|
+
before_filter :find_resource, :only => %w(show destroy download download_html)
|
15
|
+
skip_after_filter :log_response_body, :only => %w(download download_html)
|
15
16
|
|
16
17
|
def resource_name
|
17
18
|
'::ForemanOpenscap::ArfReport'
|
@@ -58,9 +59,19 @@ module Api
|
|
58
59
|
|
59
60
|
def download
|
60
61
|
response = @arf_report.to_bzip
|
61
|
-
send_data response, :filename => "#{
|
62
|
+
send_data response, :filename => "#{format_filename}.xml.bz2"
|
62
63
|
rescue => e
|
63
|
-
|
64
|
+
handle_download_error e
|
65
|
+
end
|
66
|
+
|
67
|
+
api :GET, "/compliance/arf_reports/:id/download_html/", N_("Download ARF report in HTML")
|
68
|
+
param :id, :identifier, :required => true
|
69
|
+
|
70
|
+
def download_html
|
71
|
+
response = @arf_report.to_html
|
72
|
+
send_data response, :filename => "#{format_filename}.html"
|
73
|
+
rescue => e
|
74
|
+
handle_download_error e
|
64
75
|
end
|
65
76
|
|
66
77
|
private
|
@@ -70,9 +81,13 @@ module Api
|
|
70
81
|
instance_variable_set("@arf_report", resource_scope.find(params[:id]))
|
71
82
|
end
|
72
83
|
|
84
|
+
def handle_download_error(error)
|
85
|
+
render_error 'standard_error', :status => :internal_error, :locals => { :exception => error }
|
86
|
+
end
|
87
|
+
|
73
88
|
def action_permission
|
74
89
|
case params[:action]
|
75
|
-
when 'download'
|
90
|
+
when 'download', 'download_html'
|
76
91
|
:view
|
77
92
|
else
|
78
93
|
super
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class ArfReportsController < ApplicationController
|
2
2
|
include Foreman::Controller::AutoCompleteSearch
|
3
|
+
include ForemanOpenscap::ArfReportsControllerCommonExtensions
|
3
4
|
|
4
|
-
before_filter :find_arf_report, :only => [:show, :show_html, :destroy, :parse_html, :parse_bzip]
|
5
|
+
before_filter :find_arf_report, :only => [:show, :show_html, :destroy, :parse_html, :parse_bzip, :download_html]
|
5
6
|
before_filter :find_multiple, :only => [:delete_multiple, :submit_delete_multiple]
|
6
7
|
|
7
8
|
def model_of_controller
|
@@ -31,13 +32,24 @@ class ArfReportsController < ApplicationController
|
|
31
32
|
def parse_bzip
|
32
33
|
begin
|
33
34
|
response = @arf_report.to_bzip
|
34
|
-
send_data response, :filename => "#{
|
35
|
+
send_data response, :filename => "#{format_filename}.xml.bz2", :type => 'application/octet-stream', :disposition => 'attachement'
|
35
36
|
rescue => e
|
36
37
|
process_error(:error_msg => (_("Failed to downloaded ARF report as bzip: %s") % (e.message)),
|
37
38
|
:error_redirect => arf_report_path(@arf_report.id))
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
42
|
+
def download_html
|
43
|
+
begin
|
44
|
+
response = @arf_report.to_html
|
45
|
+
send_data response, :filename => "#{format_filename}.html",
|
46
|
+
:type => 'text/html', :disposition => 'attachement'
|
47
|
+
rescue => e
|
48
|
+
process_error(:error_msg => _("Failed to downloaded ARF report in HTML: %s") % e.message,
|
49
|
+
:error_redirect => arf_report_path(@arf_report.id))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
41
53
|
def destroy
|
42
54
|
if @arf_report.destroy
|
43
55
|
process_success(:success_msg => (_("Successfully deleted ARF report.")), :success_redirect => arf_reports_path)
|
@@ -87,7 +99,7 @@ class ArfReportsController < ApplicationController
|
|
87
99
|
|
88
100
|
def action_permission
|
89
101
|
case params[:action]
|
90
|
-
when 'show_html', 'parse_html', 'parse_bzip'
|
102
|
+
when 'show_html', 'parse_html', 'parse_bzip', 'download_html'
|
91
103
|
:view
|
92
104
|
when 'delete_multiple', 'submit_delete_multiple'
|
93
105
|
:destroy
|
@@ -68,19 +68,19 @@ module ForemanOpenscap
|
|
68
68
|
end
|
69
69
|
|
70
70
|
included do
|
71
|
-
scoped_search :
|
71
|
+
scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :compliance_policy,
|
72
72
|
:only_explicit => true, :ext_method => :search_by_policy_name
|
73
73
|
|
74
74
|
scoped_search :on => :id, :rename => :last_for, :complete_value => { :host => 0, :policy => 1 },
|
75
75
|
:only_explicit => true, :ext_method => :search_by_last_for
|
76
76
|
|
77
|
-
scoped_search :
|
77
|
+
scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :comply_with,
|
78
78
|
:only_explicit => true, :operators => ['= '], :ext_method => :search_by_comply_with
|
79
79
|
|
80
|
-
scoped_search :
|
80
|
+
scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :not_comply_with,
|
81
81
|
:only_explicit => true, :operators => ['= '], :ext_method => :search_by_not_comply_with
|
82
82
|
|
83
|
-
scoped_search :
|
83
|
+
scoped_search :relation => :policy, :on => :name, :complete_value => true, :rename => :inconclusive_with,
|
84
84
|
:only_explicit => true, :operators => ['= '], :ext_method => :search_by_inconclusive_with
|
85
85
|
|
86
86
|
compliance_status_scoped_search 'passed', :on => :status, :rename => :compliance_passed
|
@@ -10,13 +10,13 @@ module ForemanOpenscap
|
|
10
10
|
has_many :arf_reports, :class_name => '::ForemanOpenscap::ArfReport', :foreign_key => :host_id
|
11
11
|
has_one :compliance_status_object, :class_name => '::ForemanOpenscap::ComplianceStatus', :foreign_key => 'host_id'
|
12
12
|
|
13
|
-
scoped_search :
|
14
|
-
:only_explicit => true, :operators => ['= '
|
13
|
+
scoped_search :relation => :policies, :on => :name, :complete_value => true, :rename => :compliance_policy,
|
14
|
+
:only_explicit => true, :operators => ['= '], :ext_method => :search_by_policy_name
|
15
15
|
|
16
|
-
scoped_search :
|
16
|
+
scoped_search :relation => :policies, :on => :name, :complete_value => true, :rename => :compliance_report_missing_for,
|
17
17
|
:only_explicit => true, :operators => ['= ', '!= '], :ext_method => :search_by_missing_arf
|
18
18
|
|
19
|
-
scoped_search :
|
19
|
+
scoped_search :relation => :compliance_status_object, :on => :status, :rename => :compliance_status,
|
20
20
|
:complete_value => {:compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT,
|
21
21
|
:incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT,
|
22
22
|
:inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE}
|
@@ -63,7 +63,9 @@ module ForemanOpenscap
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def policies_enc
|
66
|
-
|
66
|
+
check = ForemanOpenscap::OpenscapProxyAssignedVersionCheck.new(self).run
|
67
|
+
method = check.pass? ? :to_enc : :to_enc_legacy
|
68
|
+
combined_policies.map(&method).to_json
|
67
69
|
end
|
68
70
|
|
69
71
|
def combined_policies
|
@@ -102,23 +104,20 @@ module ForemanOpenscap
|
|
102
104
|
module ClassMethods
|
103
105
|
def search_by_policy_name(key, operator, policy_name)
|
104
106
|
cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
|
105
|
-
{ :conditions => Host::Managed.arel_table[:id].in(
|
106
|
-
Host::Managed.select(Host::Managed.arel_table[:id]).joins(:policies).where(cond).ast
|
107
|
-
).to_sql }
|
107
|
+
{ :conditions => Host::Managed.arel_table[:id].in(Host::Managed.select(Host::Managed.arel_table[:id]).joins(:policies).where(cond).pluck(:id)).to_sql }
|
108
108
|
end
|
109
109
|
|
110
110
|
def search_by_missing_arf(key, operator, policy_name)
|
111
111
|
cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
|
112
|
-
{ :conditions => Host::Managed.arel_table[:id].in(
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
.where("foreman_openscap_assets.id NOT IN (
|
112
|
+
{ :conditions => Host::Managed.arel_table[:id].in(Host::Managed.select(Host::Managed.arel_table[:id]).
|
113
|
+
joins(:policies).
|
114
|
+
where(cond).
|
115
|
+
where("foreman_openscap_assets.id NOT IN (
|
117
116
|
SELECT DISTINCT foreman_openscap_arf_reports.asset_id
|
118
117
|
FROM foreman_openscap_arf_reports
|
119
118
|
WHERE foreman_openscap_arf_reports.asset_id = foreman_openscap_assets.id
|
120
|
-
AND foreman_openscap_arf_reports.policy_id = foreman_openscap_policies.id)
|
121
|
-
|
119
|
+
AND foreman_openscap_arf_reports.policy_id = foreman_openscap_policies.id)").
|
120
|
+
pluck(:id)).to_sql
|
122
121
|
}
|
123
122
|
end
|
124
123
|
end
|
@@ -164,11 +164,15 @@ module ForemanOpenscap
|
|
164
164
|
end
|
165
165
|
|
166
166
|
def destroy
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
167
|
+
if host
|
168
|
+
begin
|
169
|
+
openscap_proxy_api.destroy_report(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
|
170
|
+
rescue Foreman::Exception => e
|
171
|
+
logger.error "Failed to delete report with id #{id} from proxy, cause: #{e.message}"
|
172
|
+
logger.debug e.backtrace.join("\n\t")
|
173
|
+
end
|
174
|
+
else
|
175
|
+
logger.error "Failed to delete report with id #{id} from proxy, no host associated with report"
|
172
176
|
end
|
173
177
|
super
|
174
178
|
end
|
@@ -171,11 +171,15 @@ module ForemanOpenscap
|
|
171
171
|
'profile_id' => profile_for_scan,
|
172
172
|
'content_path' => "/var/lib/openscap/content/#{self.scap_content.digest}.xml",
|
173
173
|
'tailoring_path' => tailoring_file ? "/var/lib/openscap/tailoring/#{self.tailoring_file.digest}.xml" : '',
|
174
|
-
'download_path' => "/compliance/policies/#{self.id}/content",
|
175
|
-
'tailoring_download_path' => "/compliance/policies/#{self.id}/tailoring"
|
174
|
+
'download_path' => "/compliance/policies/#{self.id}/content/#{scap_content.digest}",
|
175
|
+
'tailoring_download_path' => tailoring_file ? "/compliance/policies/#{self.id}/tailoring/#{tailoring_file.digest}" : ''
|
176
176
|
}.merge(period_enc)
|
177
177
|
end
|
178
178
|
|
179
|
+
def to_enc_legacy
|
180
|
+
to_enc.tap { |hash| hash['download_path'] = "/compliance/policies/#{self.id}/content" }
|
181
|
+
end
|
182
|
+
|
179
183
|
def should_validate?(step_name)
|
180
184
|
if new_record? && wizard_initiated?
|
181
185
|
step_index > step_to_i(step_name)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ForemanOpenscap
|
2
|
+
class OpenscapProxyAssignedVersionCheck < OpenscapProxyVersionCheck
|
3
|
+
def initialize(host)
|
4
|
+
@host = host
|
5
|
+
super()
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def get_openscap_proxies
|
11
|
+
@host.openscap_proxy ? [@host.openscap_proxy] : []
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -12,5 +12,6 @@
|
|
12
12
|
display_delete_if_authorized(hash_for_arf_report_path(:id => @arf_report), :class=> "btn btn-danger"),
|
13
13
|
link_to(_("Host details"), @arf_report.host, :class => "btn btn-default"),
|
14
14
|
link_to(_("View full report"), show_html_arf_report_path(:id => @arf_report.id), :class => "btn btn-default"),
|
15
|
-
link_to(_("Download XML in bzip"), parse_bzip_arf_report_path(:id => @arf_report.id), :class => "btn btn-default", :data => { :no_turbolink => true })
|
15
|
+
link_to(_("Download XML in bzip"), parse_bzip_arf_report_path(:id => @arf_report.id), :class => "btn btn-default", :data => { :no_turbolink => true }),
|
16
|
+
link_to(_("Download HTML"), download_html_arf_report_path(:id => @arf_report.id), :class => "btn btn-default", :data => { :no_turbolink => true })
|
16
17
|
%>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%#
|
2
|
+
name: Run OpenSCAP scans
|
3
|
+
job_category: OpenSCAP
|
4
|
+
description_format: Run scan for all OpenSCAP policies on host
|
5
|
+
feature: foreman_openscap_run_scans
|
6
|
+
provider_type: SSH
|
7
|
+
snippet: false
|
8
|
+
template_inputs:
|
9
|
+
- name: policies
|
10
|
+
required: false
|
11
|
+
input_type: puppet_parameter
|
12
|
+
puppet_class_name: foreman_scap_client
|
13
|
+
puppet_parameter_name: policies
|
14
|
+
advanced: false
|
15
|
+
provider_type: SSH
|
16
|
+
kind: job_template
|
17
|
+
%>
|
18
|
+
|
19
|
+
<% input('policies').map { |policy_config| policy_config['id'] }.each do |id| -%>
|
20
|
+
/usr/bin/foreman_scap_client <%= id %>
|
21
|
+
<% end -%>
|
data/config/routes.rb
CHANGED
@@ -7,6 +7,7 @@ Rails.application.routes.draw do
|
|
7
7
|
get 'show_html'
|
8
8
|
get 'parse_html'
|
9
9
|
get 'parse_bzip'
|
10
|
+
get 'download_html'
|
10
11
|
end
|
11
12
|
collection do
|
12
13
|
get 'auto_complete_search'
|
@@ -80,6 +81,7 @@ Rails.application.routes.draw do
|
|
80
81
|
resources :arf_reports, :only => [:index, :show, :destroy] do
|
81
82
|
member do
|
82
83
|
get 'download'
|
84
|
+
get 'download_html'
|
83
85
|
end
|
84
86
|
end
|
85
87
|
post 'arf_reports/:cname/:policy_id/:date', \
|
@@ -0,0 +1,10 @@
|
|
1
|
+
if ForemanOpenscap.with_remote_execution?
|
2
|
+
User.as_anonymous_admin do
|
3
|
+
JobTemplate.without_auditing do
|
4
|
+
Dir[File.join("#{ForemanOpenscap::Engine.root}/app/views/job_templates/**/*.erb")].each do |template|
|
5
|
+
sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
|
6
|
+
JobTemplate.import!(File.read(template), :default => true, :locked => true, :update => sync)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -9,6 +9,7 @@ module ForemanOpenscap
|
|
9
9
|
config.autoload_paths += Dir["#{config.root}/app/models"]
|
10
10
|
config.autoload_paths += Dir["#{config.root}/app/overrides"]
|
11
11
|
config.autoload_paths += Dir["#{config.root}/app/lib"]
|
12
|
+
config.autoload_paths += Dir["#{config.root}/app/services"]
|
12
13
|
config.autoload_paths += Dir["#{config.root}/lib"]
|
13
14
|
config.autoload_paths += Dir["#{config.root}/test/"]
|
14
15
|
|
@@ -51,8 +52,8 @@ module ForemanOpenscap
|
|
51
52
|
# Add permissions
|
52
53
|
security_block :foreman_openscap do
|
53
54
|
permission :view_arf_reports, {:arf_reports => [:index, :show, :parse_html, :show_html,
|
54
|
-
:parse_bzip, :auto_complete_search],
|
55
|
-
'api/v2/compliance/arf_reports' => [:index, :show, :download],
|
55
|
+
:parse_bzip, :auto_complete_search, :download_html],
|
56
|
+
'api/v2/compliance/arf_reports' => [:index, :show, :download, :download_html],
|
56
57
|
:compliance_hosts => [:show]},
|
57
58
|
:resource_type => 'ForemanOpenscap::ArfReport'
|
58
59
|
permission :destroy_arf_reports, {:arf_reports => [:destroy, :delete_multiple, :submit_delete_multiple],
|
@@ -154,6 +155,20 @@ module ForemanOpenscap
|
|
154
155
|
parameter_filter Hostgroup, :openscap_proxy_id, :openscap_proxy
|
155
156
|
parameter_filter Log, :result
|
156
157
|
|
158
|
+
if ForemanOpenscap.with_remote_execution?
|
159
|
+
RemoteExecutionFeature.register(:foreman_openscap_run_scans, N_("Run OpenSCAP scan"),
|
160
|
+
:description => N_("Run OpenSCAP scan"),
|
161
|
+
:host_action_button => true,
|
162
|
+
:provided_inputs => "policies")
|
163
|
+
end
|
164
|
+
|
165
|
+
add_controller_action_scope(::Api::V2::HostsController, :index) do |base_scope|
|
166
|
+
base_scope.includes(:policies)
|
167
|
+
end
|
168
|
+
|
169
|
+
add_controller_action_scope(::HostsController, :index) do |base_scope|
|
170
|
+
base_scope.includes(:policies)
|
171
|
+
end
|
157
172
|
end
|
158
173
|
end
|
159
174
|
|
@@ -194,4 +209,8 @@ module ForemanOpenscap
|
|
194
209
|
def self.use_relative_model_naming?
|
195
210
|
true
|
196
211
|
end
|
212
|
+
|
213
|
+
def self.with_remote_execution?
|
214
|
+
RemoteExecutionFeature rescue false
|
215
|
+
end
|
197
216
|
end
|