abide_dev_utils 0.18.2 → 0.18.3

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: b4687964cd4b5d202b892c1fbcbc26bae0a4b7ca50892510e66aa1e2ba0a99bb
4
- data.tar.gz: e13bbfac5991052c33a8626eed6354454522a5bb3d9211a2d387aa1a5890f191
3
+ metadata.gz: 78c9c17693c37ea1fef9d03a39f7694a033a985c162e3c2df82ac3305491e747
4
+ data.tar.gz: f207165591c42fc17694f792ec17f0ce8e6bf502e14f326135a0bfb02a42a521
5
5
  SHA512:
6
- metadata.gz: 87c903786292eb538ae1e210734fa539b6b551d2cb5d29886175c234e196d29f9cce8627b08e72dedf661945bc8796980c5da5d737a63acfac8216265a7d06a5
7
- data.tar.gz: f8ba2cdcb7f2074990563c2791d82d51bd171142446410f5700a7c64bcb36c761034b2bb1a2324b756a66563bc8c18ab949d7fc3454a08cee44e74d9306d3743
6
+ metadata.gz: '0210948da62d9eecf039617acef3be3fe21143eacd0aa4593ec9d1f3fdfde7ca5d0cc0ef15d60e9dad12432ab170e010e6c28b54f31ca3fa8442820ce64b9cd9'
7
+ data.tar.gz: c332682a7c2a918ade7f6c8a84f9cb90ebd0d4ab5197f79b9a645db0b5610a37205f7b29797d039e58a27802909ab79303d755ea273d5407e7e77169c2cbe512
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.18.2)
4
+ abide_dev_utils (0.18.3)
5
5
  cmdparse (~> 3.0)
6
6
  facterdb (~> 2.1.0)
7
7
  google-cloud-storage (~> 1.34)
@@ -208,8 +208,8 @@ GEM
208
208
  trailblazer-option (>= 0.1.1, < 0.2.0)
209
209
  uber (< 0.2.0)
210
210
  retriable (3.1.2)
211
- rexml (3.2.8)
212
- strscan (>= 3.0.9)
211
+ rexml (3.3.6)
212
+ strscan
213
213
  rgen (0.9.1)
214
214
  rspec (3.11.0)
215
215
  rspec-core (~> 3.11.0)
@@ -54,12 +54,8 @@ module Abide
54
54
  options.on('-L [LEVEL]', '--level [LEVEL]', 'Specify the level to show coverage for') do |l|
55
55
  @data[:level] = l
56
56
  end
57
- options.on('-I', '--ignore-benchmark-errors', 'Ignores errors while generating benchmark reports') do
58
- @data[:ignore_all] = true
59
- end
60
- options.on('-X [XCCDF_DIR]', '--xccdf-dir [XCCDF_DIR]',
61
- 'If specified, the coverage report will be correlated with info from the benchmark XCCDF files') do |d|
62
- @data[:xccdf_dir] = d
57
+ options.on('-I', '--no-ignore-benchmark-errors', 'Does not ignore errors while generating benchmark reports') do
58
+ @data[:ignore_benchmark_errors] = false
63
59
  end
64
60
  options.on('-v', '--verbose', 'Will output the report to the console') { @data[:verbose] = true }
65
61
  options.on('-q', '--quiet', 'Will not output anything to the console') { @data[:quiet] = true }
@@ -70,15 +66,17 @@ module Abide
70
66
  out_format = @data.fetch(:format, 'yaml')
71
67
  quiet = @data.fetch(:quiet, false)
72
68
  console = @data.fetch(:verbose, false) && !quiet
69
+ ignore = @data.fetch(:ignore_benchmark_errors, true)
73
70
  generate_opts = {
74
71
  benchmark: @data[:benchmark],
75
72
  profile: @data[:profile],
76
73
  level: @data[:level],
77
- ignore_benchmark_errors: @data.fetch(:ignore_all, false),
78
- xccdf_dir: @data[:xccdf_dir]
74
+ ignore_benchmark_errors: ignore
79
75
  }
80
76
  AbideDevUtils::Output.simple('Generating coverage report...') unless quiet
81
77
  coverage = AbideDevUtils::Sce::Generate::CoverageReport.generate(format_func: :to_h, opts: generate_opts)
78
+ raise 'No coverage data found' if coverage.empty?
79
+
82
80
  AbideDevUtils::Output.simple("Saving coverage report to #{file_name}...")
83
81
  case out_format
84
82
  when /yaml/i
@@ -14,24 +14,36 @@ module AbideDevUtils
14
14
  # Methods and objects used to construct a report of what SCE enforces versus what
15
15
  # the various compliance frameworks expect to be enforced.
16
16
  module CoverageReport
