smart_proxy_openscap 0.6.1 → 0.6.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.
Files changed (19) hide show
  1. checksums.yaml +4 -4
  2. data/lib/smart_proxy_openscap/fetch_tailoring_file.rb +1 -1
  3. data/lib/smart_proxy_openscap/foreman_forwarder.rb +3 -0
  4. data/lib/smart_proxy_openscap/openscap_api.rb +3 -0
  5. data/lib/smart_proxy_openscap/openscap_exception.rb +1 -0
  6. data/lib/smart_proxy_openscap/spool_forwarder.rb +16 -16
  7. data/lib/smart_proxy_openscap/storage_fs.rb +18 -0
  8. data/lib/smart_proxy_openscap/version.rb +1 -1
  9. data/settings.d/openscap.yml.example +4 -0
  10. data/test/data/corrupted_arf_report +0 -0
  11. data/test/data/spool/cleanup_spool/arf/2c101b95-033f-4b15-b490-f50bf9090dae/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1 +0 -0
  12. data/test/data/spool/cleanup_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484309984/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1 +0 -0
  13. data/test/data/spool/corrupted_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484309984/a4dfba5db27b21795e6fa401b8dce7a70faeb25b7963891f07f6f4baaf052afb +0 -0
  14. data/test/data/spool/corrupted_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1 +0 -0
  15. data/test/data/spool/valid_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484309984/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1 +0 -0
  16. data/test/data/spool/valid_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1 +0 -0
  17. data/test/post_report_api_test.rb +11 -0
  18. data/test/spool_forwarder_test.rb +82 -0
  19. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: feab59ae3e8ce1e915f22d558c1160c55373fa16
4
- data.tar.gz: e7de38b8eae9570f604850f129beb66a69e27060
3
+ metadata.gz: 17c8ac2a2ead069f4efa7282704a31bfc92b248a
4
+ data.tar.gz: bfe816a4639d132847e7ba97848aeed06829c80b
5
5
  SHA512:
6
- metadata.gz: 37138364fff28b9677e4c2f401aad31c0c2fce71c18b5ca26cb25c0e6f8081ad0cf98caf8b092061b4241e9a9c2ce98a2ee800e025b4645c798e5ecb0c9ff7f7
7
- data.tar.gz: aac42840356d8a85c7f74e08fe050584c45af8c5e857ab30d0b14004e71eb0e26afa88dfdb3fe207edad60669701ab2c9f55ffb997f32ac8869f93ef3f667f41
6
+ metadata.gz: db6215253f5ddd5f6e862b5fa01a23a06f2eaeacb16d0a82bd037b493bc5c4cdcdabd21034f425aede1013ca7189c7b98b83ef81e06c6fa5684d75402d8008e8
7
+ data.tar.gz: cf76b07956f6d50a101ea9ec26432c2dd7a0206763db8732149e9d97bb97ae6114eb8b481354ecff08941e0253e90006673014913b2d9f0014cda393a27d7546
@@ -10,7 +10,7 @@ module Proxy::OpenSCAP
10
10
  create_store_dir store_dir
11
11
 
12
12
  scap_file = policy_content_file(policy_tailoring_file)
13
- clean_store_folder(policy_store_dir) unless scap_file
13
+ clean_store_folder(store_dir) unless scap_file
14
14
  scap_file ||= save_or_serve_scap_file(policy_tailoring_file, file_download_path)
15
15
  end
16
16
  end
@@ -11,6 +11,9 @@ module Proxy::OpenSCAP
11
11
  response.value
12
12
  res = JSON.parse(response.body)
13
13
  raise StandardError, "Received response: #{response.code} #{response.msg}" unless res['result'] == 'OK'
14
+ rescue OpenSCAP::OpenSCAPError => e
15
+ logger.debug e.backtrace.join("\n\t")
16
+ raise e
14
17
  rescue StandardError => e
15
18
  logger.debug response.body if response
16
19
  logger.debug e.backtrace.join("\n\t")
@@ -42,6 +42,9 @@ module Proxy::OpenSCAP
42
42
  Proxy::OpenSCAP::StorageFS.new(Proxy::OpenSCAP::Plugin.settings.failed_dir, cn, post_to_foreman['id'], date).store_failed(request.body.string)
43
43
  logger.error "Failed to save Report in reports directory (#{Proxy::OpenSCAP::Plugin.settings.reportsdir}). Failed with: #{e.message}.
44
44
  Saving file in #{Proxy::OpenSCAP::Plugin.settings.failed_dir}. Please copy manually to #{Proxy::OpenSCAP::Plugin.settings.reportsdir}"
45
+ rescue OpenSCAP::OpenSCAPError => e
46
+ logger.error "Failed to parse Arf Report, moving to #{Proxy::OpenSCAP::Plugin.settings.corrupted_dir}"
47
+ Proxy::OpenSCAP::StorageFS.new(Proxy::OpenSCAP::Plugin.settings.corrupted_dir, cn, policy, date).store_corrupted(request.body.string)
45
48
  rescue *HTTP_ERRORS => e
46
49
  ### If the upload to foreman fails then store it in the spooldir
47
50
  logger.error "Failed to upload to Foreman, saving in spool. Failed with: #{e.message}"
@@ -4,4 +4,5 @@ module Proxy::OpenSCAP
4
4
  class StoreSpoolError < StandardError; end
5
5
  class StoreFailedError < StandardError; end
6
6
  class FileNotFound < StandardError; end
7
+ class StoreCorruptedError < StandardError; end
7
8
  end
@@ -3,19 +3,11 @@ module Proxy::OpenSCAP
3
3
  include ::Proxy::Log
4
4
 
5
5
  def post_arf_from_spool(arf_dir)
6
- failed = nil
7
6
  Dir.foreach(arf_dir) do |cname|
8
- begin
9
- next if cname == '.' || cname == '..'
10
- cname_dir = File.join(arf_dir, cname)
11
- forward_cname_dir(cname, cname_dir) if File.directory?(cname_dir)
12
- rescue StandardError => e
13
- logger.debug e.backtrace.join("\n\t")
14
- logger.error "Failed to send SCAP results for #{cname} to the Foreman server: #{e}"
15
- failed = true
16
- end
7
+ next if cname == '.' || cname == '..'
8
+ cname_dir = File.join(arf_dir, cname)
9
+ forward_cname_dir(cname, cname_dir) if File.directory?(cname_dir)
17
10
  end
18
- raise "Failed to send SCAP results for one or more hosts." if failed
19
11
  end
20
12
 
21
13
  private
@@ -28,7 +20,7 @@ module Proxy::OpenSCAP
28
20
  forward_policy_dir(cname, policy_id, policy_dir)
29
21
  end
30
22
  end
31
- remove(cname_dir)
23
+ remove_if_empty(cname_dir)
32
24
  end
33
25
 
34
26
  def forward_policy_dir(cname, policy_id, policy_dir)
@@ -39,7 +31,7 @@ module Proxy::OpenSCAP
39
31
  forward_date_dir(cname, policy_id, date, date_dir)
40
32
  end
41
33
  end
42
- remove(policy_dir)
34
+ remove_if_empty(policy_dir)
43
35
  end
44
36
 
45
37
  def forward_date_dir(cname, policy_id, date, date_dir)
@@ -51,7 +43,7 @@ module Proxy::OpenSCAP
51
43
  forward_arf_file(cname, policy_id, date, arf_path)
52
44
  end
53
45
  end
54
- remove(date_dir)
46
+ remove_if_empty(date_dir)
55
47
  end
56
48
 
57
49
  def forward_arf_file(cname, policy_id, date, arf_file_path)
@@ -59,11 +51,19 @@ module Proxy::OpenSCAP
59
51
  post_to_foreman = ForemanForwarder.new.post_arf_report(cname, policy_id, date, data)
60
52
  Proxy::OpenSCAP::StorageFS.new(Proxy::OpenSCAP::Plugin.settings.reportsdir, cname, post_to_foreman['id'], date).store_archive(data)
61
53
  File.delete arf_file_path
