foreman_openscap 4.0.1 → 4.1.1

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
  SHA256:
3
- metadata.gz: afb07ec68598ddfebdea1a16d50489cb5ca88cd7e5e0eb0294591704ac41d06d
4
- data.tar.gz: 2c9aeed9bd9244263002370796e1439801dbe29183f4f19c99bc33d5aa5168b3
3
+ metadata.gz: 416db64a783e7876de13cd98e57b7daea2c0ac9f228f52f85fcb54d4db18e75f
4
+ data.tar.gz: c5b5c5f22113c4842a83d3255880af2632e12ccd26f1cc8779a36f4ae1910745
5
5
  SHA512:
6
- metadata.gz: 93afb936e476d4b8ddc3c616ec5820b7609cf8fefc59478ac7011b78edef1e33946d194ba4a47dde89acf19dcbc6d6fd74f6e5ba501502ae9a1ef7663e1b77ed
7
- data.tar.gz: c5aeec2a9ceee0c88d40e279dda82316e4a13eeb5e4b31856fa2625b20e994cf10e13b338286b5550e6d9ba107c78de0049d6587610404c31d2c3d5ecbc7b85f
6
+ metadata.gz: e92cbdf9359cc67bb7e7ed1e40da8b78789fbc9daecb7c8559853d1fce03eaa5d2953f8d810ee5176f7f4288f57115c213099ce798229837c1568a09b3a2e1be
7
+ data.tar.gz: 91263d9e014cadff61bca46fe792cd2584e3c4de5ba828cd5f7e7b46e0e5d4c890e5fdd4894d19566bee31b5cb479ed21dd0b65be2bd499d15251c4d90b58920
@@ -5,7 +5,11 @@ module Api::V2
5
5
  include ForemanOpenscap::BodyLogExtensions
6
6
  include ForemanOpenscap::Api::V2::ScapApiControllerExtensions
7
7
 
8
- before_action :find_resource, :except => %w[index create]
8
+ def self.bulk_upload_types
9
+ ['files', 'directory', 'default']
10
+ end
11
+
12
+ before_action :find_resource, :except => %w[index create bulk_upload]
9
13
 
10
14
  api :GET, '/compliance/scap_contents', N_('List SCAP contents')
11
15
  param_group :search_and_pagination, ::Api::V2::BaseController
@@ -61,6 +65,29 @@ module Api::V2
61
65
  process_response @scap_content.destroy
62
66
  end
63
67
 
68
+ api :POST, '/compliance/scap_contents/bulk_upload', N_('Upload scap contents in bulk')
69
+ param :type, bulk_upload_types, :required => true, :desc => N_('Type of the upload')
70
+ param :files, Array, :desc => N_('File paths to upload when using "files" upload type')
71
+ param :directory, String, :desc => N_('Directory to upload when using "directory" upload type')
72
+
73
+ def bulk_upload
74
+ case params[:type]
75
+ when 'files'
76
+ @result = ForemanOpenscap::BulkUpload.new.upload_from_files(params[:files])
77
+ when 'directory'
78
+ @result = ForemanOpenscap::BulkUpload.new.upload_from_directory(params[:directory])
79
+ when 'default'
80
+ @result = ForemanOpenscap::BulkUpload.new.upload_from_scap_guide
81
+ else
82
+ return render :json => {
83
+ :errors => [
84
+ _("Please specify import type, received: %{received}, expected one of: %{expected}") %
85
+ { :expected => self.class.bulk_upload_types.join(', '), :received => params[:type] }
86
+ ]
87
+ }, :status => :unprocessable_entity
88
+ end
89
+ end
90
+
64
91
  private
65
92
 
66
93
  def find_resource
@@ -70,6 +97,8 @@ module Api::V2
70
97
 
71
98
  def action_permission
72
99
  case params[:action]
100
+ when 'bulk_upload'
101
+ :create
73
102
  when 'xml'
74
103
  :view
75
104
  else
@@ -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
@@ -22,18 +22,10 @@ module ForemanOpenscap
22
22
  end
23
23
 
24
24
  def inherited_openscap_proxy_id
25
- inherited_ancestry_attribute(:openscap_proxy_id)
26
- end
27
-
28
- unless defined?(Katello::System)
29
- private
30
-
31
- def inherited_ancestry_attribute(attribute)
32
- if ancestry.present?
33
- self[attribute] || self.class.sort_by_ancestry(ancestors.where("#{attribute} is not NULL")).last.try(attribute)
34
- else
35
- self.send(attribute)
36
- end
25
+ if ancestry.present?
26
+ self[:openscap_proxy_id] || self.class.sort_by_ancestry(ancestors.where.not(openscap_proxy_id: nil)).last.try(:openscap_proxy_id)
27
+ else
28
+ self.send(:openscap_proxy_id)
37
29
  end
38
30
  end
39
31
  end
@@ -33,10 +33,6 @@ module ForemanOpenscap
33
33
  end
34
34
  end
35
35
 
36
- def inherited_openscap_proxy_id
37
- inherited_ancestry_attribute(:openscap_proxy_id)
38
- end
39
-
40
36
  private
41
37
 
42
38
  def scap_client_lookup_values_for(lookup_keys, model_match)
@@ -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
- digest = Digest::SHA1.hexdigest(log[:title])
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]),
@@ -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
@@ -8,6 +8,10 @@ module ForemanOpenscap
8
8
  N_('Compliance')
9
9
  end
10
10
 
11
+ def status_link
12
+ host.arf_reports_path(:search => "host = #{host.name}")
13
+ end
14
+
11
15
  def self.bit_mask(status)
12
16
  "#{ArfReport::BIT_NUM * ArfReport::METRIC.index(status)} & #{ArfReport::MAX}"
13
17
  end
@@ -174,8 +174,14 @@ module ForemanOpenscap
174
174
  end
175
175
 
176
176
  def unassign_hosts(hosts)
177
- host_asset_ids = ForemanOpenscap::Asset.where(:assetable_type => 'Host::Base', :assetable_id => hosts.map(&:id)).pluck(:id)
178
- self.asset_ids = self.asset_ids - host_asset_ids
177
+ policy_host_assets = ForemanOpenscap::Asset.joins(:asset_policies).where(
178
+ :assetable_type => 'Host::Base',
179
+ :assetable_id => hosts.map(&:id),
180
+ :foreman_openscap_asset_policies => { :policy_id => id }
181
+ ).pluck(:id)
182
+
183
+ self.asset_ids = self.asset_ids - policy_host_assets
184
+ ForemanOpenscap::Asset.where(:id => policy_host_assets).destroy_all
179
185
  end
180
186
 
181
187
  def to_enc
@@ -312,7 +318,7 @@ module ForemanOpenscap
312
318
  end
313
319
 
314
320
  def assign_ids(ids, class_name)
315
- new_assets = ids.reject { |id| id.respond_to?(:empty?) && id.empty? }.reduce([]) do |memo, id|
321
+ new_assets = ids.uniq.reject { |id| id.respond_to?(:empty?) && id.empty? }.reduce([]) do |memo, id|
316
322
  memo << assets.where(:assetable_type => class_name, :assetable_id => id).first_or_initialize
317
323
  end
318
324
  complimentary_class_name = class_name == 'Host::Base' ? 'Hostgroup' : 'Host::Base'
@@ -0,0 +1,7 @@
1
+ object @result
2
+
3
+ attributes :errors
4
+
5
+ child :results => :results do
6
+ extends 'api/v2/compliance/scap_contents/index'
7
+ end
@@ -64,6 +64,9 @@ Rails.application.routes.draw do
64
64
  member do
65
65
  get 'xml'
66
66
  end
67
+ collection do
68
+ post 'bulk_upload'
69
+ end
67
70
  end
68
71
  resources :scap_content_profiles, :only => %i[index]
69
72
 
@@ -0,0 +1,34 @@
1
+ class MigratePortOverridesForAnsible < ActiveRecord::Migration[6.0]
2
+ def up
3
+ transform_lookup_values :to_i
4
+ end
5
+
6
+ def down
7
+ transform_lookup_values :to_s
8
+ end
9
+
10
+ private
11
+
12
+ def transform_lookup_values(method)
13
+ return unless defined?(ForemanAnsible)
14
+ role = AnsibleRole.find_by :name => 'theforeman.foreman_scap_client'
15
+ return unless role
16
+ port_key = role.ansible_variables.find_by :key => 'foreman_scap_client_port'
17
+ return unless port_key
18
+ if method == :to_i
19
+ port_key.key_type = "integer"
20
+ port_key.default_value = 8080
21
+ else
22
+ port_key.key_type == "string"
23
+ port_key.default_value = ""
24
+ end
25
+
26
+ port_key.save
27
+ port_key.lookup_values.in_batches do |batch|
28
+ batch.each do |lookup_value|
29
+ lookup_value.value = lookup_value.value.send(method)
30
+ lookup_value.save
31
+ end
32
+ end
33
+ end
34
+ end
@@ -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
@@ -7,9 +7,9 @@ if ForemanOpenscap.with_remote_execution?
7
7
  sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
8
8
  # import! was renamed to import_raw! around 1.3.1
9
9
  if JobTemplate.respond_to?('import_raw!')
10
- template = JobTemplate.import_raw!(File.read(template), :default => true, :locked => true, :update => sync)
10
+ template = JobTemplate.import_raw!(File.read(template), :default => true, :lock => true, :update => sync)
11
11
  else
12
- template = JobTemplate.import!(File.read(template), :default => true, :locked => true, :update => sync)
12
+ template = JobTemplate.import!(File.read(template), :default => true, :lock => true, :update => sync)
13
13
  end
14
14
  template.organizations = organizations if SETTINGS[:organizations_enabled] && template.present?
15
15
  template.locations = locations if SETTINGS[:locations_enabled] && template.present?
@@ -1,48 +1,74 @@
1
1
  require 'digest/sha2'
2
+ require 'ostruct'
3
+
2
4
  module ForemanOpenscap
3
5
  class BulkUpload
4
- attr_accessor :from_scap_security_guide
5
- def initialize(from_scap_security_guide = false)
6
- @from_scap_security_guide = from_scap_security_guide
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 generate_scap_default_content
10
- return unless @from_scap_security_guide
14
+ def scap_guide_installed?
15
+ `rpm -qa | grep scap-security-guide`.present?
16
+ end
11
17
 
12
- if `rpm -qa | grep scap-security-guide`.empty?
13
- Rails.logger.debug "Can't find scap-security-guide RPM"
14
- return
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
- files_array = `rpm -ql scap-security-guide | grep ds.xml`.split
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.map(&:id) if SETTINGS[:locations_enabled]
32
- scap_content.organization_ids = Organization.all.map(&:id) if SETTINGS[:organizations_enabled]
52
+ scap_content.location_ids = Location.all.map(&:id)
53
+ scap_content.organization_ids = Organization.all.map(&: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
- puts "Saved #{datastream} as #{scap_content.title}"
56
+ @result.results.push(scap_content)
37
57
  else
38
- puts "Failed saving #{datastream}"
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) unless files_array.empty?
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
- @from_scap_security_guide ? "Red Hat #{os_name} default content" : "#{os_name} content"
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' => [:create] },
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
@@ -1,3 +1,3 @@
1
1
  module ForemanOpenscap
2
- VERSION = "4.0.1".freeze
2
+ VERSION = "4.1.1".freeze
3
3
  end
@@ -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(true).generate_scap_default_content
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(:digest => ForemanOpenscap::ArfReport.unscoped.last.logs.first.message.digest).count, 1
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 => "Disable Firefox Configuration File ROT-13 Encoding Changed For Test")
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.digest, Digest::SHA1.hexdigest("Disable Firefox Configuration File ROT-13 Encoding Changed For Test")
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
@@ -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, :puppetclass_id => puppet_class.id)
15
- port_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.port_param, :puppetclass_id => puppet_class.id)
16
- policies_param = FactoryBot.create(:puppetclass_lookup_key, :key => puppet_config.policies_param, :puppetclass_id => puppet_class.id)
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
 
@@ -37,6 +37,39 @@ class PolicyTest < ActiveSupport::TestCase
37
37
  assert_equal hostgroup, policy.hostgroups.first
38
38
  end
39
39
 
40
+ test "should not raise when assiging same host by id" do
41
+ host1 = FactoryBot.create(:compliance_host)
42
+ asset = FactoryBot.create(:asset, :assetable_id => host1.id, :assetable_type => 'Host::Base')
43
+ policy = FactoryBot.create(:policy, :assets => [asset], :scap_content => @scap_content, :scap_content_profile => @scap_profile)
44
+ policy.host_ids = [host1, host1].map(&:id)
45
+ policy.save!
46
+ assert_equal 1, policy.hosts.count
47
+ end
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
+
40
73
  test "should remove associated hostgroup" do
41
74
  hg = FactoryBot.create(:hostgroup)
42
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.1
4
+ version: 4.1.1
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: 2020-07-13 00:00:00.000000000 Z
11
+ date: 2020-12-03 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
@@ -244,6 +245,8 @@ files:
244
245
  - db/migrate/20171016125613_add_content_title_unique_constraint.foreman_openscap.rb
245
246
  - db/migrate/20190103093409_add_deployment_option_to_policy.foreman_openscap.rb
246
247
  - db/migrate/20200117135424_migrate_port_overrides_to_int.rb
248
+ - db/migrate/20200803065041_migrate_port_overrides_for_ansible.rb
249
+ - db/migrate/20201202110213_update_puppet_port_param_type.rb
247
250
  - db/seeds.d/75-job_templates.rb
248
251
  - db/seeds.d/openscap_feature.rb
249
252
  - db/seeds.d/openscap_policy_notification.rb
@@ -356,10 +359,10 @@ test_files:
356
359
  - test/factories/arf_report_factory.rb
357
360
  - test/factories/asset_factory.rb
358
361
  - test/factories/compliance_host_factory.rb
359
- - test/factories/compliance_log_factory.rb
360
362
  - test/factories/policy_arf_report_factory.rb
361
363
  - test/factories/policy_factory.rb
362
364
  - test/factories/scap_content_related.rb
365
+ - test/factories/compliance_log_factory.rb
363
366
  - test/files/arf_report/arf_report.bz2
364
367
  - test/files/arf_report/arf_report.html
365
368
  - test/files/arf_report/arf_report.json
@@ -368,11 +371,11 @@ test_files:
368
371
  - test/files/scap_contents/ssg-fedora-ds.xml
369
372
  - test/files/tailoring_files/ssg-firefox-ds-tailoring-2.xml
370
373
  - test/files/tailoring_files/ssg-firefox-ds-tailoring.xml
371
- - test/functional/api/v2/compliance/arf_reports_controller_test.rb
372
374
  - test/functional/api/v2/compliance/policies_controller_test.rb
373
375
  - test/functional/api/v2/compliance/scap_content_profiles_controller_test.rb
374
376
  - test/functional/api/v2/compliance/scap_contents_controller_test.rb
375
377
  - test/functional/api/v2/compliance/tailoring_files_controller_test.rb
378
+ - test/functional/api/v2/compliance/arf_reports_controller_test.rb
376
379
  - test/functional/api/v2/hosts_controller_test.rb
377
380
  - test/functional/arf_reports_controller_test.rb
378
381
  - test/functional/openscap_proxies_controller_test.rb