17
+ # Generate a coverage report for a Puppet module
18
+ # @param format_func [Symbol] the format function to use
19
+ # @param opts [Hash] options for generating the report
20
+ # @option opts [String] :benchmark the benchmark to generate the report for
21
+ # @option opts [String] :profile the profile to generate the report for
22
+ # @option opts [String] :level the level to generate the report for
23
+ # @option opts [Symbol] :format_func the format function to use
24
+ # @option opts [Boolean] :ignore_benchmark_errors ignore all errors when loading benchmarks
17
25
  def self.generate(format_func: :to_h, opts: {})
18
26
  opts = ReportOptions.new(opts)
19
27
  benchmarks = AbideDevUtils::Sce::BenchmarkLoader.benchmarks_from_puppet_module(
20
- ignore_all_errors: opts.ignore_all_errors
28
+ ignore_all_errors: opts.ignore_benchmark_errors
21
29
  )
22
- benchmarks.map do |b|
30
+ benchmarks.filter_map do |b|
31
+ next if opts.benchmark && !Regexp.new(Regexp.escape(opts.benchmark)).match?(b.title_key)
32
+ next if opts.profile && b.mapper.profiles.none?(opts.profile)
33
+ next if opts.level && b.mapper.levels.none?(opts.level)
34
+
23
35
  BenchmarkReport.new(b, opts).run.send(format_func)
24
36
  end
25
37
  end
26
38
 
39
+ # Holds options for generating a report
27
40
  class ReportOptions
28
41
  DEFAULTS = {
29
42
  benchmark: nil,
30
43
  profile: nil,
31
44
  level: nil,
32
45
  format_func: :to_h,
33
- ignore_all_errors: false,
34
- xccdf_dir: nil
46
+ ignore_benchmark_errors: false
35
47
  }.freeze
36
48
 
37
49
  attr_reader(*DEFAULTS.keys)
@@ -44,7 +56,7 @@ module AbideDevUtils
44
56
  end
45
57
 
46
58
  def report_type
47
- @report_type ||= (xccdf_dir.nil? ? :basic_coverage : :correlated_coverage)
59
+ :basic_coverage
48
60
  end
49
61
  end
50
62
 
@@ -150,94 +162,17 @@ module AbideDevUtils
150
162
  end
151
163
  end
152
164
 
153
- class OldReport
154
- def initialize(benchmarks)
155
- @benchmarks = benchmarks
156
- end
157
-
158
- def self.generate
159
- coverage = {}
160
- coverage['classes'] = {}
161
- all_cap = ClassUtils.find_all_classes_and_paths(puppet_class_dir)
162
- invalid_classes = find_invalid_classes(all_cap)
163
- valid_classes = find_valid_classes(all_cap, invalid_classes)
164
- coverage['classes']['invalid'] = invalid_classes
165
- coverage['classes']['valid'] = valid_classes
166
- hiera = YAML.safe_load(File.open(hiera_path))
167
- profile&.gsub!(/^profile_/, '') unless profile.nil?
168
-
169
- matcher = profile.nil? ? /^profile_/ : /^profile_#{profile}/
170
- hiera.each do |k, v|
171
- key_base = k.split('::')[-1]
172
- coverage['benchmark'] = v if key_base == 'title'
173
- next unless key_base.match?(matcher)
174
-
175
- coverage[key_base] = generate_uncovered_data(v, valid_classes)
176
- end
177
- coverage
178
- end
179
-
180
- def self.generate_uncovered_data(ctrl_list, valid_classes)
181
- out_hash = {}
182
- out_hash[:num_total] = ctrl_list.length
183
- out_hash[:uncovered] = []
184
- out_hash[:covered] = []
185
- ctrl_list.each do |c|
186
- if valid_classes.include?(c)
187
- out_hash[:covered] << c
188
- else
189
- out_hash[:uncovered] << c
190
- end
191
- end
192
- out_hash[:num_covered] = out_hash[:covered].length
193
- out_hash[:num_uncovered] = out_hash[:uncovered].length
194
- out_hash[:coverage] = Float(
195
- (Float(out_hash[:num_covered]) / Float(out_hash[:num_total])) * 100.0
196
- ).floor(3)
197
- out_hash
198
- end
199
-
200
- def self.find_valid_classes(all_cap, invalid_classes)
201
- all_classes = all_cap.dup.transpose[0]
202
- return [] if all_classes.nil?
203
-
204
- return all_classes - invalid_classes unless invalid_classes.nil?
205
-
206
- all_classes
207
- end
208
-
209
- def self.find_invalid_classes(all_cap)
210
- invalid_classes = []
211
- all_cap.each do |cap|
212
- invalid_classes << cap[0] unless class_valid?(cap[1])
213
- end
214
- invalid_classes
215
- end
216
-
217
- def self.class_valid?(manifest_path)
218
- compiler = Puppet::Pal::Compiler.new(nil)
219
- ast = compiler.parse_file(manifest_path)
220
- ast.body.body.statements.each do |s|
221
- next unless s.respond_to?(:arguments)
222
- next unless s.arguments.respond_to?(:each)
223
-
224
- s.arguments.each do |i|
225
- return false if i.value == 'Not implemented'
226
- end
227
- end
228
- true
229
- end
230
- end
231
-
232
165
  # Class manages organizing report data into various output formats
