abide_dev_utils 0.10.1 → 0.11.2

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +7 -1
  4. data/Gemfile.lock +25 -19
  5. data/Rakefile +28 -0
  6. data/abide_dev_utils.gemspec +1 -0
  7. data/lib/abide_dev_utils/cem/benchmark.rb +490 -0
  8. data/lib/abide_dev_utils/cem/generate/coverage_report.rb +380 -0
  9. data/lib/abide_dev_utils/cem/generate/reference.rb +319 -0
  10. data/lib/abide_dev_utils/cem/generate.rb +11 -0
  11. data/lib/abide_dev_utils/cem/hiera_data/mapping_data/map_data.rb +110 -0
  12. data/lib/abide_dev_utils/cem/hiera_data/mapping_data/mixins.rb +46 -0
  13. data/lib/abide_dev_utils/cem/hiera_data/mapping_data.rb +146 -0
  14. data/lib/abide_dev_utils/cem/hiera_data/resource_data/control.rb +127 -0
  15. data/lib/abide_dev_utils/cem/hiera_data/resource_data/parameters.rb +90 -0
  16. data/lib/abide_dev_utils/cem/hiera_data/resource_data/resource.rb +102 -0
  17. data/lib/abide_dev_utils/cem/hiera_data/resource_data.rb +310 -0
  18. data/lib/abide_dev_utils/cem/hiera_data.rb +7 -0
  19. data/lib/abide_dev_utils/cem/mapping/mapper.rb +282 -0
  20. data/lib/abide_dev_utils/cem/validate/resource_data.rb +33 -0
  21. data/lib/abide_dev_utils/cem/validate.rb +10 -0
  22. data/lib/abide_dev_utils/cem.rb +1 -0
  23. data/lib/abide_dev_utils/cli/cem.rb +98 -0
  24. data/lib/abide_dev_utils/dot_number_comparable.rb +75 -0
  25. data/lib/abide_dev_utils/errors/cem.rb +32 -0
  26. data/lib/abide_dev_utils/errors/general.rb +8 -2
  27. data/lib/abide_dev_utils/errors/ppt.rb +4 -0
  28. data/lib/abide_dev_utils/errors.rb +6 -0
  29. data/lib/abide_dev_utils/markdown.rb +104 -0
  30. data/lib/abide_dev_utils/ppt/class_utils.rb +1 -1
  31. data/lib/abide_dev_utils/ppt/code_gen/data_types.rb +64 -0
  32. data/lib/abide_dev_utils/ppt/code_gen/generate.rb +15 -0
  33. data/lib/abide_dev_utils/ppt/code_gen/resource.rb +59 -0
  34. data/lib/abide_dev_utils/ppt/code_gen/resource_types/base.rb +93 -0
  35. data/lib/abide_dev_utils/ppt/code_gen/resource_types/class.rb +17 -0
  36. data/lib/abide_dev_utils/ppt/code_gen/resource_types/manifest.rb +16 -0
  37. data/lib/abide_dev_utils/ppt/code_gen/resource_types/parameter.rb +16 -0
  38. data/lib/abide_dev_utils/ppt/code_gen/resource_types/strings.rb +13 -0
  39. data/lib/abide_dev_utils/ppt/code_gen/resource_types.rb +6 -0
  40. data/lib/abide_dev_utils/ppt/code_gen.rb +15 -0
  41. data/lib/abide_dev_utils/ppt/code_introspection.rb +102 -0
  42. data/lib/abide_dev_utils/ppt/facter_utils.rb +140 -0
  43. data/lib/abide_dev_utils/ppt/hiera.rb +300 -0
  44. data/lib/abide_dev_utils/ppt/puppet_module.rb +75 -0
  45. data/lib/abide_dev_utils/ppt.rb +6 -5
  46. data/lib/abide_dev_utils/validate.rb +14 -0
  47. data/lib/abide_dev_utils/version.rb +1 -1
  48. data/lib/abide_dev_utils/xccdf/parser/helpers.rb +146 -0
  49. data/lib/abide_dev_utils/xccdf/parser/objects.rb +87 -144
  50. data/lib/abide_dev_utils/xccdf/parser.rb +5 -0
  51. data/lib/abide_dev_utils/xccdf/utils.rb +89 -0
  52. data/lib/abide_dev_utils/xccdf.rb +3 -0
  53. metadata +50 -3
  54. data/lib/abide_dev_utils/ppt/coverage.rb +0 -86
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'abide_dev_utils/validate'
4
+
5
+ module AbideDevUtils
6
+ module XCCDF
7
+ module Utils
8
+ # Class for working with directories that contain XCCDF files
9
+ class FileDir
10
+ CIS_FILE_NAME_PARTS_PATTERN = /^CIS_(?<subject>[A-Za-z0-9._()-]+)_Benchmark_v(?<version>[0-9.]+)-xccdf$/.freeze
11
+ def initialize(path)
12
+ @path = File.expand_path(path)
13
+ AbideDevUtils::Validate.directory(@path)
14
+ end
15
+
16
+ def files
17
+ @files ||= Dir.glob(File.join(@path, '*-xccdf.xml')).map { |f| FileNameData.new(f) }
18
+ end
19
+
20
+ def fuzzy_find(label, value)
21
+ files.find { |f| f.fuzzy_match?(label, value) }
22
+ end
23
+
24
+ def fuzzy_select(label, value)
25
+ files.select { |f| f.fuzzy_match?(label, value) }
26
+ end
27
+
28
+ def fuzzy_reject(label, value)
29
+ files.reject { |f| f.fuzzy_match?(label, value) }
30
+ end
31
+
32
+ def label?(label)
33
+ files.select { |f| f.has?(label) }
34
+ end
35
+
36
+ def no_label?(label)
37
+ files.reject { |f| f.has?(label) }
38
+ end
39
+ end
40
+
41
+ # Parses XCCDF file names into labeled parts
42
+ class FileNameData
43
+ CIS_PATTERN = /^CIS_(?<subject>[A-Za-z0-9._()-]+?)(?<stig>_STIG)?_Benchmark_v(?<version>[0-9.]+)-xccdf$/.freeze
44
+
45
+ attr_reader :path, :name, :labeled_parts
46
+
47
+ def initialize(path)
48
+ @path = path
49
+ @name = File.basename(path, '.xml')
50
+ @labeled_parts = File.basename(name, '.xml').match(CIS_PATTERN)&.named_captures
51
+ end
52
+
53
+ def subject
54
+ @subject ||= labeled_parts&.fetch('subject', nil)
55
+ end
56
+
57
+ def stig
58
+ @stig ||= labeled_parts&.fetch('subject', nil)
59
+ end
60
+
61
+ def version
62
+ @version ||= labeled_parts&.fetch('version', nil)
63
+ end
64
+
65
+ def has?(label)
66
+ val = send(label.to_sym)
67
+ !val.nil? && !val.empty?
68
+ end
69
+
70
+ def fuzzy_match?(label, value)
71
+ return false unless has?(label)
72
+
73
+ this_val = normalize_char_array(send(label.to_sym).chars)
74
+ other_val = normalize_char_array(value.chars)
75
+ other_val.each_with_index do |c, idx|
76
+ return false unless this_val[idx] == c
77
+ end
78
+ true
79
+ end
80
+
81
+ private
82
+
83
+ def normalize_char_array(char_array)
84
+ char_array.grep_v(/[^A-Za-z0-9]/).map(&:downcase)[3..]
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -70,6 +70,7 @@ module AbideDevUtils
70
70
  CIS_LEVEL_CODE = /(?:_|^)([Ll]evel_[0-9]|[Ll]1|[Ll]2|[NnBb][GgLl]|#{CIS_NEXT_GEN_WINDOWS})/.freeze
71
71
  CIS_CONTROL_PARTS = /#{CIS_CONTROL_NUMBER}#{CIS_LEVEL_CODE}?_+([A-Za-z].*)/.freeze
72
72
  CIS_PROFILE_PARTS = /#{CIS_LEVEL_CODE}[_-]+([A-Za-z].*)/.freeze
73
+ STIG_PROFILE_PARTS = /(STIG)/.freeze
73
74
 
74
75
  def xpath(path)
75
76
  @xml.xpath(path)
@@ -119,6 +120,8 @@ module AbideDevUtils
119
120
  end
120
121
 
121
122
  def profile_parts(profile)
123
+ return ['STIG', ''] if profile == 'STIG'
124
+
122
125
  parts = control_profile_text(profile).match(CIS_PROFILE_PARTS)
123
126
  raise AbideDevUtils::Errors::ProfilePartsError, profile if parts.nil?
124
127
 
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.10.1
4
+ version: 0.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-02 00:00:00.000000000 Z
11
+ date: 2022-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0.4'
139
+ - !ruby/object:Gem::Dependency
140
+ name: facterdb
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '1.18'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '1.18'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: bundler
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -345,6 +359,21 @@ files:
345
359
  - exe/abide
346
360
  - lib/abide_dev_utils.rb
347
361
  - lib/abide_dev_utils/cem.rb
362
+ - lib/abide_dev_utils/cem/benchmark.rb
363
+ - lib/abide_dev_utils/cem/generate.rb
364
+ - lib/abide_dev_utils/cem/generate/coverage_report.rb
365
+ - lib/abide_dev_utils/cem/generate/reference.rb
366
+ - lib/abide_dev_utils/cem/hiera_data.rb
367
+ - lib/abide_dev_utils/cem/hiera_data/mapping_data.rb
368
+ - lib/abide_dev_utils/cem/hiera_data/mapping_data/map_data.rb
369
+ - lib/abide_dev_utils/cem/hiera_data/mapping_data/mixins.rb
370
+ - lib/abide_dev_utils/cem/hiera_data/resource_data.rb
371
+ - lib/abide_dev_utils/cem/hiera_data/resource_data/control.rb
372
+ - lib/abide_dev_utils/cem/hiera_data/resource_data/parameters.rb
373
+ - lib/abide_dev_utils/cem/hiera_data/resource_data/resource.rb
374
+ - lib/abide_dev_utils/cem/mapping/mapper.rb
375
+ - lib/abide_dev_utils/cem/validate.rb
376
+ - lib/abide_dev_utils/cem/validate/resource_data.rb
348
377
  - lib/abide_dev_utils/cli.rb
349
378
  - lib/abide_dev_utils/cli/abstract.rb
350
379
  - lib/abide_dev_utils/cli/cem.rb
@@ -356,8 +385,10 @@ files:
356
385
  - lib/abide_dev_utils/comply.rb
357
386
  - lib/abide_dev_utils/config.rb
358
387
  - lib/abide_dev_utils/constants.rb
388
+ - lib/abide_dev_utils/dot_number_comparable.rb
359
389
  - lib/abide_dev_utils/errors.rb
360
390
  - lib/abide_dev_utils/errors/base.rb
391
+ - lib/abide_dev_utils/errors/cem.rb
361
392
  - lib/abide_dev_utils/errors/comply.rb
362
393
  - lib/abide_dev_utils/errors/gcloud.rb
363
394
  - lib/abide_dev_utils/errors/general.rb
@@ -367,13 +398,27 @@ files:
367
398
  - lib/abide_dev_utils/files.rb
368
399
  - lib/abide_dev_utils/gcloud.rb
369
400
  - lib/abide_dev_utils/jira.rb
401
+ - lib/abide_dev_utils/markdown.rb
370
402
  - lib/abide_dev_utils/mixins.rb
371
403
  - lib/abide_dev_utils/output.rb
372
404
  - lib/abide_dev_utils/ppt.rb
373
405
  - lib/abide_dev_utils/ppt/api.rb
374
406
  - lib/abide_dev_utils/ppt/class_utils.rb
375
- - lib/abide_dev_utils/ppt/coverage.rb
407
+ - lib/abide_dev_utils/ppt/code_gen.rb
408
+ - lib/abide_dev_utils/ppt/code_gen/data_types.rb
409
+ - lib/abide_dev_utils/ppt/code_gen/generate.rb
410
+ - lib/abide_dev_utils/ppt/code_gen/resource.rb
411
+ - lib/abide_dev_utils/ppt/code_gen/resource_types.rb
412
+ - lib/abide_dev_utils/ppt/code_gen/resource_types/base.rb
413
+ - lib/abide_dev_utils/ppt/code_gen/resource_types/class.rb
414
+ - lib/abide_dev_utils/ppt/code_gen/resource_types/manifest.rb
415
+ - lib/abide_dev_utils/ppt/code_gen/resource_types/parameter.rb
416
+ - lib/abide_dev_utils/ppt/code_gen/resource_types/strings.rb
417
+ - lib/abide_dev_utils/ppt/code_introspection.rb
418
+ - lib/abide_dev_utils/ppt/facter_utils.rb
419
+ - lib/abide_dev_utils/ppt/hiera.rb
376
420
  - lib/abide_dev_utils/ppt/new_obj.rb
421
+ - lib/abide_dev_utils/ppt/puppet_module.rb
377
422
  - lib/abide_dev_utils/ppt/score_module.rb
378
423
  - lib/abide_dev_utils/prompt.rb
379
424
  - lib/abide_dev_utils/resources/generic_spec.erb
@@ -388,9 +433,11 @@ files:
388
433
  - lib/abide_dev_utils/xccdf/diff/benchmark/property_existence.rb
389
434
  - lib/abide_dev_utils/xccdf/diff/utils.rb
390
435
  - lib/abide_dev_utils/xccdf/parser.rb
436
+ - lib/abide_dev_utils/xccdf/parser/helpers.rb
391
437
  - lib/abide_dev_utils/xccdf/parser/objects.rb
392
438
  - lib/abide_dev_utils/xccdf/parser/objects/digest_object.rb
393
439
  - lib/abide_dev_utils/xccdf/parser/objects/numbered_object.rb
440
+ - lib/abide_dev_utils/xccdf/utils.rb
394
441
  - new_diff.rb
395
442
  homepage: https://github.com/puppetlabs/abide_dev_utils
396
443
  licenses:
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
- require 'pathname'
5
- require 'yaml'
6
- require 'puppet_pal'
7
- require 'abide_dev_utils/ppt/class_utils'
8
-
9
- module AbideDevUtils
10
- module Ppt
11
- class CoverageReport
12
- def self.generate(puppet_class_dir, hiera_path, profile = nil)
13
- coverage = {}
14
- coverage['classes'] = {}
15
- all_cap = ClassUtils.find_all_classes_and_paths(puppet_class_dir)
16
- invalid_classes = find_invalid_classes(all_cap)
17
- valid_classes = find_valid_classes(all_cap, invalid_classes)
18
- coverage['classes']['invalid'] = invalid_classes
19
- coverage['classes']['valid'] = valid_classes
20
- hiera = YAML.safe_load(File.open(hiera_path))
21
- profile&.gsub!(/^profile_/, '') unless profile.nil?
22
-
23
- matcher = profile.nil? ? /^profile_/ : /^profile_#{profile}/
24
- hiera.each do |k, v|
25
- key_base = k.split('::')[-1]
26
- coverage['benchmark'] = v if key_base == 'title'
27
- next unless key_base.match?(matcher)
28
-
29
- coverage[key_base] = generate_uncovered_data(v, valid_classes)
30
- end
31
- coverage
32
- end
33
-
34
- def self.generate_uncovered_data(ctrl_list, valid_classes)
35
- out_hash = {}
36
- out_hash[:num_total] = ctrl_list.length
37
- out_hash[:uncovered] = []
38
- out_hash[:covered] = []
39
- ctrl_list.each do |c|
40
- if valid_classes.include?(c)
41
- out_hash[:covered] << c
42
- else
43
- out_hash[:uncovered] << c
44
- end
45
- end
46
- out_hash[:num_covered] = out_hash[:covered].length
47
- out_hash[:num_uncovered] = out_hash[:uncovered].length
48
- out_hash[:coverage] = Float(
49
- (Float(out_hash[:num_covered]) / Float(out_hash[:num_total])) * 100.0
50
- ).floor(3)
51
- out_hash
52
- end
53
-
54
- def self.find_valid_classes(all_cap, invalid_classes)
55
- all_classes = all_cap.dup.transpose[0]
56
- return [] if all_classes.nil?
57
-
58
- return all_classes - invalid_classes unless invalid_classes.nil?
59
-
60
- all_classes
61
- end
62
-
63
- def self.find_invalid_classes(all_cap)
64
- invalid_classes = []
65
- all_cap.each do |cap|
66
- invalid_classes << cap[0] unless class_valid?(cap[1])
67
- end
68
- invalid_classes
69
- end
70
-
71
- def self.class_valid?(manifest_path)
72
- compiler = Puppet::Pal::Compiler.new(nil)
73
- ast = compiler.parse_file(manifest_path)
74
- ast.body.body.statements.each do |s|
75
- next unless s.respond_to?(:arguments)
76
- next unless s.arguments.respond_to?(:each)
77
-
78
- s.arguments.each do |i|
79
- return false if i.value == 'Not implemented'
80
- end
81
- end
82
- true
83
- end
84
- end
85
- end
86
- end