abide-data-processor 0.3.0 → 1.1.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.
@@ -1,283 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'deep_merge'
4
- require 'set'
3
+ require 'abide-data-processor/parser'
5
4
 
6
5
  module AbideDataProcessor
7
6
  module Processor
8
- # Here lies the class that will be use to create/extract resources
9
- class ResourceCreator
10
-
11
- # @param control_maps: The control mappings to valid IDs
12
- # @param module_name: The name of the module
13
- # @param logger: The logger that we will use to log information for the user
14
- def initialize(control_maps, logger)
15
- @control_maps = control_maps
16
- @logger = logger
17
- end
18
-
19
- # control_key_maps
20
- # Gets all control key maps from Hiera for indexed control ID permutation searches
21
- # @return An array of four control ID maps, each indexed by one of the four different valid permutations of a control ID
22
- def self.control_key_maps(module_name)
23
- key_prefix = "#{module_name}::mappings::cis"
24
- %w[hiera_title hiera_title_num number title].each_with_object([]) do |key, ary|
25
- ary << [key_prefix, key].join('::')
26
- end
27
- end
28
-
29
- def cis_hiera_key(prefix, key)
30
- "#{prefix}::#{key}"
31
- end
32
-
33
- # create_resources
34
- # @param resources_hash: the hash of controls to be enforces, user will provide this
35
- # @param only: the list of controls to be enforce only, pulled from cis.pp
36
- # @param ignore: the list of controls to be ignore, pulled from cis.pp
37
- # @param control_configs: the custom control configurations pulled from cis.pp
38
- # Return a hash to be convert to Puppet code.
39
- def create_resources(resources_hash, only, ignore, control_configs)
40
- unfreezed_resources = Marshal.load(Marshal.dump(resources_hash))
41
- resources = real_resources(unfreezed_resources, only.to_set, ignore.to_set, control_configs)
42
- ordered_resources = order_resources(resources)
43
-
44
- mutate_ordering_params!(ordered_resources[1])
45
- ordered_resources
46
- end
47
-
48
- # Everything else except the create_resource function will be private
49
- private
50
-
51
- # real_resources
52
- # Formats a Hiera resources hash into a hash used by order_resources()
53
- # @param resources_hash The raw resources hash pulled from hiera
54
- # @param only The $only parameter from cis.pp
55
- # @param ignore The $ignore parameter from cis.pp
56
- # @param control_configs The $control_configs parameter from cis.pp
57
- def real_resources(resources_hash, only, ignore, control_configs)
58
- real_resources = {}
59
- all_controls_name = Set.new # subject to change
60
-
61
- # Grabbing all the control name here into a set
62
- resources_hash.each do |_title, data|
63
- all_controls_name |= data['controls'].keys.to_set
64
- end
65
-
66
- resources_hash.each do |title, data|
67
- resource_params = if data.key?('controls')
68
- extract_control_params(data['controls'], only, ignore, control_configs, all_controls_name)
69
- else
70
- {}
71
- end
72
- if real_resources.key?(data['type']) && real_resources[data['type']].key?(title)
73
- real_resources[data['type']][title].deep_merge!(resource_params, merge_hash_arrays: true)
74
- else
75
- real_resources[data['type']] = { title => resource_params }
76
- end
77
- end
78
- real_resources
79
- end
80
-
81
- # extract_control_params
82
- # Extracts resource parameters from a Hiera resource hash item's `controls` key
83
- # @param control_data The resource hash item's `controls` key-value pair (i.e. data['controls'])
84
- # @param only The $only parameter from cis.pp
85
- # @param ignore The $ignore parameter from cis.pp
86
- # @param control_configs The $control_configs parameter from cis.pp
87
- # @param all_controls_name: All of the controls name
88
- def extract_control_params(control_data, only, ignore, control_configs, all_controls_name)
89
- control_params = {}
90
- control_data.each do |name, params|
91
- name_map = map_for_control_name(name, @control_maps)
92
- next if name_map.nil?
93
- # Only and ignore list check
94
- # The name_map that got passed in here is a hash
95
- next unless only_and_ignore_check(name, name_map, only, ignore)
96
-
97
- # Control dependent check
98
- if params.key?('dependent')
99
- unless dependent_check(all_controls_name, params['dependent'], ignore, only)
100
- # Below is just a sure fire way to make sure that we will never use the resource
101
- only.delete(name) # Remove from the only list
102
- ignore.add(name) # Add the name of the current control to the ignore list if we're not gonna enforce it
103
- @logger.debug("Control #{name} will not be enforced because the controls that it depends on is invalid.")
104
- next
105
- end
106
- end
107
- # Find if there are any custom control configs from the cis.pp based on the control's name and its permutation
108
- customized = find_control_customization(name, name_map[name], control_configs) # Check for failuer here
109
- params.deep_merge!(customized, merge_hash_arrays: true)
110
- control_params.deep_merge!(params, merge_hash_arrays: true)
111
- end
112
- control_params
113
- end
114
-
115
- # dependent_check
116
- # @param all_controls_name: Set of all controls name that parsed from the hiera data
117
- # @param all_dependent_resources: An array of all the resources that is relied upon
118
- # @param ignore: List of controls to be ignore
119
- # @param only: List of only controls that need to be enforce
120
- # return true if a dependent control is
121
- def dependent_check(all_controls_name, all_dependent_resources, ignore, only)
122
- all_dependent_resources.each do |resource_name|
123
- valid_resource_name = map_for_control_name(resource_name, @control_maps)
124
- # Bounce immediately if it is not a part of the controls we're enforcing
125
- return false unless filter_function(resource_name, valid_resource_name, all_controls_name)
126
-
127
- if !ignore.empty?
128
- return false if filter_function(resource_name, valid_resource_name, ignore)
129
- elsif !only.empty?
130
- return false unless filter_function(resource_name, valid_resource_name, only)
131
- end
132
- end
133
- end
134
-
135
- # order_resources
136
- # A work in progress to integrate more metaparamenters in
137
- # Checks for and creates resources based off of `before`, `after`, `notify`, `require` parameters
138
- # specified in a controls hash
139
- # @param resources Output of real_resources()
140
- # @return An array of resource hashes indexed in the order their contents should be created
141
- def order_resources(resources)
142
- before = {}
143
- after = {}
144
- req = {}
145
- notify = {}
146
- resources.each do |_, data|
147
- create_ordered_resource!('before', before, data)
148
- create_ordered_resource!('notify', notify, data)
149
- create_ordered_resource!('after', after, data)
150
- create_ordered_resource!('require', req, data)
151
- end
152
-
153
- before.deep_merge!(notify)
154
- after.deep_merge!(req)
155
-
156
- [before, resources, after]
157
- end
158
-
159
- # filter_function
160
- # A general function to see if a control name is in a supply list of control name
161
- # @param name: The name of the control that we have
162
- # @param name_map: Hash that contains all valid control ID permutation of the param name
163
- # @set_of_control: Either the ignore or the only list to go through
164
- # return true if control ID is found in set_of_control
165
- def filter_function(name, name_map, set_of_control)
166
- name_list = name_map[name] # Grab the array that contain all valid permutation of the ID
167
- return true if set_of_control.include?(name)
168
-
169
- name_list.each do |n|
170
- return true if set_of_control.include?(n)
171
- end
172
-
173
- false
174
- end
175
-
176
- # only_and_ignore_check
177
- # @param name: name of the control to check if it's in either only or ignore list
178
- # @param name_map: a hash of the name map of valid ID permutation for the `name` param
179
- # @param only: the list of controls that will get enforced only
180
- # @param ignore: the list of controls that will be ignored
181
- # @return false when control is either not in the only list or is in the ignore list.
182
- # else return true
183
- def only_and_ignore_check(name, name_map, only, ignore)
184
- if !only.empty? && !filter_function(name, name_map, only)
185
- @logger.debug("Control #{name} will be skipped because it is not in the only list.")
186
- return false
187
- end
188
-
189
- if !ignore.empty? && filter_function(name, name_map, ignore)
190
- @logger.debug("Control #{name} will be skipped because it is in the ignore list.")
191
- return false
192
- end
193
- true
194
- end
195
-
196
- # create_ordered_resource!
197
- # Creates a resource hash from a resource declaration found in a `before`, `after`, `require`, or `notify` parameter
198
- # @param order_key Either 'before', 'after', `notify`, or `require`
199
- # @param container Either the before hash, the notify hash, the require hash or the after hash.
200
- # The container is modified in place.
201
- # @param res_data Resource data from the real_resources hash
202
- def create_ordered_resource!(order_key, container, res_data)
203
- res_data.each do |_, data|
204
- next unless data.key?(order_key)
205
-
206
- data[order_key].each do |title, params|
207
- container[params['type']] = {} unless container.key?(params['type'])
208
- container[params['type']][title] = params.reject { |k, _| k == 'type' }
209
- end
210
- end
211
- end
212
-
213
- # mutate_ordering_params!
214
- # This takes the Hiera resource declarations in a `before` or `after` param and transforms
215
- # them into and array of Puppet resource references. Puppet resource references take the
216
- # form: Resource::Type['<resource title'].
217
- # @param resources Output from real_resources()
218
- def mutate_ordering_params!(resources)
219
- resources.each do |res_type, res_data|
220
- %w[before notify after require].each do |order_key|
221
- res_data.each do |res_title, params|
222
- next unless params.key?(order_key)
223
-
224
- references = []
225
- params[order_key].each do |k, v|
226
- references << resource_reference(v['type'], k)
227
- end
228
- resources[res_type][res_title][order_key] = references
229
- end
230
- end
231
- end
232
- end
233
-
234
- # resource_reference
235
- # Returns a Puppet resource reference string
236
- # @param res_type A Puppet resource type
237
- # @param title A Puppet resource title
238
- def resource_reference(res_type, title)
239
- type_ref = res_type.split('::').map(&:capitalize).join('::')
240
- "#{type_ref}[#{title}]"
241
- end
242
-
243
- # find_control_customization
244
- # Finds any control parameter customizations passed in via control_configs
245
- # @param name The control name (or other valid permutation)
246
- # @param control_configs The $control_configs parameter from cis.pp
247
- # @param name_map: The array of valid permutation of name
248
- # @return A hash of customized parameters. If none were found, nil
249
- def find_control_customization(name, name_map, control_configs)
250
- return {} if control_configs.empty?
251
-
252
- mapped_key(control_configs, name, name_map)
253
- end
254
-
255
- # map_for_control_name
256
- # Returns a hash of all valid permutations of the given control id
257
- # @param name The control name or other valid permutation
258
- # @param maps All maps
259
- def map_for_control_name(name, maps)
260
- maps.each do |map|
261
- return map if map&.fetch(name, false) # returns the map if fetch returns false
262
- end
263
- nil
264
- end
265
-
266
- # mapped_key
267
- # Finds an item in the given hash that matches one of the values in name_map
268
- # @param hsh The hash to search i.e the custom config hash
269
- # @param name The name of the current control that we're looking to see if it has any custom configs
270
- # @param name_map An array name for valid control permutations
271
- # @return The value from the hash if found, or nil
272
- def mapped_key(hsh, name, name_map)
273
- return hsh[name] if hsh&.fetch(name, false)
274
-
275
- name_map.each do |pkey|
276
- return hsh[pkey] if hsh&.fetch(pkey, false)
277
- end
278
- nil
279
- end
280
-
7
+ def self.create_resources(resources_hash, control_maps, only, ignore, control_configs)
8
+ unfrozen_resources = Marshal.load(Marshal.dump(resources_hash))
9
+ AbideDataProcessor::Parser.parse(unfrozen_resources, control_maps, only: only, ignore: ignore, control_configs: control_configs)
281
10
  end
282
11
  end
283
12
  end
@@ -1,3 +1,3 @@
1
1
  module AbideDataProcessor
2
- VERSION = "0.3.0"
2
+ VERSION = "1.1.1"
3
3
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abide-data-processor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-30 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: puppet
14
+ name: deep_merge
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '6.23'
19
+ version: '1.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rgl
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '6.23'
40
+ version: '0.5'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -241,6 +255,7 @@ files:
241
255
  - bin/setup
242
256
  - lib/abide-data-processor.rb
243
257
  - lib/abide-data-processor/logger.rb
258
+ - lib/abide-data-processor/parser.rb
244
259
  - lib/abide-data-processor/processor.rb
245
260
  - lib/abide-data-processor/version.rb
246
261
  homepage: https://github.com/puppetlabs/abide-data-processor