abide_dev_utils 0.8.0 → 0.9.4

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: 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