54
+ rescue OpenSCAP::OpenSCAPError => e
55
+ logger.error "Failed to parse Arf Report at #{arf_file_path}, moving to #{Proxy::OpenSCAP::Plugin.settings.corrupted_dir}"
56
+
57
+ Proxy::OpenSCAP::StorageFS.new(Proxy::OpenSCAP::Plugin.settings.corrupted_dir, cname, policy_id, date)
58
+ .move_corrupted(arf_file_path.split('/').last)
59
+ rescue StandardError => e
60
+ logger.error "smart-proxy-openscap-send failed to upload Compliance report for #{cname}, generated on #{Time.at date.to_i}. Cause: #{e}"
62
61
  end
63
62
 
64
- def remove(dir)
63
+ def remove_if_empty(dir)
65
64
  begin
66
- Dir.delete dir
65
+ Dir.delete dir if Dir["#{dir}/*"].empty?
66
+ logger.debug "Removing directory: #{dir}"
67
67
  rescue StandardError => e
68
68
  logger.error "Could not remove directory: #{e.message}"
69
69
  end
@@ -14,6 +14,15 @@ module Proxy::OpenSCAP
14
14
  store(data, StoreFailedError)
15
15
  end
16
16
 
17
+ def store_corrupted(data)
18
+ store(data, StoreCorruptedError)
19
+ end
20
+
21
+ def move_corrupted(digest)
22
+ source = "#{Proxy::OpenSCAP::Plugin.settings.spooldir}/#{@namespace}/#{@cname}/#{@id}/#{@date}"
23
+ move "#{source}/#{digest}", StoreCorruptedError
24
+ end
25
+
17
26
  def get_arf_xml(digest)
18
27
  get_arf_file(digest)[:xml]
19
28
  end
@@ -54,6 +63,15 @@ module Proxy::OpenSCAP
54
63
  @path
55
64
  end
56
65
 
66
+ def move(source, error_type)
67
+ begin
68
+ create_directory
69
+ FileUtils.mv source, @path
70
+ rescue StandardError => e
71
+ raise error_type, "Could not move file: #{e.message}"
72
+ end
73
+ end
74
+
57
75
  def store(data, error_type)
58
76
  begin
59
77
  create_directory
@@ -10,6 +10,6 @@
10
10
 
11
11
  module Proxy
12
12
  module OpenSCAP
13
- VERSION = '0.6.1'
13
+ VERSION = '0.6.2'
14
14
  end
15
15
  end
@@ -22,3 +22,7 @@
22
22
  # Directory where OpenSCAP report XML are stored
23
23
  # In case sending to Foreman succeeded, yet failed to save to reportsdir
24
24
  #:failed_dir: /usr/share/foreman-proxy/openscap/failed
25
+
26
+ # Directory where corrupted OpenSCAP report XML are stored
27
+ # When proxy cannot parse the report sent by client
28
+ #:corrupted_dir: /var/lib/foreman-proxy/openscap/corrupted
@@ -16,10 +16,13 @@ class OpenSCAPApiTest < Test::Unit::TestCase
16
16
  Proxy::OpenSCAP::Plugin.settings.stubs(:spooldir).returns(@results_path + "/spool")
17
17
  Proxy::OpenSCAP::Plugin.settings.stubs(:reportsdir).returns(@results_path + "/reports")
18
18
  Proxy::OpenSCAP::Plugin.settings.stubs(:failed_dir).returns(@results_path + "/failed")
19
+ Proxy::OpenSCAP::Plugin.settings.stubs(:corrupted_dir).returns(@results_path + "/corrupted")
19
20
  @arf_report = File.open("#{Dir.getwd}/test/data/arf_report").read
21
+ @corrupted_arf_report = File.open("#{Dir.getwd}/test/data/corrupted_arf_report").read
20
22
  @policy_id = 1
21
23
  @arf_id = 145
22
24
  @filename = Digest::SHA256.hexdigest(@arf_report)
25
+ @corrupted_filename = Digest::SHA256.hexdigest(@corrupted_arf_report)
23
26
  @cname = 'node.example.org'
24
27
  @date = Time.now.to_i
25
28
  # Bypass common_name as it requires ssl certificate
@@ -72,4 +75,12 @@ class OpenSCAPApiTest < Test::Unit::TestCase
72
75
  log_file = File.read('logs/test.log')
73
76
  assert(log_file.include?('Failed to save Report in reports directory'), 'Logger should notify that failed to save in reports dir')
74
77
  end
