abide_dev_utils 0.9.7 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []