abide_dev_utils 0.8.1 → 0.9.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 550d53a5583b4befefc9cb5b2cd2ae41dab12dac51d6fe564067d8ad6113daf4
4
- data.tar.gz: 62edfb6d0145ec674ad2cf70eb09b37008075bbe7215c3aba7b0c82988b49cb7
3
+ metadata.gz: 66f347b83cd235bff425a1300f86095cd212550c2948438bec76dded1f367f2c
4
+ data.tar.gz: c4c2ea76f96d88d8bcb89aedeaea795deafc8641addcb729cfba89a3eb383ade
5
5
  SHA512:
6
- metadata.gz: 336b80d3b41db5c839de238d7b3308bcd02b4cad1e339fb2b5879cbb7e132cbf3b8b8432f2ba6c0c2fa0825491fb042817a6225594433fba058eacfdeb6f510c
7
- data.tar.gz: a8e34b36f2bdd51d4d7bf467b91c3f01e7507ea5315a864a564f4c830d43768f98de88075569643205d8c5c43ea8113a1c0afed011a708367a3c66771e10534f
6
+ metadata.gz: 6cc7f7c3a93bab84f56c00a43ecbace096eb82db3363cdd2a43e41a16da13467c0d612f081cfec30c908563c1e5977e19d913f81362b06db8a03f12236c661f7
7
+ data.tar.gz: ed7c670cce6b50b14eb9c82f4a3020078bf7f03e15ef4f687ff1925c6505d48accfd9211e1c0ff6e2bbbf68d9664e4bf22242fb01624c223b939f4545889c804
@@ -16,6 +16,42 @@ module Abide
16
16
  add_command(CmdParse::HelpCommand.new, default: true)
17
17
  add_command(XccdfToHieraCommand.new)
18
18
  add_command(XccdfDiffCommand.new)
19
+ add_command(XccdfGenMapCommand.new)
20
+ end
21
+ end
22
+
23
+ class XccdfGenMapCommand < CmdParse::Command
24
+ CMD_NAME = 'gen-map'
25
+ CMD_SHORT = 'Generates mappings from XCCDF files'
26
+ CMD_LONG = 'Generates mappings for CEM modules from 1 or more XCCDF files as YAML'
27
+ def initialize
28
+ super(CMD_NAME, takes_commands: false)
29
+ short_desc(CMD_SHORT)
30
+ long_desc(CMD_LONG)
31
+ options.on('-b [TYPE]', '--benchmark-type [TYPE]', 'XCCDF Benchmark type CIS by default') { |b| @data[:type] = b }
32
+ options.on('-d [DIR]', '--files-output-directory [DIR]', 'Directory to save files data/mappings by default') { |d| @data[:dir] = d }
33
+ options.on('-q', '--quiet', 'Show no output in the terminal') { @data[:quiet] = true }
34
+ options.on('-p [PREFIX]', '--parent-key-prefix [PREFIX]', 'A prefix to append to the parent key') do |p|
35
+ @data[:parent_key_prefix] = p
36
+ end
37
+ end
38
+
39
+ def execute(xccdf_file)
40
+ if @data[:quiet] && !@data[:dir]
41
+ AbideDevUtils::Output.simple("I don\'t know how to quietly output to the console\n¯\\_(ツ)_/¯")
42
+ exit 1
43
+ end
44
+ @data[:console] = true if @data[:dir].nil?
45
+ @data[:type] = 'cis' if @data[:type].nil?
46
+ @data[:parent_key_prefix] = '' if @data[:parent_key_prefix].nil?
47
+ hfile = AbideDevUtils::XCCDF.gen_map(xccdf_file, **@data)
48
+ mapping_dir = File.dirname(hfile.keys[0]) unless @data[:dir].nil?
49
+ AbideDevUtils::Output.simple("Creating directory #{mapping_dir}") unless @data[:quiet] || @data[:console] || @data[:dir].nil?
50
+ FileUtils.mkdir_p(mapping_dir) unless @data[:console] || @data[:dir].nil?
51
+ hfile.each do |key, val|
52
+ file_path = @data[:dir].nil? ? nil : key
53
+ AbideDevUtils::Output.yaml(val, console: @data[:console], file: file_path)
54
+ end
19
55
  end
20
56
  end
21
57
 
@@ -53,5 +53,9 @@ module AbideDevUtils
53
53
  class NotHashableError < GenericError
54
54
  @default = 'Object does not respond to #to_hash or #to_h:'
55
55
  end
56
+
57
+ class CliOptionsConflict < GenericError
58
+ @default = "Console options conflict."
59
+ end
56
60
  end
57
61
  end
@@ -20,5 +20,9 @@ module AbideDevUtils
20
20
  class ProfilePartsError < GenericError
21
21
  @default = 'Failed to extract parts from profile name:'
22
22
  end