78
+
79
+ def test_post_corrupted_should_move_to_corrupted
80
+ stub_request(:post, "#{@foreman_url}/api/v2/compliance/arf_reports/#{@cname}/#{@policy_id}/#{@date}")
81
+ .to_return(:status => 200, :body => "{\"result\":\"OK\",\"id\":\"#{@arf_id}\"}")
82
+ post "/arf/#{@policy_id}", @corrupted_arf_report, 'CONTENT_TYPE' => 'text/xml', 'CONTENT_ENCODING' => 'x-bzip2'
83
+ assert(File.file?("#{@results_path}/corrupted/arf/#{@cname}/#{@policy_id}/#{@date}/#{@corrupted_filename}"), "File should be in Corrupted directory")
84
+ refute(File.file?("#{@results_path}/spool/arf/#{@cname}/#{@policy_id}/#{@date}/#{@corrupted_filename}"), "File should not be in Spool directory")
85
+ end
75
86
  end
@@ -0,0 +1,82 @@
1
+ require 'test_helper'
2
+ require 'smart_proxy_openscap'
3
+ require 'smart_proxy_openscap/openscap_lib'
4
+
5
+ class SpoolForwarderTest < Test::Unit::TestCase
6
+ def setup
7
+ @foreman_url = 'https://foreman.example.com'
8
+ Proxy::SETTINGS.stubs(:foreman_url).returns(@foreman_url)
9
+ @base_spool_for_test = ("#{Dir.getwd}/test/data/spool")
10
+ @results_path = ("#{Dir.getwd}/test/test_run_files")
11
+ FileUtils.mkdir_p(@results_path)
12
+ Proxy::OpenSCAP::Plugin.settings.stubs(:contentdir).returns(@results_path)
13
+ @spooldir = @results_path + "/spool"
14
+ Proxy::OpenSCAP::Plugin.settings.stubs(:spooldir).returns(@spooldir)
15
+ Proxy::OpenSCAP::Plugin.settings.stubs(:reportsdir).returns(@results_path + "/reports")
16
+ Proxy::OpenSCAP::Plugin.settings.stubs(:corrupted_dir).returns(@results_path + "/corrupted")
17
+ @policy_id = 1
18
+ @date_1 = 1484309984
19
+ @date_2 = 1484313035
20
+ @id_1 = 42
21
+ @id_2 = 84
22
+ @valid_digest = "fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1"
23
+ @corrupted_digest = "a4dfba5db27b21795e6fa401b8dce7a70faeb25b7963891f07f6f4baaf052afb"
24
+ @cname = "e20b9695-f655-401a-9dda-8cca7a47a8c0"
25
+ @cname_2 = "2c101b95-033f-4b15-b490-f50bf9090dae"
26
+
27
+ @arf_dir = File.join(Proxy::OpenSCAP::Plugin.settings.spooldir, "/arf")
28
+
29
+ stub_request(:post, "#{@foreman_url}/api/v2/compliance/arf_reports/#{@cname}/#{@policy_id}/#{@date_1}")
30
+ .to_return(:status => 200, :body => "{\"result\":\"OK\",\"id\":\"#{@id_1}\"}")
31
+
32
+ stub_request(:post, "#{@foreman_url}/api/v2/compliance/arf_reports/#{@cname}/#{@policy_id}/#{@date_2}")
33
+ .to_return(:status => 200, :body => "{\"result\":\"OK\",\"id\":\"#{@id_2}\"}")
34
+
35
+ end
36
+
37
+ def teardown
38
+ FileUtils.rm_rf @results_path
39
+ end
40
+
41
+ def test_send_spool_to_foreman
42
+ test_spool = @base_spool_for_test + "/valid_spool/"
43
+ FileUtils.cp_r test_spool, @spooldir
44
+
45
+ Proxy::OpenSCAP::SpoolForwarder.new.post_arf_from_spool(@arf_dir)
46
+ assert(File.file?("#{@results_path}/reports/arf/#{@cname}/#{@id_1}/#{@date_1}/#{@valid_digest}"), "File should be in reports directory")
47
+ assert(File.file?("#{@results_path}/reports/arf/#{@cname}/#{@id_2}/#{@date_2}/#{@valid_digest}"), "File should be in reports directory")
48
+ refute(File.file?("#{@spooldir}/arf/#{@cname}/#{@policy_id}/#{@date_1}/#{@valid_digest}"), "File should not be in spool directory")
49
+ refute(File.file?("#{@spooldir}/arf/#{@cname}/#{@policy_id}/#{@date_2}/#{@valid_digest}"), "File should not be in spool directory")
50
+ end
51
+
52
+ def test_send_corrupted_spool_to_foreman
53
+ test_spool = @base_spool_for_test + "/corrupted_spool/"
54
+ FileUtils.cp_r test_spool, @spooldir
55
+
56
+ Proxy::OpenSCAP::SpoolForwarder.new.post_arf_from_spool(@arf_dir)
57
+
58
+ assert(File.file?("#{@results_path}/corrupted/arf/#{@cname}/#{@policy_id}/#{@date_1}/#{@corrupted_digest}"), "File should be in corrupted directory")
59
+ assert(File.file?("#{@results_path}/reports/arf/#{@cname}/#{@id_2}/#{@date_2}/#{@valid_digest}"), "File should be in reports directory")
60
+
61
+ refute(File.file?("#{@spooldir}/arf/#{@cname}/#{@policy_id}/#{@date_1}/#{@corrupted_digest}"), "File should not be in spool directory")
62
+ refute(File.file?("#{@spooldir}/arf/#{@cname}/#{@policy_id}/#{@date_2}/#{@valid_digest}"), "File should not be in spool directory")
63
+ end
64
+
65
+ def test_send_spool_cleans_up
66
+ test_spool = @base_spool_for_test + "/cleanup_spool/"
67
+ FileUtils.cp_r test_spool, @spooldir
68
+
69
+ stub_request(:post, "#{@foreman_url}/api/v2/compliance/arf_reports/#{@cname}/#{@policy_id}/#{@date_1}")
70
+ .to_return(:status => 200, :body => "{\"result\":\"OK\",\"id\":\"#{@id_1}\"}")
71
+
72
+ stub_request(:post, "#{@foreman_url}/api/v2/compliance/arf_reports/#{@cname_2}/#{@policy_id}/#{@date_2}")
73
+ .to_return(:status => 500)
74
+
75
+ Proxy::OpenSCAP::SpoolForwarder.new.post_arf_from_spool(@arf_dir)
76
+
77
+ assert(File.file?("#{@results_path}/reports/arf/#{@cname}/#{@id_1}/#{@date_1}/#{@valid_digest}"), "File should be in reports directory")
78
+ assert(File.file?("#{@spooldir}/arf/#{@cname_2}/#{@policy_id}/#{@date_2}/#{@valid_digest}"), "File should be in spool directory")
79
+
80
+ refute(File.exist?("#{@spooldir}/arf/#{@cname}"), "Folder should not exist")
81
+ end
82
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_proxy_openscap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Šimon Lukašík"
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-02-14 00:00:00.000000000 Z
13
+ date: 2017-03-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -121,6 +121,13 @@ files:
121
121
  - settings.d/openscap.yml.example
122
122
  - smart_proxy_openscap.gemspec
123
123
  - test/data/arf_report
124
+ - test/data/corrupted_arf_report
125
+ - test/data/spool/cleanup_spool/arf/2c101b95-033f-4b15-b490-f50bf9090dae/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1
126
+ - test/data/spool/cleanup_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484309984/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1
127
+ - test/data/spool/corrupted_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484309984/a4dfba5db27b21795e6fa401b8dce7a70faeb25b7963891f07f6f4baaf052afb
128
+ - test/data/spool/corrupted_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1
129
+ - test/data/spool/valid_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484309984/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1
130
+ - test/data/spool/valid_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1
124
131
  - test/data/ssg-rhel7-ds.xml
125
132
  - test/data/tailoring.xml
126
133
  - test/fetch_scap_api_test.rb
@@ -128,6 +135,7 @@ files:
128
135
  - test/get_report_xml_html_test.rb
129
136
  - test/post_report_api_test.rb
130
137
  - test/scap_content_parser_api_test.rb
138
+ - test/spool_forwarder_test.rb
131
139
  - test/test_helper.rb
132
140
  homepage: http://github.com/OpenSCAP/smart_proxy_openscap
133
141
  licenses: