foreman_openscap 0.8.1 → 0.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c175cbcb36c5e9f9f33af7a8d19455af686eb8e
4
- data.tar.gz: 6ff8c1d5190727c1128c8fc49e8f17cedadd9087
3
+ metadata.gz: ab3aabb6896d03f783813b7f15ce07398832a62f
4
+ data.tar.gz: acbe97d223373e5c632dd829cc291ff60b927387
5
5
  SHA512:
6
- metadata.gz: 1d32e842e48bb9dda3c6d5ce06390d6c16bb857e506975c1643e19d3ff3282f71ea6228b5530454db98c0a31313f7d94d8971a31dd62f1a66a0330c4d4ffe6be
7
- data.tar.gz: fb7925996af5ac5dd29b72554517ad716ac5343c32f2ea844b212eb5af89ca047d43a1f589325b76a157a2ef3b52ada90fd82c621e0424a64850d72969475f4c
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, 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 Foreman::Exception(N_('Unsupported report status format'))
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.create!(:value => N_(log[:title]),
122
- :digest => digest,
123
- :severity => log[:severity],
124
- :description => newline_to_space(log[:description]),
125
- :rationale => newline_to_space(log[:rationale]),
126
- :scap_references => references_links(log[:references]))
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? || scap_content_profile.nil?
51
- return ("<h2>%s</h2>" % (_('Cannot generate HTML guide for %{scap_content}/%{profile}') %
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 ("<h2>%s</h2>" % _('No valid OpenSCAP proxy server found.')).html_safe
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
@@ -0,0 +1,3 @@
1
+ object @scap_content
2
+
3
+ extends "api/v2/compliance/scap_contents/main"
@@ -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') %>&nbsp;<%= popover("", msg) %></div>
8
+ <div class="col-md-4"><strong><%= _('Last spool error') %></strong>&nbsp;<%= 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"),
@@ -1,3 +1,3 @@
1
1
  module ForemanOpenscap
2
- VERSION = "0.8.1".freeze
2
+ VERSION = "0.8.2".freeze
3
3
  end
@@ -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
- ForemanOpenscap::Helper.stubs(:get_asset).returns(@asset)
66
- 2.times do |num|
67
- post :create,
68
- @from_json.merge(:cname => @cname,
69
- :policy_id => @policy.id,
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 => Time.new(2017, 5, 6).to_i),
82
- set_session_user
83
- assert_response :success
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
- ForemanOpenscap::Helper.stubs(:get_asset).returns(@asset)
105
- post :create,
106
- @from_json.merge(:cname => @cname,
107
- :policy_id => @policy.id,
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 = ActionDispatch::Http::UploadedFile.new(:tempfile => @scap_file,
26
- :content_type => 'text/xml')
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
@@ -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 not create policy without SCAP content profile" do
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
- refute p.save
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.1
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-07 00:00:00.000000000 Z
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
@@ -1,4 +0,0 @@
1
- Deface::Override.new(:virtual_path => "hostgroups/_form",
2
- :name => "choose_openscap_proxy",
3
- :insert_bottom => "#primary",
4
- :partial => "compliance_hosts/openscap_proxy")
@@ -1,4 +0,0 @@
1
- Deface::Override.new(:virtual_path => "hosts/_form",
2
- :name => "openscap_proxy",
3
- :insert_bottom => "#primary",
4
- :partial => "compliance_hosts/openscap_proxy")
@@ -1,3 +0,0 @@
1
- <%= select_f f, :openscap_proxy_id, SmartProxy.with_features("Openscap"), :id, :name,
2
- { :include_blank => blank_or_inherit_f(f, :openscap_proxy) },
3
- { :label => _('Openscap Proxy') } %>