23
+
24
+ class UnsupportedXCCDFError < GenericError
25
+ @default = "XCCDF type is unsupported!"
26
+ end
23
27
  end
24
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.8.1"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -10,6 +10,17 @@ require 'abide_dev_utils/output'
10
10
  module AbideDevUtils
11
11
  # Contains modules and classes for working with XCCDF files
12
12
  module XCCDF
13
+ # Generate map for CEM
14
+ def self.gen_map(xccdf_file, opts)
15
+ type = opts.fetch(:type, 'cis')
16
+ case type.downcase
17
+ when 'cis'
18
+ new_map = Benchmark.new(xccdf_file).gen_map(**opts)
19
+ else
20
+ raise AbideDevUtils::Errors::UnsupportedXCCDFError, "XCCDF type #{type} is unsupported!"
21
+ end
22
+ end
23
+
13
24
  # Converts and xccdf file to a Hiera representation
14
25
  def self.to_hiera(xccdf_file, opts)
15
26
  type = opts.fetch(:type, 'cis')
@@ -17,7 +28,7 @@ module AbideDevUtils
17
28
  when 'cis'
18
29
  Benchmark.new(xccdf_file).to_hiera(**opts)
19
30
  else
20
- AbideDevUtils::Output.simple("XCCDF type #{type} is unsupported!")
31
+ raise AbideDevUtils::Errors::UnsupportedXCCDFError, "XCCDF type #{type} is unsupported!"
21
32
  end
22
33
  end
23
34
 
@@ -218,6 +229,20 @@ module AbideDevUtils
218
229
  profiles.select { |x| x.title == profile_title }.controls
219
230
  end
220
231
 
232
+ def gen_map(dir: nil, type: 'CIS', parent_key_prefix: '', **_)
233
+ os, ver = facter_platform
234
+ if dir
235
+ mapping_dir = File.expand_path(File.join(dir, type, os, ver))
236
+ else
237
+ mapping_dir = ''
238
+ end
239
+ parent_key_prefix = parent_key_prefix.nil? ? nil : ''
240
+ ['title', 'hiera_title', 'hiera_title_num', 'number'].each_with_object({}) do |idx, h|
241
+ map_file_path = "#{mapping_dir}/#{idx}.yaml"
242
+ h[map_file_path] = map_indexed(index: idx, framework: type, key_prefix: parent_key_prefix)
243
+ end
244
+ end
245
+
221
246
  def find_cis_recommendation(name, number_format: false)
222
247
  profiles.each do |profile|
223
248
  profile.controls.each do |ctrl|
@@ -261,6 +286,43 @@ module AbideDevUtils
261
286
  controls.diff(other.controls)
262
287
  end
263
288
 
289
+ def map_indexed(index: 'title', framework: 'cis', key_prefix: '')
290
+ all_indexes = ['title', 'hiera_title', 'hiera_title_num', 'number']
291
+ c_map = profiles.each_with_object({}) do |profile, obj|
292
+ controls_hash = profile.controls.each_with_object({}) do |ctrl, hsh|
293
+ real_index = if index == 'hiera_title_num'
294
+ ctrl.hiera_title(number_format: true)
295
+ elsif index == 'title'
296
+ resolve_control_reference(ctrl).xpath('./xccdf:title').text
297
+ else
298
+ ctrl.send(index.to_sym)
299
+ end
300
+ controls_array = all_indexes.each_with_object([]) do |idx_sym, ary|
301
+ next if idx_sym == index
302
+
303
+ item = if idx_sym == 'hiera_title_num'
304
+ ctrl.hiera_title(number_format: true)
305
+ elsif idx_sym == 'title'
306
+ resolve_control_reference(ctrl).xpath('./xccdf:title').text
307
+ else
308
+ ctrl.send(idx_sym.to_sym)
309
+ end
310
+ ary << "#{item}"
311
+ end
312
+ hsh["#{real_index.to_s}"] = controls_array.sort
313
+ end
314
+ obj[profile.level.downcase] = {profile.title.downcase => controls_hash.sort_by { |k, _| k }.to_h }
315
+ end
316
+ mappings = [framework, index]
317
+ mappings.unshift(key_prefix) unless key_prefix.empty?
318
+ { mappings.join('::') => c_map }.to_yaml
319
+ end
320
+
321
+ def facter_platform
322
+ cpe = xpath('xccdf:Benchmark/xccdf:platform')[0]['idref'].split(':')
323
+ [cpe[4].split('_')[0], cpe[5].split('.')[0]]
324
+ end
325
+
264
326
  # Converts object to Hiera-formatted YAML
265
327
  # @return [String] YAML-formatted string
266
328
  def to_hiera(parent_key_prefix: nil, num: false, levels: [], titles: [], **_kwargs)
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.8.1
4
+ version: 0.9.0
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-10-14 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri