abide_dev_utils 0.9.7 → 0.10.0

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.
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'abide_dev_utils/files'
4
+ require 'abide_dev_utils/xccdf/parser/objects'
5
+
6
+ module AbideDevUtils
7
+ module XCCDF
8
+ # Contains methods and classes for parsing XCCDF files,
9
+ module Parser
10
+ def self.parse(file_path)
11
+ doc = AbideDevUtils::Files::Reader.read(file_path)
12
+ benchmark = AbideDevUtils::XCCDF::Parser::Objects::Benchmark.new(doc)
13
+ Linker.resolve_links(benchmark)
14
+ benchmark
15
+ end
16
+
17
+ # Links XCCDF objects by reference.
18
+ # Each link is resolved and then a bidirectional link is established
19
+ # between the two objects.
20
+ module Linker
21
+ def self.resolve_links(benchmark)
22
+ link_profile_rules(benchmark)
23
+ link_rule_values(benchmark)
24
+ end
25
+
26
+ def self.link_profile_rules(benchmark)
27
+ rules = benchmark.find_children_by_class(AbideDevUtils::XCCDF::Parser::Objects::Rule, recurse: true)
28
+ benchmark.profile.each do |profile|
29
+ profile.xccdf_select.each do |sel|
30
+ rules.select { |rule| rule.id == sel.idref }.each do |rule|
31
+ rule.add_link(profile)
32
+ profile.add_link(rule)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def self.link_rule_values(benchmark)
39
+ rules = benchmark.find_children_by_class(AbideDevUtils::XCCDF::Parser::Objects::Rule, recurse: true)
40
+ benchmark.value.each do |value|
41
+ rules.each do |rule|
42
+ unless rule.find_children_by_attribute_value('value-id', value.id, recurse: true).empty?
43
+ rule.add_link(value)
44
+ value.add_link(rule)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -34,21 +34,17 @@ module AbideDevUtils
34
34
 
35
35
  # Diffs two xccdf files
36
36
  def self.diff(file1, file2, opts)
37
+ require 'abide_dev_utils/xccdf/diff'
37
38
  bm1 = Benchmark.new(file1)
38
39
  bm2 = Benchmark.new(file2)
39
- profile = opts.fetch(:profile, nil)
40
- profile_diff = if profile.nil?
41
- bm1.diff_profiles(bm2).each do |_, v|
42
- v.transform_values! { |x| x.map!(&:to_s) }
43
- end
44
- else
45
- bm1.diff_profiles(bm2)[profile].transform_values! { |x| x.map!(&:to_s) }
46
- end
47
- profile_key = profile.nil? ? 'all_profiles' : profile
48
- {
49
- 'benchmark' => bm1.diff_title_version(bm2),
50
- profile_key => profile_diff
51
- }
40
+ AbideDevUtils::XCCDF::Diff.diff_benchmarks(bm1, bm2, opts)
41
+ end
42
+
43
+ # Use new-style diff
44
+ def self.new_style_diff(file1, file2, opts)
45
+ require 'abide_dev_utils/xccdf/diff/benchmark'
46
+ bm_diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(file1, file2, opts)
47
+ bm_diff.diff
52
48
  end
53
49
 
54
50
  # Common constants and methods included by nearly everything else
@@ -164,25 +160,6 @@ module AbideDevUtils
164
160
  diff_properties.map { |x| send(x) } == other.diff_properties.map { |x| other.send(x) }
165
161
  end
166
162
 
167
- def default_diff_opts
168
- {
169
- similarity: 1,
170
- strict: true,
171
- strip: true,
172
- array_path: true,
173
- delimiter: '//',
174
- use_lcs: false
175
- }
176
- end
177
-
178
- def diff(other, **opts)
179
- Hashdiff.diff(
180
- to_h,
181
- other.to_h,
182
- default_diff_opts.merge(opts)
183
- )
184
- end
185
-
186
163
  def abide_object?
187
164
  true
188
165
  end
@@ -257,33 +234,6 @@ module AbideDevUtils
257
234
  }
258
235
  end
259
236
 
260
- def diff_title_version(other)
261
- Hashdiff.diff(
262
- to_h.reject { |k, _| k.to_s == 'profiles' },
263
- other.to_h.reject { |k, _| k.to_s == 'profiles' },
264
- default_diff_opts
265
- )
266
- end
267
-
268
- def diff_profiles(other)
269
- this_diff = {}
270
- other_hash = other.to_h[:profiles]
271
- to_h[:profiles].each do |name, data|
272
- diff_h = Hashdiff.diff(data, other_hash[name], default_diff_opts).each_with_object({}) do |x, a|
273
- val_to = x.length == 4 ? x[3] : nil
274
- a_key = x[2].is_a?(Hash) ? x[2][:title] : x[2]
275
- a[a_key] = [] unless a.key?(a_key)
276
- a[a_key] << ChangeSet.new(change: x[0], key: x[1], value: x[2], value_to: val_to)
277
- end
278
- this_diff[name] = diff_h
279
- end
280
- this_diff
281
- end
282
-
283
- def diff_controls(other)
284
- controls.diff(other.controls)
285
- end
286
-
287
237
  def map_indexed(index: 'title', framework: 'cis', key_prefix: '')
288
238
  c_map = profiles.each_with_object({}) do |profile, obj|
289
239
  obj[profile.level.downcase] = {} unless obj[profile.level.downcase].is_a?(Hash)
@@ -396,69 +346,6 @@ module AbideDevUtils
396
346
  end
397
347
  end
398
348
 
399
- class ChangeSet
400
- attr_reader :change, :key, :value, :value_to
401
-
402
- def initialize(change:, key:, value:, value_to: nil)
403
- validate_change(change)
404
- @change = change
405
- @key = key
406
- @value = value
407
- @value_to = value_to
408
- end
409
-
410
- def to_s
411
- val_to_str = value_to.nil? ? ' ' : " to #{value_to} "
412
- "#{change_string} value #{value}#{val_to_str}at #{key}"
413
- end
414
-
415
- def can_merge?(other)
416
- return false unless (change == '-' && other.change == '+') || (change == '+' && other.change == '-')
417
- return false unless key == other.key || value_hash_equality(other)
418
-
419
- true
420
- end
421
-
422
- def merge(other)
423
- unless can_merge?(other)
424
- raise ArgumentError, 'Cannot merge. Possible causes: change is identical; key or value do not match'
425
- end
426
-
427
- new_to_value = value == other.value ? nil : other.value
428
- ChangeSet.new(
429
- change: '~',
430
- key: key,
431
- value: value,
432
- value_to: new_to_value
433
- )
434
- end
435
-
436
- private
437
-
438
- def value_hash_equality(other)
439
- equality = false
440
- value.each do |k, v|
441
- equality = true if v == other.value[k]
442
- end
443
- equality
444
- end
445
-
446
- def validate_change(change)
447
- raise ArgumentError, "Change type #{change} in invalid" unless ['+', '-', '~'].include?(change)
448
- end
449
-
450
- def change_string
451
- case change
452
- when '-'
453
- 'remove'
454
- when '+'
455
- 'add'
456
- else
457
- 'change'
458
- end
459
- end
460
- end
461
-
462
349
  class ObjectContainer
463
350
  include AbideDevUtils::XCCDF::Common
464
351
 
data/new_diff.rb ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'yaml'
5
+ require 'pry'
6
+ require 'abide_dev_utils/xccdf/diff/benchmark'
7
+
8
+ xml_file1 = File.expand_path(ARGV[0])
9
+ xml_file2 = File.expand_path(ARGV[1])
10
+ legacy_config = ARGV.length > 2 ? YAML.load_file(File.expand_path(ARGV[2])) : nil
11
+
12
+ def convert_legacy_config(config, num_title_diff, key_format: :hiera_num)
13
+ nt_diff = num_title_diff.diff(key: :number)
14
+ updated_config = config['config']['control_configs'].each_with_object({}) do |(key, value), h|
15
+ next if value.nil?
16
+
17
+ diff_key = key.to_s.gsub(/^c/, '').tr('_', '.') if key_format == :hiera_num
18
+ if nt_diff.key?(diff_key)
19
+ if nt_diff[diff_key][0][:diff] == :number
20
+ new_key = "c#{nt_diff[diff_key][0][:other_number].to_s.tr('.', '_')}"
21
+ h[new_key] = value
22
+ puts "Converted #{key} to #{new_key}"
23
+ elsif nt_diff[diff_key][0][:diff] == :title
24
+
25
+ h[key] = value
26
+ end
27
+ else
28
+ h[key] = value
29
+ end
30
+ end
31
+ { 'config' => { 'control_configs' => updated_config } }.to_yaml
32
+ end
33
+
34
+ start_time = Time.now
35
+
36
+ bm_diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(xml_file1, xml_file2)
37
+ self_nc_count, other_nc_count = bm_diff.numbered_children_counts
38
+ puts "Benchmark numbered children count: #{self_nc_count}"
39
+ puts "Other benchmark numbered children count: #{other_nc_count}"
40
+ puts "Rule count difference: #{bm_diff.numbered_children_count_diff}"
41
+ num_diff = bm_diff.number_title_diff
42
+ binding.pry if legacy_config.nil?
43
+ File.open('/tmp/legacy_converted.yaml', 'w') do |f|
44
+ converted = convert_legacy_config(legacy_config, num_diff)
45
+ f.write(converted)
46
+ end
47
+
48
+ puts "Computation time: #{Time.now - start_time}"
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.9.7
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-02 00:00:00.000000000 Z
11
+ date: 2022-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: amatch
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.4'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.4'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: bundler
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -330,8 +344,10 @@ files:
330
344
  - bin/setup
331
345
  - exe/abide
332
346
  - lib/abide_dev_utils.rb
347
+ - lib/abide_dev_utils/cem.rb
333
348
  - lib/abide_dev_utils/cli.rb
334
349
  - lib/abide_dev_utils/cli/abstract.rb
350
+ - lib/abide_dev_utils/cli/cem.rb
335
351
  - lib/abide_dev_utils/cli/comply.rb
336
352
  - lib/abide_dev_utils/cli/jira.rb
337
353
  - lib/abide_dev_utils/cli/puppet.rb
@@ -364,6 +380,18 @@ files:
364
380
  - lib/abide_dev_utils/validate.rb
365
381
  - lib/abide_dev_utils/version.rb
366
382
  - lib/abide_dev_utils/xccdf.rb
383
+ - lib/abide_dev_utils/xccdf/diff.rb
384
+ - lib/abide_dev_utils/xccdf/diff/benchmark.rb
385
+ - lib/abide_dev_utils/xccdf/diff/benchmark/number_title.rb
386
+ - lib/abide_dev_utils/xccdf/diff/benchmark/profile.rb
387
+ - lib/abide_dev_utils/xccdf/diff/benchmark/property.rb
388
+ - lib/abide_dev_utils/xccdf/diff/benchmark/property_existence.rb
389
+ - lib/abide_dev_utils/xccdf/diff/utils.rb
390
+ - lib/abide_dev_utils/xccdf/parser.rb
391
+ - lib/abide_dev_utils/xccdf/parser/objects.rb
392
+ - lib/abide_dev_utils/xccdf/parser/objects/digest_object.rb
393
+ - lib/abide_dev_utils/xccdf/parser/objects/numbered_object.rb
394
+ - new_diff.rb
367
395
  homepage: https://github.com/puppetlabs/abide_dev_utils
368
396
  licenses:
369
397
  - MIT
@@ -371,7 +399,7 @@ metadata:
371
399
  homepage_uri: https://github.com/puppetlabs/abide_dev_utils
372
400
  source_code_uri: https://github.com/puppetlabs/abide_dev_utils
373
401
  changelog_uri: https://github.com/puppetlabs/abide_dev_utils
374
- post_install_message:
402
+ post_install_message:
375
403
  rdoc_options: []
376
404
  require_paths:
377
405
  - lib
@@ -386,8 +414,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
386
414
  - !ruby/object:Gem::Version
387
415
  version: '0'
388
416
  requirements: []
389
- rubygems_version: 3.1.6
390
- signing_key:
417
+ rubygems_version: 3.1.4
418
+ signing_key:
391
419
  specification_version: 4
392
420
  summary: Helper utilities for developing compliance Puppet code
393
421
  test_files: []