foreman_openscap 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/concerns/foreman_openscap/data_stream_content.rb +13 -6
- data/app/models/concerns/foreman_openscap/openscap_proxy_extensions.rb +0 -4
- data/app/models/foreman_openscap/arf_report.rb +23 -9
- data/app/models/foreman_openscap/policy.rb +12 -6
- data/app/views/api/v2/compliance/scap_contents/update.json.rabl +3 -0
- data/app/views/arf_reports/_list.html.erb +1 -1
- data/app/views/smart_proxies/plugins/_openscap.html.erb +1 -1
- data/lib/foreman_openscap/engine.rb +12 -0
- data/lib/foreman_openscap/version.rb +1 -1
- data/test/functional/api/v2/compliance/arf_reports_controller_test.rb +24 -22
- data/test/functional/tailoring_files_controller_test.rb +2 -3
- data/test/unit/policy_test.rb +2 -3
- data/test/unit/scap_content_test.rb +15 -0
- metadata +3 -5
- data/app/overrides/hostgroups/form/select_openscap_proxy.rb +0 -4
- data/app/overrides/hosts/form/select_openscap_proxy.rb +0 -4
- data/app/views/compliance_hosts/_openscap_proxy.html.erb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab3aabb6896d03f783813b7f15ce07398832a62f
|
4
|
+
data.tar.gz: acbe97d223373e5c632dd829cc291ff60b927387
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74e750b1270d55d37c399adcdc2d01299d071ae87fd100115ee1f6aec2f30bd050f1fee08ae380ad6cf949f48209419627128405a367530c45a1bace3c25720a
|
7
|
+
data.tar.gz: 20b34c1021f6390319c5a39b3b005ad77ab283881597f7f0e286e1d669f2ba9e10eeb457b2f8f9e7c55206cec848b5f2b72f6bcbb6079d819377c7c1ceccc192
|
@@ -28,16 +28,23 @@ module ForemanOpenscap
|
|
28
28
|
self[:digest] ||= Digest::SHA256.hexdigest(scap_file.to_s)
|
29
29
|
end
|
30
30
|
|
31
|
+
def create_profiles
|
32
|
+
fetch_profiles.each do |key, title|
|
33
|
+
create_or_update_profile key, title
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_or_update_profile(profile_id, title)
|
38
|
+
profile = ScapContentProfile.find_by(:profile_id => profile_id, "#{self.class.to_s.demodulize.underscore}_id".to_sym => id)
|
39
|
+
return ScapContentProfile.create(:profile_id => profile_id, :title => title, "#{self.class.to_s.demodulize.underscore}_id".to_sym => id) unless profile
|
40
|
+
profile.update(:title => title) unless profile.title == title
|
41
|
+
profile
|
42
|
+
end
|
43
|
+
|
31
44
|
private
|
32
45
|
|
33
46
|
def redigest
|
34
47
|
self[:digest] = Digest::SHA256.hexdigest(scap_file.to_s)
|
35
48
|
end
|
36
|
-
|
37
|
-
def create_profiles
|
38
|
-
fetch_profiles.each do |key, title|
|
39
|
-
ScapContentProfile.where(:profile_id => key, :title => title, "#{self.class.to_s.demodulize.underscore}_id".to_sym => id).first_or_create
|
40
|
-
end
|
41
|
-
end
|
42
49
|
end
|
43
50
|
end
|
@@ -2,10 +2,6 @@ module ForemanOpenscap
|
|
2
2
|
module OpenscapProxyExtensions
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
included do
|
6
|
-
belongs_to :openscap_proxy, :class_name => "SmartProxy"
|
7
|
-
end
|
8
|
-
|
9
5
|
def openscap_proxy_api
|
10
6
|
return @openscap_api if @openscap_api
|
11
7
|
proxy_url = openscap_proxy.url if openscap_proxy
|
@@ -17,6 +17,8 @@ module ForemanOpenscap
|
|
17
17
|
has_one :asset, :through => :host, :class_name => 'ForemanOpenscap::Asset', :as => :assetable
|
18
18
|
after_save :assign_locations_organizations
|
19
19
|
has_one :log, :foreign_key => :report_id
|
20
|
+
belongs_to :openscap_proxy, :class_name => "SmartProxy"
|
21
|
+
|
20
22
|
|
21
23
|
delegate :asset=, :to => :host
|
22
24
|
|
@@ -64,12 +66,12 @@ module ForemanOpenscap
|
|
64
66
|
|
65
67
|
def status=(st)
|
66
68
|
s = case st
|
67
|
-
when Integer
|
69
|
+
when Integer
|
68
70
|
st
|
69
|
-
when Hash
|
71
|
+
when Hash, ActionController::Parameters
|
70
72
|
ArfReportStatusCalculator.new(:counters => st).calculate
|
71
73
|
else
|
72
|
-
raise
|
74
|
+
raise "Unsupported report status format #{st.class}"
|
73
75
|
end
|
74
76
|
write_attribute(:status, s)
|
75
77
|
end
|
@@ -118,12 +120,24 @@ module ForemanOpenscap
|
|
118
120
|
update_msg_with_changes(msg, log)
|
119
121
|
else
|
120
122
|
digest = Digest::SHA1.hexdigest(log[:title])
|
121
|
-
msg = Message.
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
123
|
+
if (msg = Message.find_by(:digest => digest))
|
124
|
+
msg.attributes = {
|
125
|
+
:value => N_(log[:title]),
|
126
|
+
:digest => digest,
|
127
|
+
:severity => log[:severity],
|
128
|
+
:description => newline_to_space(log[:description]),
|
129
|
+
:rationale => newline_to_space(log[:rationale]),
|
130
|
+
:scap_references => references_links(log[:references])
|
131
|
+
}
|
132
|
+
else
|
133
|
+
msg = Message.new(:value => N_(log[:title]),
|
134
|
+
:digest => digest,
|
135
|
+
:severity => log[:severity],
|
136
|
+
:description => newline_to_space(log[:description]),
|
137
|
+
:rationale => newline_to_space(log[:rationale]),
|
138
|
+
:scap_references => references_links(log[:references]))
|
139
|
+
end
|
140
|
+
msg.save!
|
127
141
|
end
|
128
142
|
#TODO: log level
|
129
143
|
Log.create!(:source_id => src.id,
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rack/utils'
|
1
2
|
module ForemanOpenscap
|
2
3
|
class Policy < ApplicationRecord
|
3
4
|
include Authorizable
|
@@ -29,7 +30,6 @@ module ForemanOpenscap
|
|
29
30
|
:if => Proc.new { |policy| policy.should_validate?('Schedule') }
|
30
31
|
|
31
32
|
validates :scap_content_id, presence: true, if: Proc.new { |policy| policy.should_validate?('SCAP Content') }
|
32
|
-
validates :scap_content_profile_id, presence: true, if: Proc.new { |policy| policy.should_validate?('SCAP Content') }
|
33
33
|
validate :matching_content_profile, if: Proc.new { |policy| policy.should_validate?('SCAP Content') }
|
34
34
|
|
35
35
|
validate :valid_cron_line, :valid_weekday, :valid_day_of_month, :valid_tailoring, :valid_tailoring_profile
|
@@ -47,18 +47,17 @@ module ForemanOpenscap
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def to_html
|
50
|
-
if scap_content.nil?
|
51
|
-
return (
|
52
|
-
{ :scap_content => h(self.scap_content), :profile => h(self.scap_content_profile) })).html_safe
|
50
|
+
if scap_content.nil?
|
51
|
+
return html_error_message(_('Cannot generate HTML guide, scap content is missing.'))
|
53
52
|
end
|
54
53
|
|
55
54
|
if (proxy = scap_content.proxy_url)
|
56
55
|
api = ProxyAPI::Openscap.new(:url => proxy)
|
57
56
|
else
|
58
|
-
return (
|
57
|
+
return html_error_message(_('Cannot generate HTML guide, no valid OpenSCAP proxy server found.'))
|
59
58
|
end
|
60
59
|
|
61
|
-
api.policy_html_guide(scap_content.scap_file, scap_content_profile.profile_id)
|
60
|
+
api.policy_html_guide(scap_content.scap_file, scap_content_profile.try(:profile_id))
|
62
61
|
end
|
63
62
|
|
64
63
|
def hostgroup_ids
|
@@ -210,6 +209,13 @@ module ForemanOpenscap
|
|
210
209
|
|
211
210
|
private
|
212
211
|
|
212
|
+
def html_error_message(message)
|
213
|
+
error_message = '<div class="alert alert-danger"><span class="pficon pficon-error-circle-o"></span><strong>' <<
|
214
|
+
message <<
|
215
|
+
'</strong></div>'
|
216
|
+
error_message.html_safe
|
217
|
+
end
|
218
|
+
|
213
219
|
def erase_period_attrs(attrs)
|
214
220
|
attrs.each { |attr| self.public_send("#{attr}=", nil) }
|
215
221
|
end
|
@@ -25,7 +25,7 @@
|
|
25
25
|
</td>
|
26
26
|
<td class="elipsis"><%= name_column(arf_report.host) %></td>
|
27
27
|
<td><%= display_link_if_authorized(_("%s ago") % time_ago_in_words(arf_report.reported_at), hash_for_arf_report_path(:id => arf_report.id)) %></td>
|
28
|
-
<td class="ellipsis"><%= display_link_if_authorized(arf_report.policy.name, hash_for_edit_policy_path(:id => arf_report.policy.id)) %></th>
|
28
|
+
<td class="ellipsis"><%= arf_report.policy.present? ? display_link_if_authorized(arf_report.policy.name, hash_for_edit_policy_path(:id => arf_report.policy.id)) : _('Deleted policy') %></th>
|
29
29
|
<td class="ellipsis"><%= openscap_proxy_link arf_report %></th>
|
30
30
|
<td><%= report_arf_column(arf_report.passed, "label-info") %></th>
|
31
31
|
<td><%= report_arf_column(arf_report.failed, "label-danger") %></th>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<%= show_feature_version(feature.downcase) %>
|
6
6
|
<div class="row">
|
7
7
|
<% msg = _("Proxy failed to send a report from spool to Foreman. This indicates a corrupted report format. Report has been moved to directory for storing corrupted files on proxy for later inspection.") %>
|
8
|
-
<div class="col-md-4"><%= _('Last spool error')
|
8
|
+
<div class="col-md-4"><strong><%= _('Last spool error') %></strong> <%= popover("", msg) %></div>
|
9
9
|
<div class="col-md-8" data-ajax-url="<%= openscap_spool_openscap_proxy_path(:smart_proxy_id => @smart_proxy) %>">
|
10
10
|
<%= spinner %>
|
11
11
|
</div>
|
@@ -156,6 +156,18 @@ view_openscap_proxies]
|
|
156
156
|
parameter_filter Hostgroup, :openscap_proxy_id, :openscap_proxy
|
157
157
|
parameter_filter Log, :result
|
158
158
|
|
159
|
+
smart_proxy_for Hostgroup, :openscap_proxy,
|
160
|
+
:feature => 'Openscap',
|
161
|
+
:label => N_('OpenSCAP Proxy'),
|
162
|
+
:description => N_('OpenSCAP Proxy to use for fetching SCAP content and uploading ARF reports'),
|
163
|
+
:api_description => N_('ID of OpenSCAP Proxy')
|
164
|
+
smart_proxy_for Host::Managed, :openscap_proxy,
|
165
|
+
:feature => 'Openscap',
|
166
|
+
:label => N_('OpenSCAP Proxy'),
|
167
|
+
:description => N_('OpenSCAP Proxy to use for fetching SCAP content and uploading ARF reports'),
|
168
|
+
:api_description => N_('ID of OpenSCAP Proxy')
|
169
|
+
|
170
|
+
|
159
171
|
if ForemanOpenscap.with_remote_execution?
|
160
172
|
options = {
|
161
173
|
:description => N_("Run OpenSCAP scan"),
|
@@ -3,6 +3,9 @@ require 'tmpdir'
|
|
3
3
|
|
4
4
|
class Api::V2::Compliance::ArfReportsControllerTest < ActionController::TestCase
|
5
5
|
setup do
|
6
|
+
# required for mysql where database cleaner does not cleanup things properly
|
7
|
+
# because of arf_create does explicit transaction commit
|
8
|
+
Message.delete_all
|
6
9
|
# override validation of policy (puppetclass, lookup_key overrides)
|
7
10
|
ForemanOpenscap::Policy.any_instance.stubs(:valid?).returns(true)
|
8
11
|
@host = FactoryGirl.create(:compliance_host)
|
@@ -62,26 +65,28 @@ class Api::V2::Compliance::ArfReportsControllerTest < ActionController::TestCase
|
|
62
65
|
|
63
66
|
test "should not duplicate messages" do
|
64
67
|
dates = [Time.new(1984, 9, 15), Time.new(1932, 3, 27)]
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
:date => dates[num].to_i),
|
71
|
-
set_session_user
|
72
|
-
end
|
73
|
-
assert_equal Message.where(:digest => ForemanOpenscap::ArfReport.unscoped.last.logs.first.message.digest).count, 1
|
74
|
-
end
|
68
|
+
params = @from_json.with_indifferent_access.merge(:cname => @cname,
|
69
|
+
:policy_id => @policy.id,
|
70
|
+
:date => dates[0].to_i)
|
71
|
+
assert ForemanOpenscap::ArfReport.create_arf(@asset, params)
|
72
|
+
|
75
73
|
|
76
|
-
test "should recognize changes in messages" do
|
77
74
|
ForemanOpenscap::Helper.stubs(:get_asset).returns(@asset)
|
78
75
|
post :create,
|
79
76
|
@from_json.merge(:cname => @cname,
|
80
77
|
:policy_id => @policy.id,
|
81
|
-
:date =>
|
82
|
-
|
83
|
-
|
78
|
+
:date => dates[1].to_i),
|
79
|
+
set_session_user
|
80
|
+
assert_equal Message.where(:digest => ForemanOpenscap::ArfReport.unscoped.last.logs.first.message.digest).count, 1
|
81
|
+
end
|
84
82
|
|
83
|
+
test "should recognize changes in messages" do
|
84
|
+
params = @from_json.with_indifferent_access.merge(:cname => @cname,
|
85
|
+
:policy_id => @policy.id,
|
86
|
+
:date => Time.new(2017, 5, 6).to_i)
|
87
|
+
assert ForemanOpenscap::ArfReport.create_arf(@asset, params)
|
88
|
+
|
89
|
+
ForemanOpenscap::Helper.stubs(:get_asset).returns(@asset)
|
85
90
|
changed_from_json = arf_from_json "#{ForemanOpenscap::Engine.root}/test/files/arf_report/arf_report_msg_desc_changed.json"
|
86
91
|
post :create,
|
87
92
|
changed_from_json.merge(:cname => @cname,
|
@@ -101,15 +106,12 @@ class Api::V2::Compliance::ArfReportsControllerTest < ActionController::TestCase
|
|
101
106
|
|
102
107
|
test "should recognize change in message title/value" do
|
103
108
|
reports_cleanup
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
:date => Time.new(2017, 7, 6).to_i),
|
109
|
-
set_session_user
|
110
|
-
|
111
|
-
assert_response :success
|
109
|
+
params = @from_json.with_indifferent_access.merge(:cname => @cname,
|
110
|
+
:policy_id => @policy.id,
|
111
|
+
:date => Time.new(2017, 7, 6).to_i)
|
112
|
+
assert ForemanOpenscap::ArfReport.create_arf(@asset, params)
|
112
113
|
|
114
|
+
ForemanOpenscap::Helper.stubs(:get_asset).returns(@asset)
|
113
115
|
changed_from_json = arf_from_json "#{ForemanOpenscap::Engine.root}/test/files/arf_report/arf_report_msg_value_changed.json"
|
114
116
|
post :create,
|
115
117
|
changed_from_json.merge(:cname => @cname,
|
@@ -22,9 +22,8 @@ class TailoringFilesControllerTest < ActionController::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
test 'create' do
|
25
|
-
uploaded_file =
|
26
|
-
|
27
|
-
uploaded_file.original_filename = 'uploaded-tailoring-file.xml'
|
25
|
+
uploaded_file = Rack::Test::UploadedFile.new(@scap_file, 'text/xml')
|
26
|
+
# uploaded_file.original_filename = 'uploaded-tailoring-file.xml'
|
28
27
|
post :create, { :tailoring_file => { :name => 'some_file', :scap_file => uploaded_file } }, set_session_user
|
29
28
|
assert_redirected_to tailoring_files_url
|
30
29
|
end
|
data/test/unit/policy_test.rb
CHANGED
@@ -135,13 +135,12 @@ class PolicyTest < ActiveSupport::TestCase
|
|
135
135
|
assert p.errors[:scap_content_id].include?("can't be blank")
|
136
136
|
end
|
137
137
|
|
138
|
-
test "should
|
138
|
+
test "should create a policy with default SCAP content profile (profile id is nil)" do
|
139
139
|
p = ForemanOpenscap::Policy.new(:name => "custom_policy",
|
140
140
|
:scap_content_id => @scap_content.id,
|
141
141
|
:period => 'monthly',
|
142
142
|
:day_of_month => '5')
|
143
|
-
|
144
|
-
assert p.errors[:scap_content_profile_id].include?("can't be blank")
|
143
|
+
assert p.save
|
145
144
|
end
|
146
145
|
|
147
146
|
test "should have correct scap profile in enc" do
|
@@ -32,4 +32,19 @@ class ScapContentTest < ActiveSupport::TestCase
|
|
32
32
|
assert_equal(available_proxy.url, scap_content.proxy_url)
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
test 'should update profile title when fetching profiles from proxy' do
|
37
|
+
scap_content = FactoryGirl.create(:scap_content)
|
38
|
+
scap_content.stubs(:fetch_profiles).returns({ "xccdf.test.profile" => "Changed title" })
|
39
|
+
scap_profile = FactoryGirl.create(:scap_content_profile, :scap_content => scap_content, :profile_id => 'xccdf.test.profile', :title => "Original title")
|
40
|
+
scap_content.create_profiles
|
41
|
+
assert_equal scap_profile.reload.title, 'Changed title'
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'should create profile when fetching profiles from proxy' do
|
45
|
+
scap_content = FactoryGirl.create(:scap_content)
|
46
|
+
scap_content.stubs(:fetch_profiles).returns({ "xccdf.test.profile" => "My title" })
|
47
|
+
scap_content.create_profiles
|
48
|
+
assert scap_content.reload.scap_content_profiles.where(:title => 'My title').first
|
49
|
+
end
|
35
50
|
end
|
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: 0.8.
|
4
|
+
version: 0.8.2
|
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: 2017-09-
|
11
|
+
date: 2017-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -91,8 +91,6 @@ files:
|
|
91
91
|
- app/models/foreman_openscap/scap_content.rb
|
92
92
|
- app/models/foreman_openscap/scap_content_profile.rb
|
93
93
|
- app/models/foreman_openscap/tailoring_file.rb
|
94
|
-
- app/overrides/hostgroups/form/select_openscap_proxy.rb
|
95
|
-
- app/overrides/hosts/form/select_openscap_proxy.rb
|
96
94
|
- app/overrides/hosts/overview/host_compliance_status.rb
|
97
95
|
- app/services/foreman_openscap/arf_report_status_calculator.rb
|
98
96
|
- app/services/foreman_openscap/host_report_dashboard/data.rb
|
@@ -117,6 +115,7 @@ files:
|
|
117
115
|
- app/views/api/v2/compliance/scap_contents/index.json.rabl
|
118
116
|
- app/views/api/v2/compliance/scap_contents/main.json.rabl
|
119
117
|
- app/views/api/v2/compliance/scap_contents/show.json.rabl
|
118
|
+
- app/views/api/v2/compliance/scap_contents/update.json.rabl
|
120
119
|
- app/views/api/v2/compliance/tailoring_files/base.json.rabl
|
121
120
|
- app/views/api/v2/compliance/tailoring_files/index.json.rabl
|
122
121
|
- app/views/api/v2/compliance/tailoring_files/main.json.rabl
|
@@ -130,7 +129,6 @@ files:
|
|
130
129
|
- app/views/arf_reports/show.html.erb
|
131
130
|
- app/views/arf_reports/show_html.html.erb
|
132
131
|
- app/views/compliance_hosts/_compliance_status.erb
|
133
|
-
- app/views/compliance_hosts/_openscap_proxy.html.erb
|
134
132
|
- app/views/compliance_hosts/show.html.erb
|
135
133
|
- app/views/dashboard/_compliance_host_reports_widget.html.erb
|
136
134
|
- app/views/dashboard/_compliance_reports_breakdown_widget.html.erb
|