abide_dev_utils 0.9.5 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +80 -83
- data/abide_dev_utils.gemspec +2 -1
- data/lib/abide_dev_utils/cem.rb +72 -0
- data/lib/abide_dev_utils/cli/cem.rb +73 -0
- data/lib/abide_dev_utils/cli/jira.rb +1 -1
- data/lib/abide_dev_utils/cli/xccdf.rb +15 -1
- data/lib/abide_dev_utils/cli.rb +2 -0
- data/lib/abide_dev_utils/files.rb +34 -0
- data/lib/abide_dev_utils/version.rb +1 -1
- data/lib/abide_dev_utils/xccdf/diff/benchmark/number_title.rb +270 -0
- data/lib/abide_dev_utils/xccdf/diff/benchmark/profile.rb +104 -0
- data/lib/abide_dev_utils/xccdf/diff/benchmark/property.rb +127 -0
- data/lib/abide_dev_utils/xccdf/diff/benchmark/property_existence.rb +47 -0
- data/lib/abide_dev_utils/xccdf/diff/benchmark.rb +267 -0
- data/lib/abide_dev_utils/xccdf/diff/utils.rb +30 -0
- data/lib/abide_dev_utils/xccdf/diff.rb +233 -0
- data/lib/abide_dev_utils/xccdf/parser/objects/digest_object.rb +118 -0
- data/lib/abide_dev_utils/xccdf/parser/objects/numbered_object.rb +104 -0
- data/lib/abide_dev_utils/xccdf/parser/objects.rb +741 -0
- data/lib/abide_dev_utils/xccdf/parser.rb +52 -0
- data/lib/abide_dev_utils/xccdf.rb +24 -125
- data/new_diff.rb +48 -0
- metadata +33 -5
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'abide_dev_utils/files'
|
4
|
+
require 'abide_dev_utils/xccdf/parser/objects'
|
5
|
+
|
6
|
+
module AbideDevUtils
|
7
|
+
module XCCDF
|
8
|
+
# Contains methods and classes for parsing XCCDF files,
|
9
|
+
module Parser
|
10
|
+
def self.parse(file_path)
|
11
|
+
doc = AbideDevUtils::Files::Reader.read(file_path)
|
12
|
+
benchmark = AbideDevUtils::XCCDF::Parser::Objects::Benchmark.new(doc)
|
13
|
+
Linker.resolve_links(benchmark)
|
14
|
+
benchmark
|
15
|
+
end
|
16
|
+
|
17
|
+
# Links XCCDF objects by reference.
|
18
|
+
# Each link is resolved and then a bidirectional link is established
|
19
|
+
# between the two objects.
|
20
|
+
module Linker
|
21
|
+
def self.resolve_links(benchmark)
|
22
|
+
link_profile_rules(benchmark)
|
23
|
+
link_rule_values(benchmark)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.link_profile_rules(benchmark)
|
27
|
+
rules = benchmark.find_children_by_class(AbideDevUtils::XCCDF::Parser::Objects::Rule, recurse: true)
|
28
|
+
benchmark.profile.each do |profile|
|
29
|
+
profile.xccdf_select.each do |sel|
|
30
|
+
rules.select { |rule| rule.id == sel.idref }.each do |rule|
|
31
|
+
rule.add_link(profile)
|
32
|
+
profile.add_link(rule)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.link_rule_values(benchmark)
|
39
|
+
rules = benchmark.find_children_by_class(AbideDevUtils::XCCDF::Parser::Objects::Rule, recurse: true)
|
40
|
+
benchmark.value.each do |value|
|
41
|
+
rules.each do |rule|
|
42
|
+
unless rule.find_children_by_attribute_value('value-id', value.id, recurse: true).empty?
|
43
|
+
rule.add_link(value)
|
44
|
+
value.add_link(rule)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -34,21 +34,17 @@ module AbideDevUtils
|
|
34
34
|
|
35
35
|
# Diffs two xccdf files
|
36
36
|
def self.diff(file1, file2, opts)
|
37
|
+
require 'abide_dev_utils/xccdf/diff'
|
37
38
|
bm1 = Benchmark.new(file1)
|
38
39
|
bm2 = Benchmark.new(file2)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
profile_key = profile.nil? ? 'all_profiles' : profile
|
48
|
-
{
|
49
|
-
'benchmark' => bm1.diff_title_version(bm2),
|
50
|
-
profile_key => profile_diff
|
51
|
-
}
|
40
|
+
AbideDevUtils::XCCDF::Diff.diff_benchmarks(bm1, bm2, opts)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Use new-style diff
|
44
|
+
def self.new_style_diff(file1, file2, opts)
|
45
|
+
require 'abide_dev_utils/xccdf/diff/benchmark'
|
46
|
+
bm_diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(file1, file2, opts)
|
47
|
+
bm_diff.diff
|
52
48
|
end
|
53
49
|
|
54
50
|
# Common constants and methods included by nearly everything else
|
@@ -164,25 +160,6 @@ module AbideDevUtils
|
|
164
160
|
diff_properties.map { |x| send(x) } == other.diff_properties.map { |x| other.send(x) }
|
165
161
|
end
|
166
162
|
|
167
|
-
def default_diff_opts
|
168
|
-
{
|
169
|
-
similarity: 1,
|
170
|
-
strict: true,
|
171
|
-
strip: true,
|
172
|
-
array_path: true,
|
173
|
-
delimiter: '//',
|
174
|
-
use_lcs: false
|
175
|
-
}
|
176
|
-
end
|
177
|
-
|
178
|
-
def diff(other, **opts)
|
179
|
-
Hashdiff.diff(
|
180
|
-
to_h,
|
181
|
-
other.to_h,
|
182
|
-
default_diff_opts.merge(opts)
|
183
|
-
)
|
184
|
-
end
|
185
|
-
|
186
163
|
def abide_object?
|
187
164
|
true
|
188
165
|
end
|
@@ -231,9 +208,12 @@ module AbideDevUtils
|
|
231
208
|
profiles.select { |x| x.title == profile_title }.controls
|
232
209
|
end
|
233
210
|
|
234
|
-
def gen_map(dir: nil, type: '
|
211
|
+
def gen_map(dir: nil, type: 'cis', parent_key_prefix: '', version_output_dir: false, **_)
|
235
212
|
os, ver = facter_platform
|
236
|
-
|
213
|
+
output_path = [type, os, ver]
|
214
|
+
output_path.unshift(File.expand_path(dir)) if dir
|
215
|
+
output_path << version if version_output_dir
|
216
|
+
mapping_dir = File.expand_path(File.join(output_path))
|
237
217
|
parent_key_prefix = '' if parent_key_prefix.nil?
|
238
218
|
MAP_INDICES.each_with_object({}) do |idx, h|
|
239
219
|
map_file_path = "#{mapping_dir}/#{idx}.yaml"
|
@@ -257,33 +237,6 @@ module AbideDevUtils
|
|
257
237
|
}
|
258
238
|
end
|
259
239
|
|
260
|
-
def diff_title_version(other)
|
261
|
-
Hashdiff.diff(
|
262
|
-
to_h.reject { |k, _| k.to_s == 'profiles' },
|
263
|
-
other.to_h.reject { |k, _| k.to_s == 'profiles' },
|
264
|
-
default_diff_opts
|
265
|
-
)
|
266
|
-
end
|
267
|
-
|
268
|
-
def diff_profiles(other)
|
269
|
-
this_diff = {}
|
270
|
-
other_hash = other.to_h[:profiles]
|
271
|
-
to_h[:profiles].each do |name, data|
|
272
|
-
diff_h = Hashdiff.diff(data, other_hash[name], default_diff_opts).each_with_object({}) do |x, a|
|
273
|
-
val_to = x.length == 4 ? x[3] : nil
|
274
|
-
a_key = x[2].is_a?(Hash) ? x[2][:title] : x[2]
|
275
|
-
a[a_key] = [] unless a.key?(a_key)
|
276
|
-
a[a_key] << ChangeSet.new(change: x[0], key: x[1], value: x[2], value_to: val_to)
|
277
|
-
end
|
278
|
-
this_diff[name] = diff_h
|
279
|
-
end
|
280
|
-
this_diff
|
281
|
-
end
|
282
|
-
|
283
|
-
def diff_controls(other)
|
284
|
-
controls.diff(other.controls)
|
285
|
-
end
|
286
|
-
|
287
240
|
def map_indexed(index: 'title', framework: 'cis', key_prefix: '')
|
288
241
|
c_map = profiles.each_with_object({}) do |profile, obj|
|
289
242
|
obj[profile.level.downcase] = {} unless obj[profile.level.downcase].is_a?(Hash)
|
@@ -298,7 +251,16 @@ module AbideDevUtils
|
|
298
251
|
|
299
252
|
def facter_platform
|
300
253
|
cpe = xpath('xccdf:Benchmark/xccdf:platform')[0]['idref'].split(':')
|
301
|
-
|
254
|
+
if cpe.length > 4
|
255
|
+
product_name = cpe[4].split('_')
|
256
|
+
product_version = cpe[5].split('.') unless cpe[5].nil?
|
257
|
+
return [product_name[0], product_version[0]] unless product_version[0] == '-'
|
258
|
+
|
259
|
+
return [product_name[0], product_name[-1]] if product_version[0] == '-'
|
260
|
+
end
|
261
|
+
|
262
|
+
product = cpe[3].split('_')
|
263
|
+
[product[0], product[-1]] # This should wrap the name i.e 'Windows' and the version '10'
|
302
264
|
end
|
303
265
|
|
304
266
|
# Converts object to Hiera-formatted YAML
|
@@ -387,69 +349,6 @@ module AbideDevUtils
|
|
387
349
|
end
|
388
350
|
end
|
389
351
|
|
390
|
-
class ChangeSet
|
391
|
-
attr_reader :change, :key, :value, :value_to
|
392
|
-
|
393
|
-
def initialize(change:, key:, value:, value_to: nil)
|
394
|
-
validate_change(change)
|
395
|
-
@change = change
|
396
|
-
@key = key
|
397
|
-
@value = value
|
398
|
-
@value_to = value_to
|
399
|
-
end
|
400
|
-
|
401
|
-
def to_s
|
402
|
-
val_to_str = value_to.nil? ? ' ' : " to #{value_to} "
|
403
|
-
"#{change_string} value #{value}#{val_to_str}at #{key}"
|
404
|
-
end
|
405
|
-
|
406
|
-
def can_merge?(other)
|
407
|
-
return false unless (change == '-' && other.change == '+') || (change == '+' && other.change == '-')
|
408
|
-
return false unless key == other.key || value_hash_equality(other)
|
409
|
-
|
410
|
-
true
|
411
|
-
end
|
412
|
-
|
413
|
-
def merge(other)
|
414
|
-
unless can_merge?(other)
|
415
|
-
raise ArgumentError, 'Cannot merge. Possible causes: change is identical; key or value do not match'
|
416
|
-
end
|
417
|
-
|
418
|
-
new_to_value = value == other.value ? nil : other.value
|
419
|
-
ChangeSet.new(
|
420
|
-
change: '~',
|
421
|
-
key: key,
|
422
|
-
value: value,
|
423
|
-
value_to: new_to_value
|
424
|
-
)
|
425
|
-
end
|
426
|
-
|
427
|
-
private
|
428
|
-
|
429
|
-
def value_hash_equality(other)
|
430
|
-
equality = false
|
431
|
-
value.each do |k, v|
|
432
|
-
equality = true if v == other.value[k]
|
433
|
-
end
|
434
|
-
equality
|
435
|
-
end
|
436
|
-
|
437
|
-
def validate_change(change)
|
438
|
-
raise ArgumentError, "Change type #{change} in invalid" unless ['+', '-', '~'].include?(change)
|
439
|
-
end
|
440
|
-
|
441
|
-
def change_string
|
442
|
-
case change
|
443
|
-
when '-'
|
444
|
-
'remove'
|
445
|
-
when '+'
|
446
|
-
'add'
|
447
|
-
else
|
448
|
-
'change'
|
449
|
-
end
|
450
|
-
end
|
451
|
-
end
|
452
|
-
|
453
352
|
class ObjectContainer
|
454
353
|
include AbideDevUtils::XCCDF::Common
|
455
354
|
|
data/new_diff.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'pry'
|
6
|
+
require 'abide_dev_utils/xccdf/diff/benchmark'
|
7
|
+
|
8
|
+
xml_file1 = File.expand_path(ARGV[0])
|
9
|
+
xml_file2 = File.expand_path(ARGV[1])
|
10
|
+
legacy_config = ARGV.length > 2 ? YAML.load_file(File.expand_path(ARGV[2])) : nil
|
11
|
+
|
12
|
+
def convert_legacy_config(config, num_title_diff, key_format: :hiera_num)
|
13
|
+
nt_diff = num_title_diff.diff(key: :number)
|
14
|
+
updated_config = config['config']['control_configs'].each_with_object({}) do |(key, value), h|
|
15
|
+
next if value.nil?
|
16
|
+
|
17
|
+
diff_key = key.to_s.gsub(/^c/, '').tr('_', '.') if key_format == :hiera_num
|
18
|
+
if nt_diff.key?(diff_key)
|
19
|
+
if nt_diff[diff_key][0][:diff] == :number
|
20
|
+
new_key = "c#{nt_diff[diff_key][0][:other_number].to_s.tr('.', '_')}"
|
21
|
+
h[new_key] = value
|
22
|
+
puts "Converted #{key} to #{new_key}"
|
23
|
+
elsif nt_diff[diff_key][0][:diff] == :title
|
24
|
+
|
25
|
+
h[key] = value
|
26
|
+
end
|
27
|
+
else
|
28
|
+
h[key] = value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
{ 'config' => { 'control_configs' => updated_config } }.to_yaml
|
32
|
+
end
|
33
|
+
|
34
|
+
start_time = Time.now
|
35
|
+
|
36
|
+
bm_diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(xml_file1, xml_file2)
|
37
|
+
self_nc_count, other_nc_count = bm_diff.numbered_children_counts
|
38
|
+
puts "Benchmark numbered children count: #{self_nc_count}"
|
39
|
+
puts "Other benchmark numbered children count: #{other_nc_count}"
|
40
|
+
puts "Rule count difference: #{bm_diff.numbered_children_count_diff}"
|
41
|
+
num_diff = bm_diff.number_title_diff
|
42
|
+
binding.pry if legacy_config.nil?
|
43
|
+
File.open('/tmp/legacy_converted.yaml', 'w') do |f|
|
44
|
+
converted = convert_legacy_config(legacy_config, num_diff)
|
45
|
+
f.write(converted)
|
46
|
+
end
|
47
|
+
|
48
|
+
puts "Computation time: #{Time.now - start_time}"
|
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.
|
4
|
+
version: 0.10.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: 2022-02
|
11
|
+
date: 2022-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.13'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.13'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: cmdparse
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '1.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: amatch
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.4'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.4'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: bundler
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -330,8 +344,10 @@ files:
|
|
330
344
|
- bin/setup
|
331
345
|
- exe/abide
|
332
346
|
- lib/abide_dev_utils.rb
|
347
|
+
- lib/abide_dev_utils/cem.rb
|
333
348
|
- lib/abide_dev_utils/cli.rb
|
334
349
|
- lib/abide_dev_utils/cli/abstract.rb
|
350
|
+
- lib/abide_dev_utils/cli/cem.rb
|
335
351
|
- lib/abide_dev_utils/cli/comply.rb
|
336
352
|
- lib/abide_dev_utils/cli/jira.rb
|
337
353
|
- lib/abide_dev_utils/cli/puppet.rb
|
@@ -364,6 +380,18 @@ files:
|
|
364
380
|
- lib/abide_dev_utils/validate.rb
|
365
381
|
- lib/abide_dev_utils/version.rb
|
366
382
|
- lib/abide_dev_utils/xccdf.rb
|
383
|
+
- lib/abide_dev_utils/xccdf/diff.rb
|
384
|
+
- lib/abide_dev_utils/xccdf/diff/benchmark.rb
|
385
|
+
- lib/abide_dev_utils/xccdf/diff/benchmark/number_title.rb
|
386
|
+
- lib/abide_dev_utils/xccdf/diff/benchmark/profile.rb
|
387
|
+
- lib/abide_dev_utils/xccdf/diff/benchmark/property.rb
|
388
|
+
- lib/abide_dev_utils/xccdf/diff/benchmark/property_existence.rb
|
389
|
+
- lib/abide_dev_utils/xccdf/diff/utils.rb
|
390
|
+
- lib/abide_dev_utils/xccdf/parser.rb
|
391
|
+
- lib/abide_dev_utils/xccdf/parser/objects.rb
|
392
|
+
- lib/abide_dev_utils/xccdf/parser/objects/digest_object.rb
|
393
|
+
- lib/abide_dev_utils/xccdf/parser/objects/numbered_object.rb
|
394
|
+
- new_diff.rb
|
367
395
|
homepage: https://github.com/puppetlabs/abide_dev_utils
|
368
396
|
licenses:
|
369
397
|
- MIT
|
@@ -386,7 +414,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
386
414
|
- !ruby/object:Gem::Version
|
387
415
|
version: '0'
|
388
416
|
requirements: []
|
389
|
-
rubygems_version: 3.1.
|
417
|
+
rubygems_version: 3.1.4
|
390
418
|
signing_key:
|
391
419
|
specification_version: 4
|
392
420
|
summary: Helper utilities for developing compliance Puppet code
|