abide_dev_utils 0.11.0 → 0.12.1

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