abide_dev_utils 0.9.4 → 0.10.0

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: 3b3a74b07a3c45d7177fa8b2dd24f4c6eb0943f6ac9c907ab9d28878e628b990
4
- data.tar.gz: 03de5f44f3150377e738bd7bb3f732136a956e463601f6b555b0ec5da1a3e574
3
+ metadata.gz: 4fc3820895d385ca28d6e097c1822cfaf878d41e2b282bfca55bec2e884a2dc2
4
+ data.tar.gz: de27ab8fb2021de5cd437695566e4ab0ad0531bc94659948557b3b09a05d59f5
5
5
  SHA512:
6
- metadata.gz: bd522c8469aa8c96a75891366b636ef0c1ece9296c16e973896d8cb8e2c897a3d1b475ef98648a4be052085c8f7e681d708b2987df87e1fedaf2fa4a16d40011
7
- data.tar.gz: 63720ae69e2ff22423f9ae2a6d217b6ccdbd0ce90f4fd79a8762579a9e1398bd5ea75e244aec64783029c74d9b9a76358ef5251c927a510684e4425f488cfb05
6
+ metadata.gz: 7df796781a8f4e4b87cf324c83273a9d2964f44f8dc8fd9f68c65610295f7b9f5161b70c23d66ab19ff75ca610860d27245256dabf6e69633850cbd2d1f3dd96
7
+ data.tar.gz: 3cf0142c1a0f3fae3bab07f65add4a320f90ca900adc5be63b77f72e40edba4936b6ea835796d0fd6b2c3cff034b6a2dcb4f5bd1ff43a476b40bcc053c5356cb
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.9.3)
4
+ abide_dev_utils (0.10.0)
5
+ amatch (~> 0.4)
5
6
  cmdparse (~> 3.0)
6
7
  google-cloud-storage (~> 1.34)
7
8
  hashdiff (~> 1.0)
8
- jira-ruby (~> 2.1)
9
+ jira-ruby (~> 2.2)
9
10
  nokogiri (~> 1.11)
10
11
  puppet (>= 6.23)
11
12
  ruby-progressbar (~> 1.11)
@@ -14,13 +15,16 @@ PATH
14
15
  GEM
15
16
  remote: https://rubygems.org/
16
17
  specs:
17
- activesupport (7.0.1)
18
+ activesupport (7.0.2.2)
18
19
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
20
  i18n (>= 1.6, < 2)
20
21
  minitest (>= 5.1)
21
22
  tzinfo (~> 2.0)
22
23
  addressable (2.8.0)
23
24
  public_suffix (>= 2.0.2, < 5.0)
25
+ amatch (0.4.0)
26
+ mize
27
+ tins (~> 1.0)
24
28
  ast (2.4.2)
25
29
  async (1.30.1)
26
30
  console (~> 1.10)
@@ -53,10 +57,10 @@ GEM
53
57
  diff-lcs (1.5.0)
54
58
  digest-crc (0.6.4)
55
59
  rake (>= 12.0.0, < 14.0.0)
56
- facter (4.2.7)
60
+ facter (4.2.9)
57
61
  hocon (~> 1.3)
58
62
  thor (>= 1.0.1, < 2.0)
59
- faraday (1.9.3)
63
+ faraday (1.10.0)
60
64
  faraday-em_http (~> 1.0)
61
65
  faraday-em_synchrony (~> 1.0)
62
66
  faraday-excon (~> 1.1)
@@ -93,7 +97,7 @@ GEM
93
97
  octokit (~> 4.6)
94
98
  rainbow (>= 2.2.1)
95
99
  rake (>= 10.0)
96
- google-apis-core (0.4.1)
100
+ google-apis-core (0.4.2)
97
101
  addressable (~> 2.5, >= 2.5.1)
98
102
  googleauth (>= 0.16.2, < 2.a)
99
103
  httpclient (>= 2.8.1, < 3.a)
@@ -104,15 +108,15 @@ GEM
104
108
  webrick
105
109
  google-apis-iamcredentials_v1 (0.10.0)
106
110
  google-apis-core (>= 0.4, < 2.a)
107
- google-apis-storage_v1 (0.11.0)
111
+ google-apis-storage_v1 (0.13.0)
108
112
  google-apis-core (>= 0.4, < 2.a)
109
113
  google-cloud-core (1.6.0)
110
114
  google-cloud-env (~> 1.0)
111
115
  google-cloud-errors (~> 1.0)
112
- google-cloud-env (1.5.0)
113
- faraday (>= 0.17.3, < 2.0)
116
+ google-cloud-env (1.6.0)
117
+ faraday (>= 0.17.3, < 3.0)
114
118
  google-cloud-errors (1.2.0)
115
- google-cloud-storage (1.36.0)
119
+ google-cloud-storage (1.36.1)
116
120
  addressable (~> 2.8)
117
121
  digest-crc (~> 0.4)
118
122
  google-apis-iamcredentials_v1 (~> 0.1)
@@ -120,18 +124,18 @@ GEM
120
124
  google-cloud-core (~> 1.6)
121
125
  googleauth (>= 0.16.2, < 2.a)
122
126
  mini_mime (~> 1.0)
123
- googleauth (1.1.0)
124
- faraday (>= 0.17.3, < 2.0)
127
+ googleauth (1.1.2)
128
+ faraday (>= 0.17.3, < 3.a)
125
129
  jwt (>= 1.4, < 3.0)
126
130
  memoist (~> 0.16)
127
131
  multi_json (~> 1.11)
128
132
  os (>= 0.9, < 2.0)
129
133
  signet (>= 0.16, < 2.a)
130
134
  hashdiff (1.0.1)
131
- hiera (3.8.0)
135
+ hiera (3.9.0)
132
136
  hocon (1.3.1)
133
137
  httpclient (2.8.3)
134
- i18n (1.8.11)
138
+ i18n (1.10.0)
135
139
  concurrent-ruby (~> 1.0)
136
140
  jira-ruby (2.2.0)
137
141
  activesupport
@@ -143,13 +147,15 @@ GEM
143
147
  memoist (0.16.2)
144
148
  method_source (1.0.0)
145
149
  mini_mime (1.1.2)
146
- mini_portile2 (2.7.1)
150
+ mini_portile2 (2.8.0)
147
151
  minitest (5.15.0)
152
+ mize (0.4.0)
153
+ protocol (~> 2.0)
148
154
  multi_json (1.15.0)
149
155
  multipart-post (2.1.1)
150
156
  nio4r (2.5.8)
151
- nokogiri (1.13.1)
152
- mini_portile2 (~> 2.7.0)
157
+ nokogiri (1.13.6)
158
+ mini_portile2 (~> 2.8.0)
153
159
  racc (~> 1.4)
154
160
  oauth (0.5.8)
155
161
  octokit (4.22.0)
@@ -157,8 +163,10 @@ GEM
157
163
  sawyer (~> 0.8.0, >= 0.5.3)
158
164
  os (1.1.4)
159
165
  parallel (1.21.0)
160
- parser (3.1.0.0)
166
+ parser (3.1.1.0)
161
167
  ast (~> 2.4.1)
168
+ protocol (2.0.0)
169
+ ruby_parser (~> 3.0)
162
170
  protocol-hpack (1.4.2)
163
171
  protocol-http (0.22.5)
164
172
  protocol-http1 (0.14.2)
@@ -170,7 +178,7 @@ GEM
170
178
  coderay (~> 1.1)
171
179
  method_source (~> 1.0)
172
180
  public_suffix (4.0.6)
173
- puppet (7.13.1)
181
+ puppet (7.16.0)
174
182
  concurrent-ruby (~> 1.0)
175
183
  deep_merge (~> 1.0)
176
184
  facter (> 2.0.1, < 5)
@@ -186,46 +194,48 @@ GEM
186
194
  racc (1.6.0)
187
195
  rainbow (3.1.1)
188
196
  rake (13.0.6)
189
- regexp_parser (2.2.0)
197
+ regexp_parser (2.2.1)
190
198
  representable (3.1.1)
191
199
  declarative (< 0.1.0)
192
200
  trailblazer-option (>= 0.1.1, < 0.2.0)
193
201
  uber (< 0.2.0)
194
202
  retriable (3.1.2)
195
203
  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)
204
+ rspec (3.11.0)
205
+ rspec-core (~> 3.11.0)
206
+ rspec-expectations (~> 3.11.0)
207
+ rspec-mocks (~> 3.11.0)
208
+ rspec-core (3.11.0)
209
+ rspec-support (~> 3.11.0)
210
+ rspec-expectations (3.11.0)
203
211
  diff-lcs (>= 1.2.0, < 2.0)
204
- rspec-support (~> 3.10.0)
205
- rspec-mocks (3.10.2)
212
+ rspec-support (~> 3.11.0)
213
+ rspec-mocks (3.11.0)
206
214
  diff-lcs (>= 1.2.0, < 2.0)
207
- rspec-support (~> 3.10.0)
208
- rspec-support (3.10.3)
209
- rubocop (1.24.1)
215
+ rspec-support (~> 3.11.0)
216
+ rspec-support (3.11.0)
217
+ rubocop (1.25.1)
210
218
  parallel (~> 1.10)
211
- parser (>= 3.0.0.0)
219
+ parser (>= 3.1.0.0)
212
220
  rainbow (>= 2.2.2, < 4.0)
213
221
  regexp_parser (>= 1.8, < 3.0)
214
222
  rexml
215
223
  rubocop-ast (>= 1.15.1, < 2.0)
216
224
  ruby-progressbar (~> 1.7)
217
225
  unicode-display_width (>= 1.4.0, < 3.0)
218
- rubocop-ast (1.15.1)
219
- parser (>= 3.0.1.1)
226
+ rubocop-ast (1.16.0)
227
+ parser (>= 3.1.1.0)
220
228
  rubocop-i18n (3.0.0)
221
229
  rubocop (~> 1.0)
222
- rubocop-performance (1.13.1)
230
+ rubocop-performance (1.13.2)
223
231
  rubocop (>= 1.7.0, < 2.0)
224
232
  rubocop-ast (>= 0.4.0)
225
- rubocop-rspec (2.7.0)
233
+ rubocop-rspec (2.9.0)
226
234
  rubocop (~> 1.19)
227
235
  ruby-progressbar (1.11.0)
228
236
  ruby2_keywords (0.0.5)
237
+ ruby_parser (3.19.1)
238
+ sexp_processor (~> 4.16)
229
239
  rubyzip (2.3.2)
230
240
  sawyer (0.8.2)
231
241
  addressable (>= 2.3.5)
@@ -236,13 +246,17 @@ GEM
236
246
  rexml (~> 3.2, >= 3.2.5)
237
247
  rubyzip (>= 1.2.2)
238
248
  semantic_puppet (1.0.4)
239
- signet (0.16.0)
249
+ sexp_processor (4.16.1)
250
+ signet (0.16.1)
240
251
  addressable (~> 2.8)
241
- faraday (>= 0.17.3, < 2.0)
252
+ faraday (>= 0.17.5, < 3.0)
242
253
  jwt (>= 1.5, < 3.0)
243
254
  multi_json (~> 1.10)
255
+ sync (0.5.0)
244
256
  thor (1.2.1)
245
257
  timers (4.3.3)
258
+ tins (1.31.0)
259
+ sync
246
260
  trailblazer-option (0.1.2)
247
261
  tzinfo (2.0.4)
248
262
  concurrent-ruby (~> 1.0)
@@ -35,11 +35,12 @@ Gem::Specification.new do |spec|
35
35
  spec.add_dependency 'nokogiri', '~> 1.11'
36
36
  spec.add_dependency 'cmdparse', '~> 3.0'
37
37
  spec.add_dependency 'puppet', '>= 6.23'
38
- spec.add_dependency 'jira-ruby', '~> 2.1'
38
+ spec.add_dependency 'jira-ruby', '~> 2.2'
39
39
  spec.add_dependency 'ruby-progressbar', '~> 1.11'
40
40
  spec.add_dependency 'selenium-webdriver', '~> 4.0.0.beta4'
41
41
  spec.add_dependency 'google-cloud-storage', '~> 1.34'
42
42
  spec.add_dependency 'hashdiff', '~> 1.0'
43
+ spec.add_dependency 'amatch', '~> 0.4'
43
44
 
44
45
  # Dev dependencies
45
46
  spec.add_development_dependency 'bundler'
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'abide_dev_utils/xccdf'
4
+
5
+ module AbideDevUtils
6
+ # Methods for working with Compliance Enforcement Modules (CEM)
7
+ module CEM
8
+ def self.xccdf
9
+ return @xccdf if defined?(@xccdf)
10
+
11
+ xccdf = Object.new
12
+ xccdf.extend AbideDevUtils::XCCDF::Common
13
+ @xccdf = xccdf
14
+ @xccdf
15
+ end
16
+
17
+ def self.rule_id_format(rule_id)
18
+ case rule_id
19
+ when /^c[0-9_]+$/
20
+ :hiera_title_num
21
+ when /^[a-z][a-z0-9_]+$/
22
+ :hiera_title
23
+ when /^[0-9.]+$/
24
+ :number
25
+ else
26
+ :title
27
+ end
28
+ end
29
+
30
+ def self.rule_identifiers(rule_id)
31
+ {
32
+ number: xccdf.control_parts(rule_id).first,
33
+ hiera_title: xccdf.name_normalize_control(rule_id),
34
+ hiera_title_num: xccdf.number_normalize_control(rule_id),
35
+ }
36
+ end
37
+
38
+ def self.update_legacy_config_from_diff(config_hiera, diff)
39
+ new_config_hiera = config_hiera.dup
40
+ new_control_configs = {}
41
+ change_report = []
42
+ changes = diff.select { |d| d[:type][0] == :number }
43
+ config_hiera['config']['control_configs'].each do |key, val_hash|
44
+ key_id_format = rule_id_format(key)
45
+ changed = false
46
+ changes.each do |change|
47
+ if key_id_format == :title
48
+ next unless change[:title] == key
49
+ else
50
+ next unless rule_identifiers(change[:self].id)[key_id_format] == key
51
+ end
52
+
53
+ changed = true
54
+ new_key = if key_id_format == :title
55
+ change[:other_title]
56
+ else
57
+ rule_identifiers(change[:other].id)[key_id_format]
58
+ end
59
+ new_control_configs[new_key] = val_hash
60
+ change_report << {
61
+ type: :identifier_update,
62
+ from: key,
63
+ to: new_key,
64
+ }
65
+ end
66
+ new_control_configs[key] = val_hash unless changed
67
+ end
68
+ new_config_hiera['config']['control_configs'] = new_control_configs
69
+ [new_config_hiera, change_report]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'abide_dev_utils/cem'
4
+ require 'abide_dev_utils/files'
5
+ require 'abide_dev_utils/output'
6
+ require 'abide_dev_utils/validate'
7
+ require 'abide_dev_utils/xccdf/diff/benchmark'
8
+ require 'abide_dev_utils/cli/abstract'
9
+
10
+ module Abide
11
+ module CLI
12
+ class CemCommand < AbideCommand
13
+ CMD_NAME = 'cem'
14
+ CMD_SHORT = 'Commands related to Puppet CEM'
15
+ CMD_LONG = 'Namespace for commands related to Puppet CEM'
16
+ def initialize
17
+ super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: true)
18
+ add_command(CemUpdateConfig.new)
19
+ end
20
+ end
21
+
22
+ class CemUpdateConfig < AbideCommand
23
+ CMD_NAME = 'update-config'
24
+ CMD_SHORT = 'Updates the Puppet CEM config'
25
+ CMD_LONG = 'Updates the Puppet CEM config'
26
+ def initialize
27
+ super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: true)
28
+ add_command(CemUpdateConfigFromDiff.new)
29
+ end
30
+ end
31
+
32
+ class CemUpdateConfigFromDiff < AbideCommand
33
+ CMD_NAME = 'from-diff'
34
+ CMD_SHORT = 'Update by diffing two XCCDF files'
35
+ CMD_LONG = 'Update by diffing two XCCDF files'
36
+ CMD_CONFIG_FILE = 'Path to the Puppet CEM config file'
37
+ CMD_CURRENT_XCCDF = 'Path to the current XCCDF file'
38
+ CMD_NEW_XCCDF = 'Path to the new XCCDF file'
39
+ def initialize
40
+ super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: false)
41
+ argument_desc(CONFIG_FILE: CMD_CONFIG_FILE, CURRENT_XCCDF: CMD_CURRENT_XCCDF, NEW_XCCDF: CMD_NEW_XCCDF)
42
+ options.on('-o [FILE]', '--out-file [FILE]', 'Path to save the updated config file') do |o|
43
+ @data[:out_file] = o
44
+ end
45
+ options.on('-v', '--verbose', 'Verbose output') do
46
+ @data[:verbose] = true
47
+ end
48
+ options.on('-q', '--quiet', 'Quiet output') do
49
+ @data[:quiet] = true
50
+ end
51
+ end
52
+
53
+ def help_arguments
54
+ <<~ARGHELP
55
+ Arguments:
56
+ CONFIG_FILE: #{CMD_CONFIG_FILE}
57
+ CURRENT_XCCDF: #{CMD_CURRENT_XCCDF}
58
+ NEW_XCCDF: #{CMD_NEW_XCCDF}
59
+ ARGHELP
60
+ end
61
+
62
+ def execute(config_file, cur_xccdf, new_xccdf)
63
+ AbideDevUtils::Validate.file(config_file, extension: 'yaml')
64
+ AbideDevUtils::Validate.file(cur_xccdf, extension: 'xml')
65
+ config_hiera = AbideDevUtils::Files::Reader.read(config_file, safe: true)
66
+ diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(cur_xccdf, new_xccdf).diff[:diff][:number_title]
67
+ new_config_hiera, change_report = AbideDevUtils::CEM.update_legacy_config_from_diff(config_hiera, diff)
68
+ AbideDevUtils::Output.yaml(new_config_hiera, console: @data[:verbose], file: @data[:out_file])
69
+ AbideDevUtils::Output.simple(change_report) unless @data[:quiet]
70
+ end
71
+ end
72
+ end
73
+ end
@@ -104,13 +104,24 @@ module Abide
104
104
  options.on('-p [PROFILE]', '--profile', 'Only diff and specific profile in the benchmarks') do |x|
105
105
  @data[:profile] = x
106
106
  end
107
+ options.on('-l [LEVEL]', '--level', 'Only diff the specific level in the benchmarks') do |x|
108
+ @data[:level] = x
109
+ end
110
+ options.on('-r', '--raw', 'Output the diff in raw hash format') { @data[:raw] = true }
107
111
  options.on('-q', '--quiet', 'Show no output in the terminal') { @data[:quiet] = false }
108
112
  options.on('--no-diff-profiles', 'Do not diff the profiles in the XCCDF files') { @data[:diff_profiles] = false }
109
113
  options.on('--no-diff-controls', 'Do not diff the controls in the XCCDF files') { @data[:diff_controls] = false }
114
+ options.on('--old-style', 'Use old-style diffs') { @data[:old_style] = true }
110
115
  end
111
116
 
112
117
  def execute(file1, file2)
113
- diffreport = AbideDevUtils::XCCDF.diff(file1, file2, @data)
118
+ diffreport = if @data[:old_style]
119
+ AbideDevUtils::XCCDF.diff(file1, file2, @data)
120
+ else
121
+ dr = AbideDevUtils::XCCDF.new_style_diff(file1, file2, @data)
122
+ dr[:diff][:number_title].map! { |d| d[:text] }
123
+ dr
124
+ end
114
125
  AbideDevUtils::Output.yaml(diffreport, console: @data.fetch(:quiet, true), file: @data.fetch(:outfile, nil))
115
126
  end
116
127
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'cmdparse'
4
4
  require 'abide_dev_utils/version'
5
+ require 'abide_dev_utils/cli/cem'
5
6
  require 'abide_dev_utils/constants'
6
7
  require 'abide_dev_utils/cli/comply'
7
8
  require 'abide_dev_utils/cli/puppet'
@@ -22,6 +23,7 @@ module Abide
22
23
  parser.main_options.banner = ROOT_CMD_BANNER
23
24
  parser.add_command(CmdParse::HelpCommand.new, default: true)
24
25
  parser.add_command(CmdParse::VersionCommand.new(add_switches: true))
26
+ parser.add_command(CemCommand.new)
25
27
  parser.add_command(ComplyCommand.new)
26
28
  parser.add_command(PuppetCommand.new)
27
29
  parser.add_command(XccdfCommand.new)
@@ -1,7 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'abide_dev_utils/validate'
4
+
3
5
  module AbideDevUtils
4
6
  module Files
7
+ class Reader
8
+ def self.read(path, raw: false, safe: true, opts: {})
9
+ AbideDevUtils::Validate.file(path)
10
+ return File.read(path) if raw
11
+
12
+ extension = File.extname(path)
13
+ case extension
14
+ when /\.yaml|\.yml/
15
+ require 'yaml'
16
+ if safe
17
+ YAML.safe_load(File.read(path))
18
+ else
19
+ YAML.load_file(path)
20
+ end
21
+ when '.json'
22
+ require 'json'
23
+ return JSON.parse(File.read(path), opts) if safe
24
+
25
+ JSON.parse!(File.read(path), opts)
26
+ when '.xml'
27
+ require 'nokogiri'
28
+ File.open(path, 'r') do |file|
29
+ Nokogiri::XML.parse(file) do |config|
30
+ config.strict.noblanks.norecover
31
+ end
32
+ end
33
+ else
34
+ File.read(path)
35
+ end
36
+ end
37
+ end
38
+
5
39
  class Writer
6
40
  MSG_EXT_APPEND = 'Appending %s extension to file'
7
41
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.9.4"
4
+ VERSION = "0.10.0"
5
5
  end