foreman_openscap 4.0.4 → 4.2.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/stylesheets/foreman_openscap/policy.css +5 -0
- data/app/controllers/api/v2/compliance/scap_contents_controller.rb +32 -1
- data/app/helpers/arf_reports_helper.rb +7 -10
- data/app/helpers/policies_helper.rb +4 -17
- data/app/models/concerns/foreman_openscap/host_extensions.rb +5 -0
- data/app/models/foreman_openscap/arf_report.rb +3 -7
- data/app/models/foreman_openscap/compliance_status.rb +4 -0
- data/app/models/foreman_openscap/policy.rb +11 -6
- data/app/views/api/v2/compliance/scap_contents/bulk_upload.json.rabl +7 -0
- data/app/views/arf_reports/show.html.erb +1 -1
- data/app/views/arf_reports/show_html.html.erb +1 -0
- data/app/views/compliance_hosts/show.html.erb +1 -8
- data/app/views/policies/edit.html.erb +3 -2
- data/app/views/policies/show.html.erb +3 -1
- data/app/views/scap_contents/edit.html.erb +2 -12
- data/app/views/tailoring_files/edit.html.erb +2 -10
- data/config/routes.rb +3 -0
- data/db/migrate/20201202110213_update_puppet_port_param_type.rb +28 -0
- data/db/seeds.d/75-job_templates.rb +3 -2
- data/lib/foreman_openscap/bulk_upload.rb +46 -20
- data/lib/foreman_openscap/engine.rb +14 -14
- data/lib/foreman_openscap/version.rb +1 -1
- data/lib/tasks/foreman_openscap_tasks.rake +15 -3
- data/test/factories/compliance_log_factory.rb +0 -6
- data/test/functional/api/v2/compliance/arf_reports_controller_test.rb +4 -4
- data/test/lib/foreman_openscap/bulk_upload_test.rb +48 -0
- data/test/test_plugin_helper.rb +3 -3
- data/test/unit/policy_test.rb +24 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69eab4d9434f1b502ba511db38d8a7faff9721c5416703f6010ccc87fdc52b86
|
4
|
+
data.tar.gz: 94ba4cbecc85106f968d9b5f137e0808dbd12711db01fd14e0f0c4e9761e27a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e3253f876e3ab4efd5c853fdb05f0b81cbbe7184c5b00ea552690b0cce9664a76210c32f92fe86c631bc9eaa2ed81ba1a8762b8b47e0678149a946cf593554e
|
7
|
+
data.tar.gz: a6c3706f6fcc836af18f7aeda76c1cf735981836a0661cdcc66e4ead2272b6249519f305ff3b6766266ebb05eda1ebfe778811993286be3e162e269412aa6fd8
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'foreman_openscap/bulk_upload'
|
2
|
+
|
1
3
|
module Api::V2
|
2
4
|
module Compliance
|
3
5
|
class ScapContentsController < ::Api::V2::BaseController
|
@@ -5,7 +7,11 @@ module Api::V2
|
|
5
7
|
include ForemanOpenscap::BodyLogExtensions
|
6
8
|
include ForemanOpenscap::Api::V2::ScapApiControllerExtensions
|
7
9
|
|
8
|
-
|
10
|
+
def self.bulk_upload_types
|
11
|
+
['files', 'directory', 'default']
|
12
|
+
end
|
13
|
+
|
14
|
+
before_action :find_resource, :except => %w[index create bulk_upload]
|
9
15
|
|
10
16
|
api :GET, '/compliance/scap_contents', N_('List SCAP contents')
|
11
17
|
param_group :search_and_pagination, ::Api::V2::BaseController
|
@@ -61,6 +67,29 @@ module Api::V2
|
|
61
67
|
process_response @scap_content.destroy
|
62
68
|
end
|
63
69
|
|
70
|
+
api :POST, '/compliance/scap_contents/bulk_upload', N_('Upload scap contents in bulk')
|
71
|
+
param :type, bulk_upload_types, :required => true, :desc => N_('Type of the upload')
|
72
|
+
param :files, Array, :desc => N_('File paths to upload when using "files" upload type')
|
73
|
+
param :directory, String, :desc => N_('Directory to upload when using "directory" upload type')
|
74
|
+
|
75
|
+
def bulk_upload
|
76
|
+
case params[:type]
|
77
|
+
when 'files'
|
78
|
+
@result = ForemanOpenscap::BulkUpload.new.upload_from_files(params[:files])
|
79
|
+
when 'directory'
|
80
|
+
@result = ForemanOpenscap::BulkUpload.new.upload_from_directory(params[:directory])
|
81
|
+
when 'default'
|
82
|
+
@result = ForemanOpenscap::BulkUpload.new.upload_from_scap_guide
|
83
|
+
else
|
84
|
+
return render :json => {
|
85
|
+
:errors => [
|
86
|
+
_("Please specify import type, received: %{received}, expected one of: %{expected}") %
|
87
|
+
{ :expected => self.class.bulk_upload_types.join(', '), :received => params[:type] }
|
88
|
+
]
|
89
|
+
}, :status => :unprocessable_entity
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
64
93
|
private
|
65
94
|
|
66
95
|
def find_resource
|
@@ -70,6 +99,8 @@ module Api::V2
|
|
70
99
|
|
71
100
|
def action_permission
|
72
101
|
case params[:action]
|
102
|
+
when 'bulk_upload'
|
103
|
+
:create
|
73
104
|
when 'xml'
|
74
105
|
:view
|
75
106
|
else
|
@@ -14,16 +14,13 @@ module ArfReportsHelper
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def arf_report_breadcrumbs
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
:url => (arf_report_path(@arf_report) if authorized_for(hash_for_arf_report_path(@arf_report))) }
|
25
|
-
])
|
26
|
-
end
|
17
|
+
breadcrumbs(:resource_url => api_compliance_arf_reports_path,
|
18
|
+
:switchable => false,
|
19
|
+
:items => [
|
20
|
+
{ :caption => _('Compliance Reports'),
|
21
|
+
:url => url_for(arf_reports_path) },
|
22
|
+
{ :caption => @arf_report.host.to_s }
|
23
|
+
])
|
27
24
|
end
|
28
25
|
|
29
26
|
def result_tag(level)
|
@@ -11,10 +11,10 @@ module PoliciesHelper
|
|
11
11
|
|
12
12
|
def deploy_by_radios(f, policy)
|
13
13
|
ForemanOpenscap::ConfigNameService.new.configs.map do |tool|
|
14
|
-
popover_block = popover("", config_inline_help(tool.inline_help))
|
14
|
+
popover_block = tag.span(popover("", config_inline_help(tool.inline_help)), class: 'scap_policy_popover')
|
15
15
|
|
16
|
-
label = label_tag('', :class => 'col-md-2 control-label') do
|
17
|
-
tool.type.to_s.capitalize.html_safe
|
16
|
+
label = label_tag('', :class => 'col-md-2 control-label', :for => "policy_deploy_by_#{tool.type}") do
|
17
|
+
tool.type.to_s.capitalize.html_safe
|
18
18
|
end
|
19
19
|
|
20
20
|
radio = content_tag(:div, :class => "col-md-2") do
|
@@ -23,7 +23,7 @@ module PoliciesHelper
|
|
23
23
|
|
24
24
|
content_tag(:div, :class => "clearfix") do
|
25
25
|
content_tag(:div, :class => "form-group") do
|
26
|
-
label.html_safe + radio.html_safe
|
26
|
+
label.html_safe + popover_block.html_safe + radio.html_safe
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end.join('').html_safe
|
@@ -136,17 +136,4 @@ module PoliciesHelper
|
|
136
136
|
def translate_steps(policy)
|
137
137
|
policy.steps.map { |step| _(step) }
|
138
138
|
end
|
139
|
-
|
140
|
-
def policy_breadcrumbs
|
141
|
-
if @policy
|
142
|
-
breadcrumbs(:resource_url => api_compliance_policies_path,
|
143
|
-
:name_field => 'name',
|
144
|
-
:items => [
|
145
|
-
{ :caption => _('Policies'),
|
146
|
-
:url => url_for(policies_path) },
|
147
|
-
{ :caption => @policy.name,
|
148
|
-
:url => (edit_policy_path(@policy) if authorized_for(hash_for_edit_policy_path(@policy))) }
|
149
|
-
])
|
150
|
-
end
|
151
|
-
end
|
152
139
|
end
|
@@ -81,6 +81,11 @@ module ForemanOpenscap
|
|
81
81
|
}
|
82
82
|
|
83
83
|
base.send :extend, ClassMethods
|
84
|
+
|
85
|
+
base.apipie :class do
|
86
|
+
property :policies_enc, String, desc: 'Returns JSON string containing policies for the host'
|
87
|
+
property :policies_enc_raw, array_of: Hash, desc: 'Returns a list with key:value objects containing policies for the host'
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
def inherited_attributes
|
@@ -125,11 +125,9 @@ module ForemanOpenscap
|
|
125
125
|
msg = Log.where(:source_id => src.id).order(:id => :desc).first.message
|
126
126
|
update_msg_with_changes(msg, log)
|
127
127
|
else
|
128
|
-
|
129
|
-
if (msg = Message.find_by(:digest => digest))
|
128
|
+
if (msg = Message.find_by(:value => log[:title]))
|
130
129
|
msg.attributes = {
|
131
130
|
:value => N_(log[:title]),
|
132
|
-
:digest => digest,
|
133
131
|
:severity => log[:severity],
|
134
132
|
:description => newline_to_space(log[:description]),
|
135
133
|
:rationale => newline_to_space(log[:rationale]),
|
@@ -137,7 +135,6 @@ module ForemanOpenscap
|
|
137
135
|
}
|
138
136
|
else
|
139
137
|
msg = Message.new(:value => N_(log[:title]),
|
140
|
-
:digest => digest,
|
141
138
|
:severity => log[:severity],
|
142
139
|
:description => newline_to_space(log[:description]),
|
143
140
|
:rationale => newline_to_space(log[:rationale]),
|
@@ -159,8 +156,8 @@ module ForemanOpenscap
|
|
159
156
|
|
160
157
|
def assign_locations_organizations
|
161
158
|
if host
|
162
|
-
self.location_ids = [host.location_id]
|
163
|
-
self.organization_ids = [host.organization_id]
|
159
|
+
self.location_ids = [host.location_id]
|
160
|
+
self.organization_ids = [host.organization_id]
|
164
161
|
end
|
165
162
|
end
|
166
163
|
|
@@ -233,7 +230,6 @@ module ForemanOpenscap
|
|
233
230
|
msg.value = incoming_data['title']
|
234
231
|
|
235
232
|
return unless msg.changed?
|
236
|
-
msg.digest = Digest::SHA1.hexdigest(msg.value) if msg.value_changed?
|
237
233
|
msg.save
|
238
234
|
end
|
239
235
|
end
|
@@ -6,6 +6,8 @@ module ForemanOpenscap
|
|
6
6
|
include Taxonomix
|
7
7
|
attr_writer :current_step, :wizard_initiated
|
8
8
|
|
9
|
+
STEPS_LIST = [N_('Deployment Options'), N_('Policy Attributes'), N_('SCAP Content'), N_('Schedule'), N_('Locations'), N_('Organizations'), N_('Hostgroups')]
|
10
|
+
|
9
11
|
belongs_to :scap_content
|
10
12
|
belongs_to :scap_content_profile
|
11
13
|
belongs_to :tailoring_file
|
@@ -108,10 +110,7 @@ module ForemanOpenscap
|
|
108
110
|
end
|
109
111
|
|
110
112
|
def steps
|
111
|
-
|
112
|
-
base_steps << N_('Locations') if SETTINGS[:locations_enabled]
|
113
|
-
base_steps << N_('Organizations') if SETTINGS[:organizations_enabled]
|
114
|
-
base_steps << N_('Hostgroups') # always be last.
|
113
|
+
STEPS_LIST
|
115
114
|
end
|
116
115
|
|
117
116
|
def current_step
|
@@ -174,8 +173,14 @@ module ForemanOpenscap
|
|
174
173
|
end
|
175
174
|
|
176
175
|
def unassign_hosts(hosts)
|
177
|
-
|
178
|
-
|
176
|
+
policy_host_assets = ForemanOpenscap::Asset.joins(:asset_policies).where(
|
177
|
+
:assetable_type => 'Host::Base',
|
178
|
+
:assetable_id => hosts.map(&:id),
|
179
|
+
:foreman_openscap_asset_policies => { :policy_id => id }
|
180
|
+
).pluck(:id)
|
181
|
+
|
182
|
+
self.asset_ids = self.asset_ids - policy_host_assets
|
183
|
+
ForemanOpenscap::Asset.where(:id => policy_host_assets).destroy_all
|
179
184
|
end
|
180
185
|
|
181
186
|
def to_enc
|
@@ -3,14 +3,7 @@
|
|
3
3
|
|
4
4
|
<%= breadcrumbs(:resource_url => api_hosts_path,
|
5
5
|
:resource_filter => "is_compliance_host = true",
|
6
|
-
:name_field => 'name'
|
7
|
-
:switchable => true,
|
8
|
-
:items => [
|
9
|
-
{ :caption => _('Compliance Hosts'),
|
10
|
-
:url => url_for(hosts_path(:search => "is_compliance_host = true")) },
|
11
|
-
{ :caption => ((N_("%s compliance reports by policy") % @host.to_label)),
|
12
|
-
:url => (host_path(@host) if authorized_for(hash_for_host_path(@host))) }
|
13
|
-
])
|
6
|
+
:name_field => 'name')
|
14
7
|
%>
|
15
8
|
<% title n_("%s compliance report by policy", "%s compliance reports by policy" , @host.combined_policies.length) % @host.to_label %>
|
16
9
|
<% @host.combined_policies.each do |policy| %>
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
<% title _("Details for Compliance Policy %s") % @policy.name %>
|
2
|
+
<%= breadcrumbs(:resource_url => api_compliance_policies_path,
|
3
|
+
:name_field => 'name') %>
|
2
4
|
|
3
5
|
<div class="row">
|
4
6
|
<iframe style="min-height: 800px" height="100%" width="100%" frameborder="0" src="<%= parse_policy_path(@policy) %>"></iframe>
|
@@ -1,15 +1,5 @@
|
|
1
|
-
<% title _("Edit
|
1
|
+
<% title _("Edit %s") % @scap_content.title %>
|
2
2
|
<%= breadcrumbs(:resource_url => api_compliance_scap_contents_path,
|
3
|
-
:name_field => 'title'
|
4
|
-
:items => [
|
5
|
-
{ :caption => _('Scap Contents'),
|
6
|
-
:url => url_for(scap_contents_path)
|
7
|
-
},
|
8
|
-
{ :caption => @scap_content.title,
|
9
|
-
:url => (edit_scap_content_path(@scap_content) if authorized_for(hash_for_edit_scap_content_path(@scap_content)))
|
10
|
-
}
|
11
|
-
]
|
12
|
-
) if @scap_content %>
|
13
|
-
|
3
|
+
:name_field => 'title') %>
|
14
4
|
|
15
5
|
<%= render :partial => 'form' %>
|
@@ -1,13 +1,5 @@
|
|
1
|
-
<% title _("Edit
|
1
|
+
<% title _("Edit %s") % @tailoring_file.name %>
|
2
2
|
<%= breadcrumbs(:resource_url => api_compliance_tailoring_files_path,
|
3
|
-
:
|
4
|
-
{ :caption => _('Tailoring Files'),
|
5
|
-
:url => url_for(tailoring_files_path)
|
6
|
-
},
|
7
|
-
{ :caption => @tailoring_file.name,
|
8
|
-
:url => (edit_tailoring_file_path(@tailoring_file) if authorized_for(hash_for_edit_tailoring_file_path(@tailoring_file)))
|
9
|
-
}
|
10
|
-
]
|
11
|
-
) if @tailoring_file %>
|
3
|
+
:name_field => 'name') %>
|
12
4
|
|
13
5
|
<%= render :partial => 'form' %>
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
class UpdatePuppetPortParamType < ActiveRecord::Migration[6.0]
|
2
|
+
def up
|
3
|
+
update_port_type :to_i
|
4
|
+
end
|
5
|
+
|
6
|
+
def down
|
7
|
+
update_port_type :to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def update_port_type(method)
|
13
|
+
puppet_class = Puppetclass.find_by :name => 'foreman_scap_client'
|
14
|
+
return unless puppet_class
|
15
|
+
port_key = puppet_class.class_params.find_by :key => 'port'
|
16
|
+
return unless port_key
|
17
|
+
def_value = port_key.default_value
|
18
|
+
|
19
|
+
if method == :to_i
|
20
|
+
port_key.key_type = "integer"
|
21
|
+
port_key.default_value = def_value.to_i
|
22
|
+
else
|
23
|
+
port_key.key_type == "string"
|
24
|
+
port_key.default_value = port_key.default_value.to_s
|
25
|
+
end
|
26
|
+
port_key.save!
|
27
|
+
end
|
28
|
+
end
|
@@ -11,8 +11,9 @@ if ForemanOpenscap.with_remote_execution?
|
|
11
11
|
else
|
12
12
|
template = JobTemplate.import!(File.read(template), :default => true, :lock => true, :update => sync)
|
13
13
|
end
|
14
|
-
|
15
|
-
template.
|
14
|
+
next unless template.present?
|
15
|
+
template.organizations = organizations
|
16
|
+
template.locations = locations
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -1,48 +1,74 @@
|
|
1
1
|
require 'digest/sha2'
|
2
|
+
require 'ostruct'
|
3
|
+
|
2
4
|
module ForemanOpenscap
|
3
5
|
class BulkUpload
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
def initialize
|
7
|
+
@result = OpenStruct.new(:errors => [], :results => [])
|
8
|
+
end
|
9
|
+
|
10
|
+
def files_from_guide
|
11
|
+
`rpm -ql scap-security-guide | grep ds.xml`.split
|
7
12
|
end
|
8
13
|
|
9
|
-
def
|
10
|
-
|
14
|
+
def scap_guide_installed?
|
15
|
+
`rpm -qa | grep scap-security-guide`.present?
|
16
|
+
end
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
def upload_from_scap_guide
|
19
|
+
unless scap_guide_installed?
|
20
|
+
@result.errors.push("Can't find scap-security-guide RPM, are you sure it is installed on your server?")
|
21
|
+
return @result
|
15
22
|
end
|
16
23
|
|
17
|
-
|
18
|
-
upload_from_files(files_array) unless files_array.empty?
|
24
|
+
upload_from_files(files_from_guide, true)
|
19
25
|
end
|
20
26
|
|
21
|
-
def upload_from_files(files_array)
|
27
|
+
def upload_from_files(files_array, from_scap_guide = false)
|
28
|
+
unless files_array.is_a? Array
|
29
|
+
@result.errors.push("Expected an array of files to upload, got: #{files_array}.")
|
30
|
+
return @result
|
31
|
+
end
|
32
|
+
|
22
33
|
files_array.each do |datastream|
|
34
|
+
if File.directory?(datastream)
|
35
|
+
@result.errors.push("#{datastream} is a directory, expecting file.")
|
36
|
+
next
|
37
|
+
end
|
38
|
+
|
39
|
+
unless File.file?(datastream)
|
40
|
+
@result.errors.push("#{datastream} does not exist, skipping.")
|
41
|
+
next
|
42
|
+
end
|
43
|
+
|
23
44
|
file = File.open(datastream, 'rb').read
|
24
45
|
digest = Digest::SHA2.hexdigest(datastream)
|
25
|
-
title = content_name(datastream)
|
46
|
+
title = content_name(datastream, from_scap_guide)
|
26
47
|
filename = original_filename(datastream)
|
27
48
|
scap_content = ScapContent.where(:title => title, :digest => digest).first_or_initialize
|
28
49
|
next if scap_content.persisted?
|
29
50
|
scap_content.scap_file = file
|
30
51
|
scap_content.original_filename = filename
|
31
|
-
scap_content.location_ids = Location.all.
|
32
|
-
scap_content.organization_ids = Organization.all.
|
52
|
+
scap_content.location_ids = Location.all.pluck(:id)
|
53
|
+
scap_content.organization_ids = Organization.all.pluck(:id)
|
33
54
|
|
34
|
-
next puts "## SCAP content is invalid: #{scap_content.errors.full_messages.uniq.join(',')} ##" unless scap_content.valid?
|
35
55
|
if scap_content.save
|
36
|
-
|
56
|
+
@result.results.push(scap_content)
|
37
57
|
else
|
38
|
-
|
58
|
+
@result.errors.push("Failed saving #{datastream}: #{scap_content.errors.full_messages.uniq.join(',')}")
|
39
59
|
end
|
40
60
|
end
|
61
|
+
@result
|
41
62
|
end
|
42
63
|
|
43
64
|
def upload_from_directory(directory_path)
|
65
|
+
unless directory_path && Dir.exist?(directory_path)
|
66
|
+
@result[:errors].push("No such directory: #{directory_path}. Please check the path you have provided.")
|
67
|
+
return @result
|
68
|
+
end
|
69
|
+
|
44
70
|
files_array = Dir["#{directory_path}/*-ds.xml"]
|
45
|
-
upload_from_files(files_array)
|
71
|
+
upload_from_files(files_array)
|
46
72
|
end
|
47
73
|
|
48
74
|
private
|
@@ -57,9 +83,9 @@ module ForemanOpenscap
|
|
57
83
|
file.split('/').last
|
58
84
|
end
|
59
85
|
|
60
|
-
def content_name(datastream)
|
86
|
+
def content_name(datastream, from_scap_guide)
|
61
87
|
os_name = extract_name_from_file(datastream)
|
62
|
-
|
88
|
+
from_scap_guide ? "Red Hat #{os_name} default content" : "#{os_name} content"
|
63
89
|
end
|
64
90
|
end
|
65
91
|
end
|
@@ -92,7 +92,7 @@ module ForemanOpenscap
|
|
92
92
|
'api/v2/compliance/scap_contents' => [:update] },
|
93
93
|
:resource_type => 'ForemanOpenscap::ScapContent'
|
94
94
|
permission :create_scap_contents, { :scap_contents => %i[new create],
|
95
|
-
'api/v2/compliance/scap_contents' => [
|
95
|
+
'api/v2/compliance/scap_contents' => %i[create bulk_upload] },
|
96
96
|
:resource_type => 'ForemanOpenscap::ScapContent'
|
97
97
|
permission :destroy_scap_contents, { :scap_contents => [:destroy],
|
98
98
|
'api/v2/compliance/scap_contents' => [:destroy] },
|
@@ -180,19 +180,6 @@ module ForemanOpenscap
|
|
180
180
|
:description => proxy_description,
|
181
181
|
:api_description => N_('ID of OpenSCAP Proxy')
|
182
182
|
|
183
|
-
if ForemanOpenscap.with_remote_execution?
|
184
|
-
options = {
|
185
|
-
:description => N_("Run OpenSCAP scan"),
|
186
|
-
:provided_inputs => "policies"
|
187
|
-
}
|
188
|
-
|
189
|
-
if Gem::Version.new(ForemanRemoteExecution::VERSION) >= Gem::Version.new('1.2.3')
|
190
|
-
options[:host_action_button] = true
|
191
|
-
end
|
192
|
-
|
193
|
-
RemoteExecutionFeature.register(:foreman_openscap_run_scans, N_("Run OpenSCAP scan"), options)
|
194
|
-
end
|
195
|
-
|
196
183
|
add_controller_action_scope('Api::V2::HostsController', :index) do |base_scope|
|
197
184
|
base_scope.preload(:policies)
|
198
185
|
end
|
@@ -231,6 +218,19 @@ module ForemanOpenscap
|
|
231
218
|
Log.send(:include, ForemanOpenscap::LogExtensions)
|
232
219
|
BookmarkControllerValidator.send(:prepend, ForemanOpenscap::BookmarkControllerValidatorExtensions)
|
233
220
|
ProxyStatus.status_registry.add(ProxyStatus::OpenscapSpool)
|
221
|
+
|
222
|
+
if ForemanOpenscap.with_remote_execution?
|
223
|
+
options = {
|
224
|
+
:description => N_("Run OpenSCAP scan"),
|
225
|
+
:provided_inputs => "policies"
|
226
|
+
}
|
227
|
+
|
228
|
+
if Gem::Version.new(ForemanRemoteExecution::VERSION) >= Gem::Version.new('1.2.3')
|
229
|
+
options[:host_action_button] = true
|
230
|
+
end
|
231
|
+
|
232
|
+
RemoteExecutionFeature.register(:foreman_openscap_run_scans, N_("Run OpenSCAP scan"), options)
|
233
|
+
end
|
234
234
|
end
|
235
235
|
|
236
236
|
rake_tasks do
|
@@ -6,23 +6,26 @@ namespace :foreman_openscap do
|
|
6
6
|
namespace :bulk_upload do
|
7
7
|
desc 'Bulk upload SCAP content from directory'
|
8
8
|
task :directory, [:directory] => [:environment] do |task, args|
|
9
|
+
deprecate_upload_from_rake
|
9
10
|
abort("# No such directory, please check the path you have provided. #") unless args[:directory].blank? || Dir.exist?(args[:directory])
|
10
11
|
User.current = User.anonymous_admin
|
11
|
-
ForemanOpenscap::BulkUpload.new.upload_from_directory(args[:directory])
|
12
|
+
print_upload_result ForemanOpenscap::BulkUpload.new.upload_from_directory(args[:directory])
|
12
13
|
end
|
13
14
|
|
14
15
|
task :files, [:files] => [:environment] do |task, args|
|
16
|
+
deprecate_upload_from_rake
|
15
17
|
files_array = args[:files].split(' ')
|
16
18
|
files_array.each do |file|
|
17
19
|
abort("# #{file} is a directory, expecting file. Try using 'rake foreman_openscap:bulk_upload:directory' with this directory. #") if File.directory?(file)
|
18
20
|
end
|
19
21
|
User.current = User.anonymous_admin
|
20
|
-
ForemanOpenscap::BulkUpload.new.upload_from_files(files_array)
|
22
|
+
print_upload_result ForemanOpenscap::BulkUpload.new.upload_from_files(files_array)
|
21
23
|
end
|
22
24
|
|
23
25
|
task :default => [:environment] do
|
26
|
+
deprecate_upload_from_rake
|
24
27
|
User.current = User.anonymous_admin
|
25
|
-
ForemanOpenscap::BulkUpload.new
|
28
|
+
print_upload_result ForemanOpenscap::BulkUpload.new.upload_from_scap_guide
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
@@ -67,6 +70,15 @@ namespace :foreman_openscap do
|
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
73
|
+
def deprecate_upload_from_rake
|
74
|
+
puts 'DEPRECATION WARNING: Uploading scap contents using rake task is deprecated and will be removed in a future version. Please use API or CLI.'
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_upload_result(result)
|
78
|
+
puts result.errors.join(' ') if result.errors.present?
|
79
|
+
puts result.results.map { |sc| "Saved #{sc.original_filename} as #{sc.title}" }.join("\n") if result.results.present?
|
80
|
+
end
|
81
|
+
|
70
82
|
# Tests
|
71
83
|
namespace :test do
|
72
84
|
desc "Test ForemanOpenscap"
|
@@ -9,15 +9,9 @@ FactoryBot.define do
|
|
9
9
|
|
10
10
|
factory :compliance_message, :class => :message do
|
11
11
|
sequence(:value) { |n| "message#{n}" }
|
12
|
-
after(:build) do |msg|
|
13
|
-
msg.digest = Digest::SHA1.hexdigest(msg.value)
|
14
|
-
end
|
15
12
|
end
|
16
13
|
|
17
14
|
factory :compliance_source, :class => :source do
|
18
15
|
sequence(:value) { |n| "source#{n}" }
|
19
|
-
after(:build) do |source|
|
20
|
-
source.digest = Digest::SHA1.hexdigest(source.value)
|
21
|
-
end
|
22
16
|
end
|
23
17
|
end
|
@@ -139,7 +139,7 @@ class Api::V2::Compliance::ArfReportsControllerTest < ActionController::TestCase
|
|
139
139
|
:date => dates[1].to_i,
|
140
140
|
:openscap_proxy_name => @proxy.name),
|
141
141
|
:session => set_session_user
|
142
|
-
assert_equal Message.where(:
|
142
|
+
assert_equal Message.where(:value => ForemanOpenscap::ArfReport.unscoped.last.logs.first.message.value).count, 1
|
143
143
|
end
|
144
144
|
|
145
145
|
test "should recognize changes in messages" do
|
@@ -187,12 +187,12 @@ class Api::V2::Compliance::ArfReportsControllerTest < ActionController::TestCase
|
|
187
187
|
|
188
188
|
reports = ForemanOpenscap::ArfReport.unscoped.all
|
189
189
|
assert_equal reports.count, 2
|
190
|
-
|
191
|
-
new_msgs = Message.where(:value =>
|
190
|
+
msg_value = "Disable Firefox Configuration File ROT-13 Encoding Changed For Test"
|
191
|
+
new_msgs = Message.where(:value => msg_value)
|
192
192
|
old_msgs = Message.where(:value => "Disable Firefox Configuration File ROT-13 Encoding")
|
193
193
|
assert_equal new_msgs.count, 1
|
194
194
|
assert_equal old_msgs.count, 0
|
195
|
-
assert_equal new_msgs.first.
|
195
|
+
assert_equal new_msgs.first.value, msg_value
|
196
196
|
end
|
197
197
|
|
198
198
|
test "should find reports by policy name" do
|
@@ -3,6 +3,7 @@ require 'test_plugin_helper'
|
|
3
3
|
class BulkUploadTest < ActiveSupport::TestCase
|
4
4
|
setup do
|
5
5
|
require 'foreman_openscap/bulk_upload'
|
6
|
+
ForemanOpenscap::ScapContent.all.map(&:destroy)
|
6
7
|
end
|
7
8
|
|
8
9
|
test 'upload_from_files should create only one scap content' do
|
@@ -13,4 +14,51 @@ class BulkUploadTest < ActiveSupport::TestCase
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
17
|
+
|
18
|
+
test 'upload_from_files should not crash when scap files are not array' do
|
19
|
+
scap_files = '/tmp/foo'
|
20
|
+
res = ForemanOpenscap::BulkUpload.new.upload_from_files(scap_files)
|
21
|
+
assert_equal "Expected an array of files to upload, got: #{scap_files}.", res.errors.first
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'upload_from_files should skip directories' do
|
25
|
+
dir = "#{ForemanOpenscap::Engine.root}/test/files/scap_contents"
|
26
|
+
res = ForemanOpenscap::BulkUpload.new.upload_from_files([dir])
|
27
|
+
assert_equal "#{dir} is a directory, expecting file.", res.errors.first
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'upload_from_files should skip files that does not exist' do
|
31
|
+
file = "#{ForemanOpenscap::Engine.root}/test/files/scap_contents/foo-ds.xml"
|
32
|
+
res = ForemanOpenscap::BulkUpload.new.upload_from_files([file])
|
33
|
+
assert_equal "#{file} does not exist, skipping.", res.errors.first
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'upload_from_directory should check if directory exists' do
|
37
|
+
dir = "#{ForemanOpenscap::Engine.root}/test/files/scap_contents/foo"
|
38
|
+
res = ForemanOpenscap::BulkUpload.new.upload_from_directory(dir)
|
39
|
+
assert_equal "No such directory: #{dir}. Please check the path you have provided.", res.errors.first
|
40
|
+
end
|
41
|
+
|
42
|
+
test 'upload_from_directory should upload from directory' do
|
43
|
+
dir = "#{ForemanOpenscap::Engine.root}/test/files/scap_contents"
|
44
|
+
assert_difference('ForemanOpenscap::ScapContent.count', 1) do
|
45
|
+
ForemanOpenscap::BulkUpload.new.upload_from_directory(dir)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'should handle case when scap security guide is not installed' do
|
50
|
+
upload = ForemanOpenscap::BulkUpload.new
|
51
|
+
upload.stubs(:scap_guide_installed?).returns(false)
|
52
|
+
res = upload.upload_from_scap_guide
|
53
|
+
assert_equal "Can't find scap-security-guide RPM, are you sure it is installed on your server?", res.errors.first
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'should upload files from guide' do
|
57
|
+
upload = ForemanOpenscap::BulkUpload.new
|
58
|
+
upload.stubs(:scap_guide_installed?).returns(true)
|
59
|
+
upload.stubs(:files_from_guide).returns(["#{ForemanOpenscap::Engine.root}/test/files/scap_contents/ssg-fedora-ds.xml"])
|
60
|
+
assert_difference('ForemanOpenscap::ScapContent.count', 1) do
|
61
|
+
upload.upload_from_scap_guide
|
62
|
+
end
|
63
|
+
end
|
16
64
|
end
|
data/test/test_plugin_helper.rb
CHANGED
@@ -11,9 +11,9 @@ module ScapClientPuppetclass
|
|
11
11
|
Puppetclass.find_by(:name => puppet_config.puppetclass_name)&.destroy
|
12
12
|
|
13
13
|
puppet_class = FactoryBot.create(:puppetclass, :name => puppet_config.puppetclass_name)
|
14
|
-
server_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.server_param, :
|
15
|
-
port_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.port_param, :
|
16
|
-
policies_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.policies_param, :
|
14
|
+
server_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.server_param, :default_value => nil)
|
15
|
+
port_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.port_param, :default_value => nil)
|
16
|
+
policies_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.policies_param, :default_value => nil)
|
17
17
|
|
18
18
|
env = FactoryBot.create :environment
|
19
19
|
|
data/test/unit/policy_test.rb
CHANGED
@@ -46,6 +46,30 @@ class PolicyTest < ActiveSupport::TestCase
|
|
46
46
|
assert_equal 1, policy.hosts.count
|
47
47
|
end
|
48
48
|
|
49
|
+
test "should delete assets when unassigning hosts" do
|
50
|
+
host1 = FactoryBot.create(:compliance_host)
|
51
|
+
host2 = FactoryBot.create(:compliance_host)
|
52
|
+
asset1 = FactoryBot.create(:asset, :assetable_id => host1.id, :assetable_type => 'Host::Base')
|
53
|
+
asset2 = FactoryBot.create(:asset, :assetable_id => host2.id, :assetable_type => 'Host::Base')
|
54
|
+
policy = FactoryBot.create(:policy, :assets => [asset1, asset2], :scap_content => @scap_content, :scap_content_profile => @scap_profile)
|
55
|
+
policy.unassign_hosts([host1, host2])
|
56
|
+
|
57
|
+
assert_nil ForemanOpenscap::Asset.find_by(:id => asset1.id)
|
58
|
+
assert_nil ForemanOpenscap::Asset.find_by(:id => asset2.id)
|
59
|
+
end
|
60
|
+
|
61
|
+
test "should delete assets only for selected policy when unassigning host" do
|
62
|
+
host1 = FactoryBot.create(:compliance_host)
|
63
|
+
asset1 = FactoryBot.create(:asset, :assetable_id => host1.id, :assetable_type => 'Host::Base')
|
64
|
+
asset2 = FactoryBot.create(:asset, :assetable_id => host1.id, :assetable_type => 'Host::Base')
|
65
|
+
policy1 = FactoryBot.create(:policy, :assets => [asset1], :scap_content => @scap_content, :scap_content_profile => @scap_profile)
|
66
|
+
policy2 = FactoryBot.create(:policy, :assets => [asset2], :scap_content => @scap_content, :scap_content_profile => @scap_profile)
|
67
|
+
policy1.unassign_hosts([host1])
|
68
|
+
|
69
|
+
assert_nil ForemanOpenscap::Asset.find_by(:id => asset1.id)
|
70
|
+
assert_not_nil ForemanOpenscap::Asset.find_by(:id => asset2.id)
|
71
|
+
end
|
72
|
+
|
49
73
|
test "should remove associated hostgroup" do
|
50
74
|
hg = FactoryBot.create(:hostgroup)
|
51
75
|
asset = FactoryBot.create(:asset, :assetable_id => hg.id, :assetable_type => 'Hostgroup')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_openscap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- slukasik@redhat.com
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- app/views/api/v2/compliance/scap_content_profiles/index.json.rabl
|
131
131
|
- app/views/api/v2/compliance/scap_content_profiles/main.json.rabl
|
132
132
|
- app/views/api/v2/compliance/scap_contents/base.json.rabl
|
133
|
+
- app/views/api/v2/compliance/scap_contents/bulk_upload.json.rabl
|
133
134
|
- app/views/api/v2/compliance/scap_contents/create.json.rabl
|
134
135
|
- app/views/api/v2/compliance/scap_contents/index.json.rabl
|
135
136
|
- app/views/api/v2/compliance/scap_contents/main.json.rabl
|
@@ -245,6 +246,7 @@ files:
|
|
245
246
|
- db/migrate/20190103093409_add_deployment_option_to_policy.foreman_openscap.rb
|
246
247
|
- db/migrate/20200117135424_migrate_port_overrides_to_int.rb
|
247
248
|
- db/migrate/20200803065041_migrate_port_overrides_for_ansible.rb
|
249
|
+
- db/migrate/20201202110213_update_puppet_port_param_type.rb
|
248
250
|
- db/seeds.d/75-job_templates.rb
|
249
251
|
- db/seeds.d/openscap_feature.rb
|
250
252
|
- db/seeds.d/openscap_policy_notification.rb
|
@@ -357,10 +359,10 @@ test_files:
|
|
357
359
|
- test/factories/arf_report_factory.rb
|
358
360
|
- test/factories/asset_factory.rb
|
359
361
|
- test/factories/compliance_host_factory.rb
|
360
|
-
- test/factories/compliance_log_factory.rb
|
361
362
|
- test/factories/policy_arf_report_factory.rb
|
362
363
|
- test/factories/policy_factory.rb
|
363
364
|
- test/factories/scap_content_related.rb
|
365
|
+
- test/factories/compliance_log_factory.rb
|
364
366
|
- test/files/arf_report/arf_report.bz2
|
365
367
|
- test/files/arf_report/arf_report.html
|
366
368
|
- test/files/arf_report/arf_report.json
|
@@ -369,11 +371,11 @@ test_files:
|
|
369
371
|
- test/files/scap_contents/ssg-fedora-ds.xml
|
370
372
|
- test/files/tailoring_files/ssg-firefox-ds-tailoring-2.xml
|
371
373
|
- test/files/tailoring_files/ssg-firefox-ds-tailoring.xml
|
372
|
-
- test/functional/api/v2/compliance/arf_reports_controller_test.rb
|
373
374
|
- test/functional/api/v2/compliance/policies_controller_test.rb
|
374
375
|
- test/functional/api/v2/compliance/scap_content_profiles_controller_test.rb
|
375
376
|
- test/functional/api/v2/compliance/scap_contents_controller_test.rb
|
376
377
|
- test/functional/api/v2/compliance/tailoring_files_controller_test.rb
|
378
|
+
- test/functional/api/v2/compliance/arf_reports_controller_test.rb
|
377
379
|
- test/functional/api/v2/hosts_controller_test.rb
|
378
380
|
- test/functional/arf_reports_controller_test.rb
|
379
381
|
- test/functional/openscap_proxies_controller_test.rb
|