233
166
  class ReportOutput
234
167
  attr_reader :controls_in_resource_data, :rules_in_map, :timestamp,
235
168
  :title
236
169
 
237
- def initialize(benchmark, controls_in_resource_data, rules_in_map)
170
+ def initialize(benchmark, controls_in_resource_data, rules_in_map, profile: nil, level: nil)
238
171
  @benchmark = benchmark
239
172
  @controls_in_resource_data = controls_in_resource_data
240
173
  @rules_in_map = rules_in_map
174
+ @profile = profile
175
+ @level = level
241
176
  @timestamp = DateTime.now.iso8601
242
177
  @title = "Coverage Report for #{@benchmark.title_key}"
243
178
  end
@@ -287,7 +222,9 @@ module AbideDevUtils
287
222
  {
288
223
  title: @benchmark.title,
289
224
  version: @benchmark.version,
290
- framework: @benchmark.framework
225
+ framework: @benchmark.framework,
226
+ profile: @profile || 'all',
227
+ level: @level || 'all'
291
228
  }
292
229
  end
293
230
 
@@ -310,6 +247,8 @@ module AbideDevUtils
310
247
  def initialize(benchmark, opts = ReportOptions.new)
311
248
  @benchmark = benchmark
312
249
  @opts = opts
250
+ @special_control_names = %w[sce_options sce_protected]
251
+ @stig_map_types = %w[vulnid ruleid]
313
252
  end
314
253
 
315
254
  def run
@@ -327,7 +266,7 @@ module AbideDevUtils
327
266
  def basic_coverage(level: @opts.level, profile: @opts.profile)
328
267
  map_type = @benchmark.map_type(controls_in_resource_data[0])
329
268
  rules_in_map = @benchmark.rules_in_map(map_type, level: level, profile: profile)
330
- ReportOutput.new(@benchmark, controls_in_resource_data, rules_in_map)
269
+ ReportOutput.new(@benchmark, controls_in_resource_data, rules_in_map, profile: profile, level: level)
331
270
  end
332
271
 
333
272
  # def correlated_coverage(level: @opts.level, profile: @opts.profile)
@@ -348,35 +287,19 @@ module AbideDevUtils
348
287
  end
349
288
  end
350
289
  controls.flatten.uniq.select do |c|
351
- case @benchmark.framework
352
- when 'cis'
353
- @benchmark.map_type(c) != 'vulnid'
354
- when 'stig'
355
- @benchmark.map_type(c) == 'vulnid'
290
+ if @special_control_names.include? c
291
+ false
356
292
  else
357
- raise "Cannot find controls for framework #{@benchmark.framework}"
358
- end
359
- end
360
- end
361
-
362
- def find_controls_in_mapping_data
363
- controls = @benchmark.map_data[0].each_with_object([]) do |(_, mapping), arr|
364
- mapping.each do |level, profs|
365
- next if level == 'benchmark'
366
-
367
- profs.each do |_, ctrls|
368
- arr << ctrls.keys
369
- arr << ctrls.values
293
+ case @benchmark.framework
294
+ when 'cis'
295
+ @stig_map_types.none? @benchmark.map_type(c)
296
+ when 'stig'
297
+ @stig_map_types.include? @benchmark.map_type(c)
298
+ else
299
+ raise "Cannot find controls for framework #{@benchmark.framework}"
370
300
  end
371
301
  end
372
302
  end
373
- controls.flatten.uniq
374
- end
375
- end
376
-
377
- class ReportOutputCorrelation
378
- def initialize(cov_rep)
379
- @cov_rep = cov_rep
380
303
  end
381
304
  end
382
305
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.18.2"
4
+ VERSION = "0.18.3"
5
5
  end
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.18.2
4
+ version: 0.18.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-24 00:00:00.000000000 Z
11
+ date: 2024-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -486,7 +486,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
486
486
  - !ruby/object:Gem::Version
487
487
  version: '0'
488
488
  requirements: []
489
- rubygems_version: 3.4.19
489
+ rubygems_version: 3.5.18
490
490
  signing_key:
491
491
  specification_version: 4
492
492
  summary: Helper utilities for developing compliance Puppet code