abide_dev_utils 0.11.0 → 0.12.1

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +18 -31
  3. data/lib/abide_dev_utils/cem/benchmark.rb +335 -136
  4. data/lib/abide_dev_utils/cem/generate/coverage_report.rb +380 -0
  5. data/lib/abide_dev_utils/cem/generate/reference.rb +238 -35
  6. data/lib/abide_dev_utils/cem/generate.rb +5 -4
  7. data/lib/abide_dev_utils/cem/hiera_data/mapping_data/map_data.rb +110 -0
  8. data/lib/abide_dev_utils/cem/hiera_data/mapping_data/mixins.rb +46 -0
  9. data/lib/abide_dev_utils/cem/hiera_data/mapping_data.rb +146 -0
  10. data/lib/abide_dev_utils/cem/hiera_data/resource_data/control.rb +127 -0
  11. data/lib/abide_dev_utils/cem/hiera_data/resource_data/parameters.rb +90 -0
  12. data/lib/abide_dev_utils/cem/hiera_data/resource_data/resource.rb +102 -0
  13. data/lib/abide_dev_utils/cem/hiera_data/resource_data.rb +310 -0
  14. data/lib/abide_dev_utils/cem/hiera_data.rb +7 -0
  15. data/lib/abide_dev_utils/cem/mapping/mapper.rb +161 -34
  16. data/lib/abide_dev_utils/cem/validate/resource_data.rb +33 -0
  17. data/lib/abide_dev_utils/cem/validate.rb +10 -0
  18. data/lib/abide_dev_utils/cem.rb +0 -1
  19. data/lib/abide_dev_utils/cli/cem.rb +20 -2
  20. data/lib/abide_dev_utils/dot_number_comparable.rb +75 -0
  21. data/lib/abide_dev_utils/errors/cem.rb +10 -0
  22. data/lib/abide_dev_utils/ppt/class_utils.rb +1 -1
  23. data/lib/abide_dev_utils/ppt/code_gen/data_types.rb +64 -0
  24. data/lib/abide_dev_utils/ppt/code_gen/generate.rb +15 -0
  25. data/lib/abide_dev_utils/ppt/code_gen/resource.rb +59 -0
  26. data/lib/abide_dev_utils/ppt/code_gen/resource_types/base.rb +93 -0
  27. data/lib/abide_dev_utils/ppt/code_gen/resource_types/class.rb +17 -0
  28. data/lib/abide_dev_utils/ppt/code_gen/resource_types/manifest.rb +16 -0
  29. data/lib/abide_dev_utils/ppt/code_gen/resource_types/parameter.rb +16 -0
  30. data/lib/abide_dev_utils/ppt/code_gen/resource_types/strings.rb +13 -0
  31. data/lib/abide_dev_utils/ppt/code_gen/resource_types.rb +6 -0
  32. data/lib/abide_dev_utils/ppt/code_gen.rb +15 -0
  33. data/lib/abide_dev_utils/ppt/code_introspection.rb +102 -0
  34. data/lib/abide_dev_utils/ppt/hiera.rb +4 -1
  35. data/lib/abide_dev_utils/ppt/puppet_module.rb +2 -1
  36. data/lib/abide_dev_utils/ppt.rb +3 -0
  37. data/lib/abide_dev_utils/version.rb +1 -1
  38. data/lib/abide_dev_utils/xccdf/parser/helpers.rb +146 -0
  39. data/lib/abide_dev_utils/xccdf/parser/objects.rb +87 -144
  40. data/lib/abide_dev_utils/xccdf/parser.rb +5 -0
  41. data/lib/abide_dev_utils/xccdf/utils.rb +89 -0
  42. data/lib/abide_dev_utils/xccdf.rb +193 -63
  43. metadata +27 -3
  44. data/lib/abide_dev_utils/cem/coverage_report.rb +0 -348
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cf13209260261bcf509e7953d4af4a47aa7301cc7c2e8227c3d736d163cd0b1
4
- data.tar.gz: a6d6cb52aadf58e33ce6a57d77c7921226ebb130aa2d6e4350c42c197df0f06c
3
+ metadata.gz: d6f05434761a55369ffb231c1573ba627aa5c9ebef29d198ccfa16c422d05c48
4
+ data.tar.gz: 534968456e7eefca691fa6a3cdc46a170dc3ee12060261225fc35adadbc27d18
5
5
  SHA512:
6
- metadata.gz: be0ac34b2ee3ea116793580ef1ffff41ca4f11b41ceb6587866183734f1aee15a566b5a0063b106a18962739a1d4d7091d6e8d276dffdf6101cfcfb48afb3832
7
- data.tar.gz: 97f9b753cb94f1a1d326eb370a59ae35d00a3c2797b6e030941e51f51e9f7713eca0af9148f9858a0f4c375273bb468ab1df928cd589903d48b9bbe7c86a92fd
6
+ metadata.gz: b9907ee602b3367d4692b5c2102f0c769614f33d22980d5b8c0a14ea7dd15ac19947800eed399e6d68215ea2c21ab670b233209bf62e79399795fc5cc0ca68c2
7
+ data.tar.gz: edbeac0d044795300b42ac1ddd70623abc9c9e7d322ecf1e5d6356c8b4f875a31e31e02c96397b0bc9ee1a6a815fa342401916d9f87696f0ad68f0bd9d887b75
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.11.0)
4
+ abide_dev_utils (0.12.1)
5
5
  amatch (~> 0.4)
6
6
  cmdparse (~> 3.0)
7
7
  facterdb (>= 1.18)
@@ -60,10 +60,10 @@ GEM
60
60
  diff-lcs (1.5.0)
61
61
  digest-crc (0.6.4)
62
62
  rake (>= 12.0.0, < 14.0.0)
63
- facter (4.2.10)
63
+ facter (4.2.11)
64
64
  hocon (~> 1.3)
65
65
  thor (>= 1.0.1, < 2.0)
66
- facterdb (1.18.0)
66
+ facterdb (1.19.0)
67
67
  facter (< 5.0.0)
68
68
  jgrep
69
69
  faraday (2.3.0)
@@ -84,7 +84,7 @@ GEM
84
84
  octokit (~> 4.6)
85
85
  rainbow (>= 2.2.1)
86
86
  rake (>= 10.0)
87
- google-apis-core (0.5.0)
87
+ google-apis-core (0.7.0)
88
88
  addressable (~> 2.5, >= 2.5.1)
89
89
  googleauth (>= 0.16.2, < 2.a)
90
90
  httpclient (>= 2.8.1, < 3.a)
@@ -93,25 +93,25 @@ GEM
93
93
  retriable (>= 2.0, < 4.a)
94
94
  rexml
95
95
  webrick
96
- google-apis-iamcredentials_v1 (0.10.0)
97
- google-apis-core (>= 0.4, < 2.a)
98
- google-apis-storage_v1 (0.14.0)
99
- google-apis-core (>= 0.4, < 2.a)
96
+ google-apis-iamcredentials_v1 (0.13.0)
97
+ google-apis-core (>= 0.7, < 2.a)
98
+ google-apis-storage_v1 (0.17.0)
99
+ google-apis-core (>= 0.7, < 2.a)
100
100
  google-cloud-core (1.6.0)
101
101
  google-cloud-env (~> 1.0)
102
102
  google-cloud-errors (~> 1.0)
103
103
  google-cloud-env (1.6.0)
104
104
  faraday (>= 0.17.3, < 3.0)
105
105
  google-cloud-errors (1.2.0)
106
- google-cloud-storage (1.36.2)
106
+ google-cloud-storage (1.38.0)
107
107
  addressable (~> 2.8)
108
108
  digest-crc (~> 0.4)
109
109
  google-apis-iamcredentials_v1 (~> 0.1)
110
- google-apis-storage_v1 (~> 0.1)
110
+ google-apis-storage_v1 (~> 0.17.0)
111
111
  google-cloud-core (~> 1.6)
112
112
  googleauth (>= 0.16.2, < 2.a)
113
113
  mini_mime (~> 1.0)
114
- googleauth (1.1.3)
114
+ googleauth (1.2.0)
115
115
  faraday (>= 0.17.3, < 3.a)
116
116
  jwt (>= 1.4, < 3.0)
117
117
  memoist (~> 0.16)
@@ -119,7 +119,7 @@ GEM
119
119
  os (>= 0.9, < 2.0)
120
120
  signet (>= 0.16, < 2.a)
121
121
  hashdiff (1.0.1)
122
- hiera (3.9.0)
122
+ hiera (3.10.0)
123
123
  hocon (1.3.1)
124
124
  httpclient (2.8.3)
125
125
  i18n (1.10.0)
@@ -130,7 +130,7 @@ GEM
130
130
  atlassian-jwt
131
131
  multipart-post
132
132
  oauth (~> 0.5, >= 0.5.0)
133
- jwt (2.3.0)
133
+ jwt (2.4.1)
134
134
  locale (2.1.3)
135
135
  memoist (0.16.2)
136
136
  method_source (1.0.0)
@@ -139,11 +139,9 @@ GEM
139
139
  mize (0.4.0)
140
140
  protocol (~> 2.0)
141
141
  multi_json (1.15.0)
142
- multipart-post (2.1.1)
142
+ multipart-post (2.2.3)
143
143
  nio4r (2.5.8)
144
- nokogiri (1.13.6-x86_64-darwin)
145
- racc (~> 1.4)
146
- nokogiri (1.13.6-x86_64-linux)
144
+ nokogiri (1.13.8-x86_64-darwin)
147
145
  racc (~> 1.4)
148
146
  oauth (0.5.10)
149
147
  octokit (4.25.0)
@@ -166,18 +164,7 @@ GEM
166
164
  coderay (~> 1.1)
167
165
  method_source (~> 1.0)
168
166
  public_suffix (4.0.7)
169
- puppet (7.17.0)
170
- concurrent-ruby (~> 1.0)
171
- deep_merge (~> 1.0)
172
- facter (> 2.0.1, < 5)
173
- fast_gettext (>= 1.1, < 3)
174
- hiera (>= 3.2.1, < 4)
175
- locale (~> 2.1)
176
- multi_json (~> 1.10)
177
- puppet-resource_api (~> 1.5)
178
- scanf (~> 1.0)
179
- semantic_puppet (~> 1.0)
180
- puppet (7.17.0-universal-darwin)
167
+ puppet (7.18.0-universal-darwin)
181
168
  CFPropertyList (~> 2.2)
182
169
  concurrent-ruby (~> 1.0)
183
170
  deep_merge (~> 1.0)
@@ -247,9 +234,9 @@ GEM
247
234
  rubyzip (>= 1.2.2)
248
235
  semantic_puppet (1.0.4)
249
236
  sexp_processor (4.16.1)
250
- signet (0.16.1)
237
+ signet (0.17.0)
251
238
  addressable (~> 2.8)
252
- faraday (>= 0.17.5, < 3.0)
239
+ faraday (>= 0.17.5, < 3.a)
253
240
  jwt (>= 1.5, < 3.0)
254
241
  multi_json (~> 1.10)
255
242
  sync (0.5.0)
@@ -1,14 +1,318 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+ require 'abide_dev_utils/dot_number_comparable'
3
5
  require 'abide_dev_utils/errors'
4
- require 'abide_dev_utils/ppt/facter_utils'
6
+ require 'abide_dev_utils/ppt'
5
7
  require 'abide_dev_utils/cem/mapping/mapper'
6
8
 
7
9
  module AbideDevUtils
8
10
  module CEM
9
- # Repesents a benchmark for purposes of organizing data for markdown representation
11
+ # Represents a resource data resource statement
12
+ class Resource
13
+ attr_reader :title, :type
14
+
15
+ def initialize(title, data, framework, mapper)
16
+ @title = title
17
+ @data = data
18
+ @type = data['type']
19
+ @framework = framework
20
+ @mapper = mapper
21
+ @dependent = []
22
+ end
23
+
24
+ # Returns a representation of the actual manifest backing this resource.
25
+ # This is used to gather information from the Puppet code about this
26
+ # resource.
27
+ # @return [AbideDevUtils::Ppt::CodeIntrospection::Manifest]
28
+ # @return [nil] if the manifest could not be found or could not be parsed
29
+ def manifest
30
+ @manifest ||= load_manifest
31
+ end
32
+
33
+ def manifest?
34
+ !manifest.nil?
35
+ end
36
+
37
+ def file_path
38
+ @file_path ||= AbideDevUtils::Ppt::ClassUtils.path_from_class_name((type == 'class' ? title : type))
39
+ end
40
+
41
+ def controls
42
+ @controls || load_controls
43
+ end
44
+
45
+ def cem_options?
46
+ !cem_options.empty?
47
+ end
48
+
49
+ def cem_options
50
+ @cem_options ||= resource_properties('cem_options')
51
+ end
52
+
53
+ def cem_protected?
54
+ !cem_protected.empty?
55
+ end
56
+
57
+ def cem_protected
58
+ @cem_protected ||= resource_properties('cem_protected')
59
+ end
60
+
61
+ def dependent_controls
62
+ @dependent_controls ||= @dependent.flatten.uniq.filter_map { |x| controls.find { |y| y.id == x } }
63
+ end
64
+
65
+ def to_reference
66
+ "#{type.split('::').map(&:capitalize).join('::')}['#{title}']"
67
+ end
68
+
69
+ private
70
+
71
+ attr_reader :data, :framework, :mapper
72
+
73
+ def load_manifest
74
+ AbideDevUtils::Ppt::CodeIntrospection::Manifest.new(file_path)
75
+ rescue StandardError
76
+ nil
77
+ end
78
+
79
+ def resource_properties(prop_name)
80
+ props = Set.new
81
+ return props unless data.key?(prop_name)
82
+
83
+ data[prop_name].each do |param, param_val|
84
+ props << { name: param,
85
+ type: ruby_class_to_puppet_type(param_val.class.to_s),
86
+ default: param_val }
87
+ end
88
+ props
89
+ end
90
+
91
+ def load_controls
92
+ if data['controls'].respond_to?(:keys)
93
+ load_hash_controls(data['controls'], framework, mapper)
94
+ elsif data['controls'].respond_to?(:each_with_index)
95
+ load_array_controls(data['controls'], framework, mapper)
96
+ else
97
+ raise "Control type is invalid. Type: #{data['controls'].class}"
98
+ end
99
+ end
100
+
101
+ def load_hash_controls(ctrls, framework, mapper)
102
+ ctrls.each_with_object([]) do |(name, data), arr|
103
+ if name == 'dependent'
104
+ @dependent << data
105
+ next
106
+ end
107
+ ctrl = Control.new(name, data, self, framework, mapper)
108
+ arr << ctrl
109
+ rescue AbideDevUtils::Errors::ControlIdFrameworkMismatchError,
110
+ AbideDevUtils::Errors::NoMappingDataForControlError
111
+ next
112
+ end
113
+ end
114
+
115
+ def load_array_controls(ctrls, framework, mapper)
116
+ ctrls.each_with_object([]) do |c, arr|
117
+ if c == 'dependent'
118
+ @dependent << c
119
+ next
120
+ end
121
+ ctrl = Control.new(c, 'no_params', self, framework, mapper)
122
+ arr << ctrl
123
+ rescue AbideDevUtils::Errors::ControlIdFrameworkMismatchError,
124
+ AbideDevUtils::Errors::NoMappingDataForControlError
125
+ next
126
+ end
127
+ end
128
+
129
+ def ruby_class_to_puppet_type(class_name)
130
+ pup_type = class_name.split('::').last.capitalize
131
+ case pup_type
132
+ when %r{(Trueclass|Falseclass)}
133
+ 'Boolean'
134
+ when %r{(String|Pathname)}
135
+ 'String'
136
+ when %r{(Integer|Fixnum)}
137
+ 'Integer'
138
+ when %r{(Float|Double)}
139
+ 'Float'
140
+ when %r{Nilclass}
141
+ 'Optional'
142
+ else
143
+ pup_type
144
+ end
145
+ end
146
+ end
147
+
148
+ # Represents a singular rule in a benchmark
149
+ class Control
150
+ include AbideDevUtils::DotNumberComparable
151
+ attr_reader :id, :params, :resource, :framework, :dependent
152
+
153
+ def initialize(id, params, resource, framework, mapper)
154
+ validate_id_with_framework(id, framework, mapper)
155
+ @id = id
156
+ @params = params
157
+ @resource = resource
158
+ @framework = framework
159
+ @mapper = mapper
160
+ raise AbideDevUtils::Errors::NoMappingDataForControlError, @id unless @mapper.get(id)
161
+ end
162
+
163
+ def params?
164
+ !(params.nil? || params.empty? || params == 'no_params') || (resource.cem_options? || resource.cem_protected?)
165
+ end
166
+
167
+ def resource_properties?
168
+ resource.cem_options? || resource.cem_protected?
169
+ end
170
+
171
+ def param_hashes
172
+ return [no_params] unless params?
173
+
174
+ params.each_with_object([]) do |(param, param_val), ar|
175
+ ar << { name: param,
176
+ type: ruby_class_to_puppet_type(param_val.class.to_s),
177
+ default: param_val }
178
+ end
179
+ end
180
+
181
+ def alternate_ids(level: nil, profile: nil)
182
+ id_map = @mapper.get(id, level: level, profile: profile)
183
+ if display_title_type.to_s == @mapper.map_type(id)
184
+ id_map
185
+ else
186
+ alt_ids = id_map.each_with_object([]) do |mapval, arr|
187
+ arr << if display_title_type.to_s == @mapper.map_type(mapval)
188
+ @mapper.get(mapval, level: level, profile: profile)
189
+ else
190
+ mapval
191
+ end
192
+ end
193
+ alt_ids.flatten.uniq
194
+ end
195
+ end
196
+
197
+ def id_map_type
198
+ @mapper.map_type(id)
199
+ end
200
+
201
+ def display_title
202
+ send(display_title_type) unless display_title_type.nil?
203
+ end
204
+
205
+ def levels
206
+ levels_and_profiles[0]
207
+ end
208
+
209
+ def profiles
210
+ levels_and_profiles[1]
211
+ end
212
+
213
+ def valid_maps?
214
+ valid = AbideDevUtils::CEM::Mapping::FRAMEWORK_TYPES[framework].each_with_object([]) do |mtype, arr|
215
+ arr << if @mapper.map_type(id) == mtype
216
+ id
217
+ else
218
+ @mapper.get(id).find { |x| @mapper.map_type(x) == mtype }
219
+ end
220
+ end
221
+ valid.compact.length == AbideDevUtils::CEM::Mapping::FRAMEWORK_TYPES[framework].length
222
+ end
223
+
224
+ def method_missing(meth, *args, &block)
225
+ meth_s = meth.to_s
226
+ if AbideDevUtils::CEM::Mapping::ALL_TYPES.include?(meth_s)
227
+ @mapper.get(id).find { |x| @mapper.map_type(x) == meth_s }
228
+ else
229
+ super
230
+ end
231
+ end
232
+
233
+ def respond_to_missing?(meth, include_private = false)
234
+ AbideDevUtils::CEM::Mapping::ALL_TYPES.include?(meth.to_s) || super
235
+ end
236
+
237
+ def to_h
238
+ {
239
+ id: id,
240
+ display_title: display_title,
241
+ alternate_ids: alternate_ids,
242
+ levels: levels,
243
+ profiles: profiles,
244
+ params: param_hashes,
245
+ resource: resource.to_stubbed_h,
246
+ }
247
+ end
248
+
249
+ private
250
+
251
+ def display_title_type
252
+ if (!vulnid.nil? && !vulnid.is_a?(String)) || !title.is_a?(String)
253
+ nil
254
+ elsif framework == 'stig' && vulnid
255
+ :vulnid
256
+ else
257
+ :title
258
+ end
259
+ end
260
+
261
+ def validate_id_with_framework(id, framework, mapper)
262
+ mtype = mapper.map_type(id)
263
+ return if AbideDevUtils::CEM::Mapping::FRAMEWORK_TYPES[framework].include?(mtype)
264
+
265
+ raise AbideDevUtils::Errors::ControlIdFrameworkMismatchError, [id, mtype, framework]
266
+ end
267
+
268
+ def map
269
+ @map ||= @mapper.get(id)
270
+ end
271
+
272
+ def levels_and_profiles
273
+ @levels_and_profiles ||= find_levels_and_profiles
274
+ end
275
+
276
+ def find_levels_and_profiles
277
+ lvls = []
278
+ profs = []
279
+ @mapper.levels.each do |lvl|
280
+ @mapper.profiles.each do |prof|
281
+ unless @mapper.get(id, level: lvl, profile: prof).nil?
282
+ lvls << lvl
283
+ profs << prof
284
+ end
285
+ end
286
+ end
287
+ [lvls.flatten.compact.uniq, profs.flatten.compact.uniq]
288
+ end
289
+
290
+ def ruby_class_to_puppet_type(class_name)
291
+ pup_type = class_name.split('::').last.capitalize
292
+ case pup_type
293
+ when %r{(Trueclass|Falseclass)}
294
+ 'Boolean'
295
+ when %r{(String|Pathname)}
296
+ 'String'
297
+ when %r{(Integer|Fixnum)}
298
+ 'Integer'
299
+ when %r{(Float|Double)}
300
+ 'Float'
301
+ when %r{Nilclass}
302
+ 'Optional'
303
+ else
304
+ pup_type
305
+ end
306
+ end
307
+
308
+ def no_params
309
+ { name: 'No parameters', type: nil, default: nil }
310
+ end
311
+ end
312
+
313
+ # Repesents a benchmark based on resource and mapping data
10
314
  class Benchmark
11
- attr_reader :osname, :major_version, :os_facts, :osfamily, :hiera_conf, :module_name, :framework, :rules
315
+ attr_reader :osname, :major_version, :os_facts, :osfamily, :hiera_conf, :module_name, :framework
12
316
 
13
317
  def initialize(osname, major_version, hiera_conf, module_name, framework: 'cis')
14
318
  @osname = osname
@@ -18,10 +322,8 @@ module AbideDevUtils
18
322
  @hiera_conf = hiera_conf
19
323
  @module_name = module_name
20
324
  @framework = framework
21
- @rules = {}
22
325
  @map_cache = {}
23
326
  @rules_in_map = {}
24
- load_rules
25
327
  end
26
328
 
27
329
  # Creates Benchmark objects from a Puppet module
@@ -38,23 +340,47 @@ module AbideDevUtils
38
340
  if majver.is_a?(Array)
39
341
  majver.sort.each do |v|
40
342
  frameworks.each do |fw|
41
- benchmark = Benchmark.new(osname, v, pupmod.hiera_conf, pupmod.name(strip_namespace: true), framework: fw)
343
+ benchmark = Benchmark.new(osname,
344
+ v,
345
+ pupmod.hiera_conf,
346
+ pupmod.name(strip_namespace: true),
347
+ framework: fw)
348
+ benchmark.controls
42
349
  ary << benchmark
350
+ rescue AbideDevUtils::Errors::MappingDataFrameworkMismatchError => e
351
+ raise e unless ignore_all_errors || ignore_framework_mismatch
43
352
  rescue StandardError => e
44
- raise e unless ignore_all_errors || (e.instance_of?(AbideDevUtils::Errors::MappingDataFrameworkMismatchError) && ignore_framework_mismatch)
353
+ raise e unless ignore_all_errors
45
354
  end
46
355
  end
47
356
  else
48
357
  frameworks.each do |fw|
49
- benchmark = Benchmark.new(osname, majver, pupmod.hiera_conf, pupmod.name(strip_namespace: true), framework: fw)
358
+ benchmark = Benchmark.new(osname,
359
+ majver,
360
+ pupmod.hiera_conf,
361
+ pupmod.name(strip_namespace: true),
362
+ framework: fw)
363
+ benchmark.controls
50
364
  ary << benchmark
365
+ rescue AbideDevUtils::Errors::MappingDataFrameworkMismatchError => e
366
+ raise e unless ignore_all_errors || ignore_framework_mismatch
51
367
  rescue StandardError => e
52
- raise e unless ignore_all_errors || (e.instance_of?(AbideDevUtils::Errors::MappingDataFrameworkMismatchError) && ignore_framework_mismatch)
368
+ raise e unless ignore_all_errors
53
369
  end
54
370
  end
55
371
  end
56
372
  end
57
373
 
374
+ def resources
375
+ @resources ||= resource_data["#{module_name}::resources"].each_with_object([]) do |(rtitle, rdata), arr|
376
+ arr << Resource.new(rtitle, rdata, framework, mapper)
377
+ end
378
+ end
379
+
380
+ def controls
381
+ @controls ||= resources.map(&:controls).flatten.sort
382
+ end
383
+
58
384
  def mapper
59
385
  @mapper ||= AbideDevUtils::CEM::Mapping::Mapper.new(module_name, framework, load_mapping_data)
60
386
  end
@@ -113,131 +439,6 @@ module AbideDevUtils
113
439
 
114
440
  private
115
441
 
116
- def load_rules
117
- resource_data["#{module_name}::resources"].each do |_, rdata|
118
- unless rdata.key?('controls')
119
- puts "Controls key not found in #{rdata}"
120
- next
121
- end
122
- rdata['controls'].each do |control, control_data|
123
- rule_title = map(control)
124
- next if rule_title.nil? || rule_title.empty?
125
-
126
- rule_title.find { |id| map_type(id) == 'title' }
127
- alternate_ids = map(rule_title)
128
-
129
- next unless rule_title.is_a?(String)
130
-
131
- @rules[rule_title] = {} unless @rules&.key?(rule_title)
132
- @rules[rule_title]['number'] = alternate_ids.find { |id| map_type(id) == 'number' }
133
- @rules[rule_title]['alternate_ids'] = alternate_ids
134
- @rules[rule_title]['params'] = [] unless @rules[rule_title].key?('params')
135
- @rules[rule_title]['level'] = [] unless @rules[rule_title].key?('level')
136
- @rules[rule_title]['profile'] = [] unless @rules[rule_title].key?('profile')
137
- param_hashes(control_data).each do |param_hash|
138
- next if @rules[rule_title]['params'].include?(param_hash[:name])
139
-
140
- @rules[rule_title]['params'] << param_hash
141
- end
142
- levels, profiles = find_levels_and_profiles(control)
143
- unless @rules[rule_title]['level'] == levels
144
- @rules[rule_title]['level'] = @rules[rule_title]['level'] | levels
145
- end
146
- unless @rules[rule_title]['profile'] == profiles
147
- @rules[rule_title]['profile'] = @rules[rule_title]['profile'] | profiles
148
- end
149
- @rules[rule_title]['resource'] = rdata['type']
150
- end
151
- end
152
- @rules = sort_rules
153
- end
154
-
155
- def param_hashes(control_data)
156
- return [] if control_data.nil? || control_data.empty?
157
-
158
- p_hashes = []
159
- if !control_data.respond_to?(:each) && control_data == 'no_params'
160
- p_hashes << no_params
161
- else
162
- control_data.each do |param, param_val|
163
- p_hashes << {
164
- name: param,
165
- type: ruby_class_to_puppet_type(param_val.class.to_s),
166
- default: param_val,
167
- }
168
- end
169
- end
170
- p_hashes
171
- end
172
-
173
- def no_params
174
- { name: 'No parameters', type: nil, default: nil }
175
- end
176
-
177
- # We sort the rules by their control number so they
178
- # appear in the REFERENCE in benchmark order
179
- def sort_rules
180
- sorted = @rules.dup.sort_by do |_, v|
181
- control_num_to_int(v['number'])
182
- end
183
- sorted.to_h
184
- end
185
-
186
- # In order to sort the rules by their control number,
187
- # we need to convert the control number to an integer.
188
- # This is a rough conversion, but should be sufficient
189
- # for the purposes of sorting. The multipliers are
190
- # the 20th, 15th, 10th, and 5th numbers in the Fibonacci
191
- # sequence, then 1 after that. The reason for this is to
192
- # ensure a "spiraled" wieghting of the sections in the control
193
- # number, with 1st section having the most sorting weight, 2nd
194
- # having second most, etc. However, the differences in the multipliers
195
- # are such that it would be difficult for the product of a lesser-weighted
196
- # section to be greater than a greater-weighted section.
197
- def control_num_to_int(control_num)
198
- multipliers = [6765, 610, 55, 5, 1]
199
- nsum = 0
200
- midx = 0
201
- control_num.split('.').each do |num|
202
- multiplier = midx >= multipliers.length ? 1 : multipliers[midx]
203
- nsum += num.to_i * multiplier
204
- midx += 1
205
- end
206
- nsum
207
- end
208
-
209
- def find_levels_and_profiles(control_id)
210
- levels = []
211
- profiles = []
212
- mapper.each_like(control_id) do |lvl, profile_hash|
213
- next if lvl == 'benchmark'
214
-
215
- profile_hash.each do |prof, _|
216
- unless map(control_id, level: lvl, profile: prof).nil?
217
- levels << lvl
218
- profiles << prof
219
- end
220
- end
221
- end
222
- [levels, profiles]
223
- end
224
-
225
- def ruby_class_to_puppet_type(class_name)
226
- pup_type = class_name.split('::').last.capitalize
227
- case pup_type
228
- when %r{(Trueclass|Falseclass)}
229
- 'Boolean'
230
- when %r{(String|Pathname)}
231
- 'String'
232
- when %r{(Integer|Fixnum)}
233
- 'Integer'
234
- when %r{(Float|Double)}
235
- 'Float'
236
- else
237
- pup_type
238
- end
239
- end
240
-
241
442
  def load_mapping_data
242
443
  files = case module_name
243
444
  when /_windows$/
@@ -248,8 +449,6 @@ module AbideDevUtils
248
449
  raise "Module name '#{module_name}' is not a CEM module"
249
450
  end
250
451
  validate_mapping_files_framework(files).each_with_object({}) do |f, h|
251
- next unless f.path.include?(framework)
252
-
253
452
  h[File.basename(f.path, '.yaml')] = YAML.load_file(f.path)
254
453
  end
255
454
  end