abide_dev_utils 0.8.0 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3978f655b9053e54d4fd63d456d3d65b9079c7684c6fcc88a3f764ead1aa012a
4
- data.tar.gz: 746265daf86c8095a0f4ddbf9909d85a30ba2495b2b449e19896584c6e88da2b
3
+ metadata.gz: 3b3a74b07a3c45d7177fa8b2dd24f4c6eb0943f6ac9c907ab9d28878e628b990
4
+ data.tar.gz: 03de5f44f3150377e738bd7bb3f732136a956e463601f6b555b0ec5da1a3e574
5
5
  SHA512:
6
- metadata.gz: a6bbb36782aff2d06e4fd55ea66582cf64c4414c2e13f1c3cca76c8b1c33c420f76474b058c2e2ce49bb294efc01b677588957fa8f745d3b2fa022683253281f
7
- data.tar.gz: 78f92a917f547ba04f17610e0bca9cc5816efaadf7b066645cc75e40c303173a9b0d3e27ea0d7a741219f88c5e479810e14f180fc813cd5a31e3d6f0ee4bf65e
6
+ metadata.gz: bd522c8469aa8c96a75891366b636ef0c1ece9296c16e973896d8cb8e2c897a3d1b475ef98648a4be052085c8f7e681d708b2987df87e1fedaf2fa4a16d40011
7
+ data.tar.gz: 63720ae69e2ff22423f9ae2a6d217b6ccdbd0ce90f4fd79a8762579a9e1398bd5ea75e244aec64783029c74d9b9a76358ef5251c927a510684e4425f488cfb05
data/.gitignore CHANGED
@@ -10,4 +10,3 @@ w10_20h2.xml
10
10
  w10_2004.xml
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
- Gemfile.lock
data/Gemfile.lock ADDED
@@ -0,0 +1,273 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ abide_dev_utils (0.9.3)
5
+ cmdparse (~> 3.0)
6
+ google-cloud-storage (~> 1.34)
7
+ hashdiff (~> 1.0)
8
+ jira-ruby (~> 2.1)
9
+ nokogiri (~> 1.11)
10
+ puppet (>= 6.23)
11
+ ruby-progressbar (~> 1.11)
12
+ selenium-webdriver (~> 4.0.0.beta4)
13
+
14
+ GEM
15
+ remote: https://rubygems.org/
16
+ specs:
17
+ activesupport (7.0.1)
18
+ concurrent-ruby (~> 1.0, >= 1.0.2)
19
+ i18n (>= 1.6, < 2)
20
+ minitest (>= 5.1)
21
+ tzinfo (~> 2.0)
22
+ addressable (2.8.0)
23
+ public_suffix (>= 2.0.2, < 5.0)
24
+ ast (2.4.2)
25
+ async (1.30.1)
26
+ console (~> 1.10)
27
+ nio4r (~> 2.3)
28
+ timers (~> 4.1)
29
+ async-http (0.56.5)
30
+ async (>= 1.25)
31
+ async-io (>= 1.28)
32
+ async-pool (>= 0.2)
33
+ protocol-http (~> 0.22.0)
34
+ protocol-http1 (~> 0.14.0)
35
+ protocol-http2 (~> 0.14.0)
36
+ async-http-faraday (0.11.0)
37
+ async-http (~> 0.42)
38
+ faraday
39
+ async-io (1.32.2)
40
+ async
41
+ async-pool (0.3.9)
42
+ async (>= 1.25)
43
+ atlassian-jwt (0.2.1)
44
+ jwt (~> 2.1)
45
+ childprocess (4.1.0)
46
+ cmdparse (3.0.7)
47
+ coderay (1.1.3)
48
+ concurrent-ruby (1.1.9)
49
+ console (1.14.0)
50
+ fiber-local
51
+ declarative (0.0.20)
52
+ deep_merge (1.2.2)
53
+ diff-lcs (1.5.0)
54
+ digest-crc (0.6.4)
55
+ rake (>= 12.0.0, < 14.0.0)
56
+ facter (4.2.7)
57
+ hocon (~> 1.3)
58
+ thor (>= 1.0.1, < 2.0)
59
+ faraday (1.9.3)
60
+ faraday-em_http (~> 1.0)
61
+ faraday-em_synchrony (~> 1.0)
62
+ faraday-excon (~> 1.1)
63
+ faraday-httpclient (~> 1.0)
64
+ faraday-multipart (~> 1.0)
65
+ faraday-net_http (~> 1.0)
66
+ faraday-net_http_persistent (~> 1.0)
67
+ faraday-patron (~> 1.0)
68
+ faraday-rack (~> 1.0)
69
+ faraday-retry (~> 1.0)
70
+ ruby2_keywords (>= 0.0.4)
71
+ faraday-em_http (1.0.0)
72
+ faraday-em_synchrony (1.0.0)
73
+ faraday-excon (1.1.0)
74
+ faraday-http-cache (2.2.0)
75
+ faraday (>= 0.8)
76
+ faraday-httpclient (1.0.1)
77
+ faraday-multipart (1.0.3)
78
+ multipart-post (>= 1.2, < 3)
79
+ faraday-net_http (1.0.1)
80
+ faraday-net_http_persistent (1.2.0)
81
+ faraday-patron (1.0.0)
82
+ faraday-rack (1.0.0)
83
+ faraday-retry (1.0.3)
84
+ fast_gettext (1.8.0)
85
+ fiber-local (1.0.0)
86
+ gem-release (2.2.2)
87
+ github_changelog_generator (1.16.4)
88
+ activesupport
89
+ async (>= 1.25.0)
90
+ async-http-faraday
91
+ faraday-http-cache
92
+ multi_json
93
+ octokit (~> 4.6)
94
+ rainbow (>= 2.2.1)
95
+ rake (>= 10.0)
96
+ google-apis-core (0.4.1)
97
+ addressable (~> 2.5, >= 2.5.1)
98
+ googleauth (>= 0.16.2, < 2.a)
99
+ httpclient (>= 2.8.1, < 3.a)
100
+ mini_mime (~> 1.0)
101
+ representable (~> 3.0)
102
+ retriable (>= 2.0, < 4.a)
103
+ rexml
104
+ webrick
105
+ google-apis-iamcredentials_v1 (0.10.0)
106
+ google-apis-core (>= 0.4, < 2.a)
107
+ google-apis-storage_v1 (0.11.0)
108
+ google-apis-core (>= 0.4, < 2.a)
109
+ google-cloud-core (1.6.0)
110
+ google-cloud-env (~> 1.0)
111
+ google-cloud-errors (~> 1.0)
112
+ google-cloud-env (1.5.0)
113
+ faraday (>= 0.17.3, < 2.0)
114
+ google-cloud-errors (1.2.0)
115
+ google-cloud-storage (1.36.0)
116
+ addressable (~> 2.8)
117
+ digest-crc (~> 0.4)
118
+ google-apis-iamcredentials_v1 (~> 0.1)
119
+ google-apis-storage_v1 (~> 0.1)
120
+ google-cloud-core (~> 1.6)
121
+ googleauth (>= 0.16.2, < 2.a)
122
+ mini_mime (~> 1.0)
123
+ googleauth (1.1.0)
124
+ faraday (>= 0.17.3, < 2.0)
125
+ jwt (>= 1.4, < 3.0)
126
+ memoist (~> 0.16)
127
+ multi_json (~> 1.11)
128
+ os (>= 0.9, < 2.0)
129
+ signet (>= 0.16, < 2.a)
130
+ hashdiff (1.0.1)
131
+ hiera (3.8.0)
132
+ hocon (1.3.1)
133
+ httpclient (2.8.3)
134
+ i18n (1.8.11)
135
+ concurrent-ruby (~> 1.0)
136
+ jira-ruby (2.2.0)
137
+ activesupport
138
+ atlassian-jwt
139
+ multipart-post
140
+ oauth (~> 0.5, >= 0.5.0)
141
+ jwt (2.3.0)
142
+ locale (2.1.3)
143
+ memoist (0.16.2)
144
+ method_source (1.0.0)
145
+ mini_mime (1.1.2)
146
+ mini_portile2 (2.7.1)
147
+ minitest (5.15.0)
148
+ multi_json (1.15.0)
149
+ multipart-post (2.1.1)
150
+ nio4r (2.5.8)
151
+ nokogiri (1.13.1)
152
+ mini_portile2 (~> 2.7.0)
153
+ racc (~> 1.4)
154
+ oauth (0.5.8)
155
+ octokit (4.22.0)
156
+ faraday (>= 0.9)
157
+ sawyer (~> 0.8.0, >= 0.5.3)
158
+ os (1.1.4)
159
+ parallel (1.21.0)
160
+ parser (3.1.0.0)
161
+ ast (~> 2.4.1)
162
+ protocol-hpack (1.4.2)
163
+ protocol-http (0.22.5)
164
+ protocol-http1 (0.14.2)
165
+ protocol-http (~> 0.22)
166
+ protocol-http2 (0.14.2)
167
+ protocol-hpack (~> 1.4)
168
+ protocol-http (~> 0.18)
169
+ pry (0.14.1)
170
+ coderay (~> 1.1)
171
+ method_source (~> 1.0)
172
+ public_suffix (4.0.6)
173
+ puppet (7.13.1)
174
+ concurrent-ruby (~> 1.0)
175
+ deep_merge (~> 1.0)
176
+ facter (> 2.0.1, < 5)
177
+ fast_gettext (>= 1.1, < 3)
178
+ hiera (>= 3.2.1, < 4)
179
+ locale (~> 2.1)
180
+ multi_json (~> 1.10)
181
+ puppet-resource_api (~> 1.5)
182
+ scanf (~> 1.0)
183
+ semantic_puppet (~> 1.0)
184
+ puppet-resource_api (1.8.14)
185
+ hocon (>= 1.0)
186
+ racc (1.6.0)
187
+ rainbow (3.1.1)
188
+ rake (13.0.6)
189
+ regexp_parser (2.2.0)
190
+ representable (3.1.1)
191
+ declarative (< 0.1.0)
192
+ trailblazer-option (>= 0.1.1, < 0.2.0)
193
+ uber (< 0.2.0)
194
+ retriable (3.1.2)
195
+ rexml (3.2.5)
196
+ rspec (3.10.0)
197
+ rspec-core (~> 3.10.0)
198
+ rspec-expectations (~> 3.10.0)
199
+ rspec-mocks (~> 3.10.0)
200
+ rspec-core (3.10.1)
201
+ rspec-support (~> 3.10.0)
202
+ rspec-expectations (3.10.2)
203
+ diff-lcs (>= 1.2.0, < 2.0)
204
+ rspec-support (~> 3.10.0)
205
+ rspec-mocks (3.10.2)
206
+ diff-lcs (>= 1.2.0, < 2.0)
207
+ rspec-support (~> 3.10.0)
208
+ rspec-support (3.10.3)
209
+ rubocop (1.24.1)
210
+ parallel (~> 1.10)
211
+ parser (>= 3.0.0.0)
212
+ rainbow (>= 2.2.2, < 4.0)
213
+ regexp_parser (>= 1.8, < 3.0)
214
+ rexml
215
+ rubocop-ast (>= 1.15.1, < 2.0)
216
+ ruby-progressbar (~> 1.7)
217
+ unicode-display_width (>= 1.4.0, < 3.0)
218
+ rubocop-ast (1.15.1)
219
+ parser (>= 3.0.1.1)
220
+ rubocop-i18n (3.0.0)
221
+ rubocop (~> 1.0)
222
+ rubocop-performance (1.13.1)
223
+ rubocop (>= 1.7.0, < 2.0)
224
+ rubocop-ast (>= 0.4.0)
225
+ rubocop-rspec (2.7.0)
226
+ rubocop (~> 1.19)
227
+ ruby-progressbar (1.11.0)
228
+ ruby2_keywords (0.0.5)
229
+ rubyzip (2.3.2)
230
+ sawyer (0.8.2)
231
+ addressable (>= 2.3.5)
232
+ faraday (> 0.8, < 2.0)
233
+ scanf (1.0.0)
234
+ selenium-webdriver (4.0.3)
235
+ childprocess (>= 0.5, < 5.0)
236
+ rexml (~> 3.2, >= 3.2.5)
237
+ rubyzip (>= 1.2.2)
238
+ semantic_puppet (1.0.4)
239
+ signet (0.16.0)
240
+ addressable (~> 2.8)
241
+ faraday (>= 0.17.3, < 2.0)
242
+ jwt (>= 1.5, < 3.0)
243
+ multi_json (~> 1.10)
244
+ thor (1.2.1)
245
+ timers (4.3.3)
246
+ trailblazer-option (0.1.2)
247
+ tzinfo (2.0.4)
248
+ concurrent-ruby (~> 1.0)
249
+ uber (0.1.0)
250
+ unicode-display_width (2.1.0)
251
+ webrick (1.7.0)
252
+
253
+ PLATFORMS
254
+ ruby
255
+
256
+ DEPENDENCIES
257
+ abide_dev_utils!
258
+ bundler
259
+ console
260
+ fast_gettext (~> 1.8)
261
+ gem-release
262
+ github_changelog_generator
263
+ pry
264
+ rake
265
+ rspec (~> 3.10)
266
+ rubocop (~> 1.8)
267
+ rubocop-ast (~> 1.4)
268
+ rubocop-i18n (~> 3.0)
269
+ rubocop-performance (~> 1.9)
270
+ rubocop-rspec (~> 2.1)
271
+
272
+ BUNDLED WITH
273
+ 2.1.4
@@ -71,6 +71,9 @@ module Abide
71
71
  options.on('--ignore [X,Y,Z]', Array, OPT_IGNORE_NODES) do |i|
72
72
  @data[:ignorelist] = i
73
73
  end
74
+ options.on('--page-source-on-error', 'Dump page source to file on error') do
75
+ @data[:page_source_on_error] = true
76
+ end
74
77
  end
75
78
 
76
79
  def help_arguments
@@ -16,17 +16,64 @@ module Abide
16
16
  add_command(CmdParse::HelpCommand.new, default: true)
17
17
  add_command(XccdfToHieraCommand.new)
18
18
  add_command(XccdfDiffCommand.new)
19
+ add_command(XccdfGenMapCommand.new)
19
20
  end
20
21
  end
21
22
 
22
- class XccdfToHieraCommand < CmdParse::Command
23
+ class XccdfGenMapCommand < AbideCommand
24
+ CMD_NAME = 'gen-map'
25
+ CMD_SHORT = 'Generates mappings from XCCDF files'
26
+ CMD_LONG = 'Generates mappings for CEM modules from 1 or more XCCDF files as YAML'
27
+ CMD_XCCDF_FILES_ARG = 'One or more paths to XCCDF files'
28
+ def initialize
29
+ super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: false)
30
+ argument_desc(XCCDF_FILES: CMD_XCCDF_FILES_ARG)
31
+ options.on('-b [TYPE]', '--benchmark-type [TYPE]', 'XCCDF Benchmark type CIS by default') do |b|
32
+ @data[:type] = b
33
+ end
34
+ options.on('-d [DIR]', '--files-output-directory [DIR]', 'Directory to save files data/mappings by default') do |d|
35
+ @data[:dir] = d
36
+ end
37
+ options.on('-q', '--quiet', 'Show no output in the terminal') { @data[:quiet] = true }
38
+ options.on('-p [PREFIX]', '--parent-key-prefix [PREFIX]', 'A prefix to append to the parent key') do |p|
39
+ @data[:parent_key_prefix] = p
40
+ end
41
+ end
42
+
43
+ def execute(*xccdf_files)
44
+ if @data[:quiet] && @data[:dir].nil?
45
+ AbideDevUtils::Output.simple("I don\'t know how to quietly output to the console\n¯\\_(ツ)_/¯")
46
+ exit 1
47
+ end
48
+ xccdf_files.each do |xccdf_file|
49
+ other_kwarg_syms = %i[type dir quiet parent_key_prefix]
50
+ other_kwargs = @data.reject { |k, _| other_kwarg_syms.include?(k) }
51
+ hfile = AbideDevUtils::XCCDF.gen_map(
52
+ File.expand_path(xccdf_file),
53
+ dir: @data[:dir],
54
+ type: @data.fetch(:type, 'cis'),
55
+ parent_key_prefix: @data.fetch(:parent_key_prefix, ''),
56
+ **other_kwargs
57
+ )
58
+ mapping_dir = File.dirname(hfile.keys[0]) unless @data[:dir].nil?
59
+ unless @data[:quiet] || @data[:dir].nil? || File.directory?(mapping_dir)
60
+ AbideDevUtils::Output.simple("Creating directory #{mapping_dir}")
61
+ end
62
+ FileUtils.mkdir_p(mapping_dir) unless @data[:dir].nil?
63
+ hfile.each do |key, val|
64
+ file_path = @data[:dir].nil? ? nil : key
65
+ AbideDevUtils::Output.yaml(val, console: @data[:dir].nil?, file: file_path)
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ class XccdfToHieraCommand < AbideCommand
23
72
  CMD_NAME = 'to-hiera'
24
73
  CMD_SHORT = 'Generates control coverage report'
25
74
  CMD_LONG = 'Generates report of valid Puppet classes that match with Hiera controls'
26
75
  def initialize
27
- super(CMD_NAME, takes_commands: false)
28
- short_desc(CMD_SHORT)
29
- long_desc(CMD_LONG)
76
+ super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: false)
30
77
  options.on('-b [TYPE]', '--benchmark-type [TYPE]', 'XCCDF Benchmark type') { |b| @data[:type] = b }
31
78
  options.on('-o [FILE]', '--out-file [FILE]', 'Path to save file') { |f| @data[:file] = f }
32
79
  options.on('-p [PREFIX]', '--parent-key-prefix [PREFIX]', 'A prefix to append to the parent key') do |p|
@@ -135,6 +135,11 @@ module AbideDevUtils
135
135
  subject.find_element(**kwargs)
136
136
  end
137
137
 
138
+ def find_elements(subject = driver, **kwargs)
139
+ driver.manage.window.resize_to(1920, 1080)
140
+ subject.find_elements(**kwargs)
141
+ end
142
+
138
143
  def wait_on(timeout: @timeout,
139
144
  ignore_nse: false,
140
145
  quit_driver: true,
@@ -231,7 +236,7 @@ module AbideDevUtils
231
236
  error_text = wait_on(ignore_nse: true) { find_element(class: 'kc-feedback-text').text }
232
237
  return if error_text.nil? || error_text.empty?
233
238
 
234
- raise ComplyLoginFailedError, error_text
239
+ raise AbideDevUtils::Comply::ComplyLoginFailedError, error_text
235
240
  end
236
241
 
237
242
  def filter_node_report_links(node_report_links)
@@ -301,6 +306,18 @@ module AbideDevUtils
301
306
  nstr
302
307
  end
303
308
 
309
+ def wait_on_element_and_increment(subject = driver, **element_id)
310
+ element = wait_on { find_element(subject, **element_id) }
311
+ progress.increment
312
+ element
313
+ end
314
+
315
+ def wait_on_elements_and_increment(subject = driver, **element_id)
316
+ elements = wait_on { find_elements(subject, **element_id) }
317
+ progress.increment
318
+ elements
319
+ end
320
+
304
321
  def scrape_report
305
322
  output.simple 'Building scan reports, this may take a while...'
306
323
  all_checks = {}
@@ -315,17 +332,14 @@ module AbideDevUtils
315
332
  progress.increment
316
333
  driver.switch_to.window driver.window_handles[1]
317
334
  driver.get(link_url)
318
- wait_on { find_element(class: 'details-scan-info') }
319
- progress.increment
320
- wait_on { find_element(class: 'details-table') }
321
- progress.increment
335
+ wait_on_element_and_increment(class: 'details-header')
336
+ wait_on_element_and_increment(class: 'details-scan-info')
337
+ wait_on_element_and_increment(class: 'details-table')
322
338
  report = { 'scan_results' => {} }
323
- scan_info_table = find_element(class: 'details-scan-info')
324
- scan_info_table_rows = scan_info_table.find_elements(tag_name: 'tr')
325
- progress.increment
326
- check_table_body = find_element(tag_name: 'tbody')
327
- check_table_rows = check_table_body.find_elements(tag_name: 'tr')
328
- progress.increment
339
+ scan_info_table = wait_on_element_and_increment(class: 'details-scan-info')
340
+ scan_info_table_rows = wait_on_elements_and_increment(scan_info_table, tag_name: 'tr')
341
+ check_table_body = wait_on_element_and_increment(tag_name: 'tbody')
342
+ check_table_rows = wait_on_elements_and_increment(check_table_body, tag_name: 'tr')
329
343
  scan_info_table_rows.each do |row|
330
344
  key = find_element(row, tag_name: 'h5').text
331
345
  value = find_element(row, tag_name: 'strong').text
@@ -53,5 +53,9 @@ module AbideDevUtils
53
53
  class NotHashableError < GenericError
54
54
  @default = 'Object does not respond to #to_hash or #to_h:'
55
55
  end
56
+
57
+ class CliOptionsConflict < GenericError
58
+ @default = "Console options conflict."
59
+ end
56
60
  end
57
61
  end
@@ -20,5 +20,9 @@ module AbideDevUtils
20
20
  class ProfilePartsError < GenericError
21
21
  @default = 'Failed to extract parts from profile name:'
22
22
  end
23
+
24
+ class UnsupportedXCCDFError < GenericError
25
+ @default = "XCCDF type is unsupported!"
26
+ end
23
27
  end
24
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.4"
5
5
  end
@@ -10,6 +10,17 @@ require 'abide_dev_utils/output'
10
10
  module AbideDevUtils
11
11
  # Contains modules and classes for working with XCCDF files
12
12
  module XCCDF
13
+ # Generate map for CEM
14
+ def self.gen_map(xccdf_file, **opts)
15
+ type = opts.fetch(:type, 'cis')
16
+ case type.downcase
17
+ when 'cis'
18
+ Benchmark.new(xccdf_file).gen_map(**opts)
19
+ else
20
+ raise AbideDevUtils::Errors::UnsupportedXCCDFError, "XCCDF type #{type} is unsupported!"
21
+ end
22
+ end
23
+
13
24
  # Converts and xccdf file to a Hiera representation
14
25
  def self.to_hiera(xccdf_file, opts)
15
26
  type = opts.fetch(:type, 'cis')
@@ -17,7 +28,7 @@ module AbideDevUtils
17
28
  when 'cis'
18
29
  Benchmark.new(xccdf_file).to_hiera(**opts)
19
30
  else
20
- AbideDevUtils::Output.simple("XCCDF type #{type} is unsupported!")
31
+ raise AbideDevUtils::Errors::UnsupportedXCCDFError, "XCCDF type #{type} is unsupported!"
21
32
  end
22
33
  end
23
34
 
@@ -181,6 +192,8 @@ module AbideDevUtils
181
192
  class Benchmark
182
193
  include AbideDevUtils::XCCDF::Common
183
194
 
195
+ MAP_INDICES = %w[title hiera_title hiera_title_num number].freeze
196
+
184
197
  attr_reader :xml, :title, :version, :diff_properties
185
198
 
186
199
  def initialize(path)
@@ -218,6 +231,16 @@ module AbideDevUtils
218
231
  profiles.select { |x| x.title == profile_title }.controls
219
232
  end
220
233
 
234
+ def gen_map(dir: nil, type: 'CIS', parent_key_prefix: '', **_)
235
+ os, ver = facter_platform
236
+ mapping_dir = dir ? File.expand_path(File.join(dir, type, os, ver)) : ''
237
+ parent_key_prefix = '' if parent_key_prefix.nil?
238
+ MAP_INDICES.each_with_object({}) do |idx, h|
239
+ map_file_path = "#{mapping_dir}/#{idx}.yaml"
240
+ h[map_file_path] = map_indexed(index: idx, framework: type, key_prefix: parent_key_prefix)
241
+ end
242
+ end
243
+
221
244
  def find_cis_recommendation(name, number_format: false)
222
245
  profiles.each do |profile|
223
246
  profile.controls.each do |ctrl|
@@ -261,6 +284,23 @@ module AbideDevUtils
261
284
  controls.diff(other.controls)
262
285
  end
263
286
 
287
+ def map_indexed(index: 'title', framework: 'cis', key_prefix: '')
288
+ c_map = profiles.each_with_object({}) do |profile, obj|
289
+ obj[profile.level.downcase] = {} unless obj[profile.level.downcase].is_a?(Hash)
290
+ obj[profile.level.downcase][profile.title.downcase] = map_controls_hash(profile, index).sort_by { |k, _| k }.to_h
291
+ end
292
+
293
+ c_map['benchmark'] = { 'title' => title, 'version' => version }
294
+ mappings = [framework, index]
295
+ mappings.unshift(key_prefix) unless key_prefix.empty?
296
+ { mappings.join('::') => c_map }.to_yaml
297
+ end
298
+
299
+ def facter_platform
300
+ cpe = xpath('xccdf:Benchmark/xccdf:platform')[0]['idref'].split(':')
301
+ [cpe[4].split('_')[0], cpe[5].split('.')[0]]
302
+ end
303
+
264
304
  # Converts object to Hiera-formatted YAML
265
305
  # @return [String] YAML-formatted string
266
306
  def to_hiera(parent_key_prefix: nil, num: false, levels: [], titles: [], **_kwargs)
@@ -284,6 +324,29 @@ module AbideDevUtils
284
324
 
285
325
  private
286
326
 
327
+ def format_map_control_index(index, control)
328
+ case index
329
+ when 'hiera_title_num'
330
+ control.hiera_title(number_format: true)
331
+ when 'title'
332
+ resolve_control_reference(control).xpath('./xccdf:title').text
333
+ else
334
+ control.send(index.to_sym)
335
+ end
336
+ end
337
+
338
+ def map_controls_hash(profile, index)
339
+ profile.controls.each_with_object({}) do |ctrl, hsh|
340
+ control_array = MAP_INDICES.each_with_object([]) do |idx_sym, ary|
341
+ next if idx_sym == index
342
+
343
+ item = format_map_control_index(idx_sym, ctrl)
344
+ ary << item.to_s
345
+ end
346
+ hsh[format_map_control_index(index, ctrl)] = control_array.sort
347
+ end
348
+ end
349
+
287
350
  def parse(path)
288
351
  validate_xccdf(path)
289
352
  Nokogiri::XML.parse(File.open(File.expand_path(path))) do |config|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abide_dev_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-14 00:00:00.000000000 Z
11
+ date: 2022-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -313,15 +313,14 @@ executables:
313
313
  extensions: []
314
314
  extra_rdoc_files: []
315
315
  files:
316
- - ".dockerignore"
317
316
  - ".gitignore"
318
317
  - ".rspec"
319
318
  - ".rubocop.yml"
320
319
  - ".rubocop_todo.yml"
321
320
  - CHANGELOG.md
322
321
  - CODEOWNERS
323
- - Dockerfile
324
322
  - Gemfile
323
+ - Gemfile.lock
325
324
  - LICENSE.txt
326
325
  - README.md
327
326
  - Rakefile
@@ -330,7 +329,6 @@ files:
330
329
  - bin/console
331
330
  - bin/setup
332
331
  - exe/abide
333
- - itests.rb
334
332
  - lib/abide_dev_utils.rb
335
333
  - lib/abide_dev_utils/cli.rb
336
334
  - lib/abide_dev_utils/cli/abstract.rb
@@ -388,7 +386,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
388
386
  - !ruby/object:Gem::Version
389
387
  version: '0'
390
388
  requirements: []
391
- rubygems_version: 3.1.4
389
+ rubygems_version: 3.1.6
392
390
  signing_key:
393
391
  specification_version: 4
394
392
  summary: Helper utilities for developing compliance Puppet code
data/.dockerignore DELETED
@@ -1 +0,0 @@
1
- Gemfile.lock
data/Dockerfile DELETED
@@ -1,23 +0,0 @@
1
- FROM ruby:2.7.3-alpine
2
-
3
- ARG version
4
-
5
- RUN mkdir /extvol && \
6
- apk update && \
7
- apk add git build-base
8
-
9
- VOLUME /extvol
10
-
11
- WORKDIR /usr/src/app
12
-
13
- RUN mkdir -p ./lib/abide_dev_utils/
14
- COPY Gemfile abide_dev_utils.gemspec ./
15
- COPY lib/abide_dev_utils/version.rb lib/abide_dev_utils
16
- RUN bundle install
17
-
18
- COPY . .
19
-
20
- RUN bundle exec rake build && \
21
- gem install pkg/abide_dev_utils-${version}.gem
22
-
23
- ENTRYPOINT [ "abide" ]
data/itests.rb DELETED
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'json'
5
- require 'yaml'
6
- require 'abide_dev_utils/comply'
7
- require 'abide_dev_utils/ppt/api'
8
-
9
- OS_BENCHMARK_MAP = {
10
- 'centos-7' => 'CIS_CentOS_Linux_7_Benchmark_v3.1.1-xccdf.xml',
11
- 'centos-8' => 'CIS_CentOS_Linux_8_Benchmark_v1.0.1-xccdf.xml',
12
- 'rhel-7' => 'CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v3.1.1-xccdf.xml',
13
- 'rhel-8' => 'CIS_Red_Hat_Enterprise_Linux_8_Benchmark_v1.0.1-xccdf.xml',
14
- 'serv-2016' => 'CIS_Microsoft_Windows_Server_2016_RTM_(Release_1607)_Benchmark_v1.3.0-xccdf.xml',
15
- 'serv-2019' => 'CIS_Microsoft_Windows_Server_2019_Benchmark_v1.2.1-xccdf.xml'
16
- }
17
- EL_PROFILE_1_SERVER = 'xccdf_org.cisecurity.benchmarks_profile_Level_1_-_Server'
18
- WIN_PROFILE_1_MS = 'xccdf_org.cisecurity.benchmarks_profile_Level_1_-_Member_Server'
19
- NIX_SCAN_HASH = {
20
- 'nix-centos-7.c.team-sse.internal' => {
21
- 'benchmark' => OS_BENCHMARK_MAP['centos-7'],
22
- 'profile' => EL_PROFILE_1_SERVER
23
- },
24
- 'nix-centos-8.c.team-sse.internal' => {
25
- 'benchmark' => OS_BENCHMARK_MAP['centos-8'],
26
- 'profile' => EL_PROFILE_1_SERVER
27
- },
28
- 'nix-rhel-7.c.team-sse.internal' => {
29
- 'benchmark' => OS_BENCHMARK_MAP['rhel-7'],
30
- 'profile' => EL_PROFILE_1_SERVER
31
- },
32
- 'nix-rhel-8.c.team-sse.internal' => {
33
- 'benchmark' => OS_BENCHMARK_MAP['rhel-8'],
34
- 'profile' => EL_PROFILE_1_SERVER
35
- }
36
- }.freeze
37
- WIN_SCAN_HASH = {
38
- 'win-server-2016.c.team-sse.internal' => {
39
- 'benchmark' => OS_BENCHMARK_MAP['serv-2016'],
40
- 'profile' => EL_PROFILE_1_SERVER
41
- },
42
- 'win-serv-2019.c.team-sse.internal' => {
43
- 'benchmark' => OS_BENCHMARK_MAP['serv-2019'],
44
- 'profile' => WIN_PROFILE_1_MS
45
- }
46
- }.freeze
47
-
48
- scan_hash = ENV['ABIDE_OS'] == 'nix' ? NIX_SCAN_HASH : WIN_SCAN_HASH
49
- node_group_name = ENV['ABIDE_OS'] == 'nix' ? 'CEM Linux Nodes' : 'CEM Windows Nodes'
50
-
51
- puts 'Creating client...'
52
- client = AbideDevUtils::Ppt::ApiClient.new(ENV['PUPPET_HOST'], auth_token: ENV['PE_ACCESS_TOKEN'])
53
- puts 'Starting code deploy...'
54
- code_manager_deploy = client.post_codemanager_deploys('environments' => ['production'], 'wait' => true)
55
- raise 'Code manager deployment failed!' unless code_manager_deploy['status'] == 'complete'
56
-
57
- puts 'Code deploy successful...'
58
- puts 'Gathering node group ID...'
59
- node_groups = client.get_classifier1_groups
60
- node_group_id = nil
61
- node_groups.each { |x| node_group_id = x['id'] if x['name'] == node_group_name }
62
- raise 'Failed to find requested node group!' if node_group_id.nil?
63
-
64
- puts 'Running Puppet on nodes...'
65
- puppet_run = client.post_orchestrator_command_deploy('environment' => 'production', 'scope' => { 'node_group' => node_group_id })
66
- puts "Started job #{puppet_run['job']['name']}..."
67
- timeout = 0
68
- run_complete = false
69
- until run_complete || timeout >= 30
70
- puts "Waiting on job #{puppet_run['job']['name']} to complete..."
71
- status = client.get_orchestrator_jobs(puppet_run['job']['name'])
72
- case status['state']
73
- when 'failed'
74
- raise "Job #{puppet_run['job']['name']} finished with failures!"
75
- when 'finished'
76
- run_complete = true
77
- break
78
- else
79
- timeout += 1
80
- sleep(10)
81
- end
82
- end
83
- raise 'Job timed out waiting for completion' unless run_complete
84
-
85
- puts 'Starting node scans...'
86
- scan_job = client.post_orchestrator_command_task(
87
- 'environment' => 'production',
88
- 'task' => 'comply::ciscat_scan',
89
- 'params' => {
90
- 'comply_port' => '443',
91
- 'comply_server' => ENV['COMPLY_FQDN'],
92
- 'ssl_verify_mode' => 'none',
93
- 'scan_type' => 'desired',
94
- 'scan_hash' => JSON.generate(scan_hash)
95
- },
96
- 'scope' => {
97
- 'node_group' => node_group_id
98
- }
99
- )
100
- puts "Started scan #{scan_job['job']['name']}..."
101
- timeout = 0
102
- scan_complete = false
103
- until scan_complete || timeout >= 30
104
- puts "Waiting on scan #{scan_job['job']['name']} to complete..."
105
- status = client.get_orchestrator_jobs(scan_job['job']['name'])
106
- case status['state']
107
- when 'failed'
108
- raise "Task #{scan_job['job']['name']} finished with failures!"
109
- when 'finished'
110
- scan_complete = true
111
- break
112
- else
113
- timeout += 1
114
- sleep(10)
115
- end
116
- end
117
- raise 'Job timed out waiting for completion' unless scan_complete
118
-
119
- puts 'Collecting scan report from Comply...'
120
- onlylist = scan_hash.keys
121
- scan_report = AbideDevUtils::Comply.build_report("https://#{ENV['COMPLY_FQDN']}", ENV['COMPLY_PASSWORD'], nil, onlylist: onlylist)
122
- puts 'Saving report to nix_report.yaml...'
123
- File.open('nix_report.yaml', 'w') { |f| f.write(scan_report.to_yaml) }
124
-
125
- puts 'Comparing current report to last report...'
126
- opts = {
127
- report_name: 'nix_report.yaml',
128
- remote_storage: 'gcloud',
129
- upload: true
130
- }
131
- result = AbideDevUtils::Comply.compare_reports(File.expand_path('./nix_report.yaml'), 'nix_report.yaml', opts)
132
- if result
133
- puts 'Success!'
134
- exit(0)
135
- else
136
- puts 'Failure!'
137
- exit(1)
138
- end