abide_dev_utils 0.8.1 → 0.9.0

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