octool 0.0.5 → 0.0.6
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 +4 -4
- data/bin/octool +21 -4
- data/lib/octool/parser.rb +41 -7
- data/lib/octool/ssp.rb +2 -2
- data/lib/octool/system.rb +44 -39
- data/lib/octool/version.rb +1 -1
- data/lib/octool.rb +1 -0
- data/octool.rdoc +13 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 245e14c9cf523957cca7c2826364125a1f11715a080015124c9477b1c99c6707
|
4
|
+
data.tar.gz: '0759efbc98a8ce26407649d2c4c458e273d3711c8661fbc94b6bb13e194a9695'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a27114864b9430e4096429a2d26d13d92ed6bc53ebfb9fa00008e1beb04cc8527f0637d336020826172b47109b192a94b9adfb6eef3036ce160f150be35b6f5d
|
7
|
+
data.tar.gz: 684fca7c472d21356ce73e63d6c079c959108ebd5debfb66b10e35acfdf04a899a50c9d669db938f284963159eaa656b4f3c981e560a17b1e3396ae8a7c99da8
|
data/bin/octool
CHANGED
@@ -21,7 +21,7 @@ class App
|
|
21
21
|
def self.find_config(args)
|
22
22
|
path = args.first || OCTool::DEFAULT_CONFIG_FILENAME
|
23
23
|
path = File.join(path, OCTool::DEFAULT_CONFIG_FILENAME) if File.directory?(path)
|
24
|
-
path
|
24
|
+
File.expand_path(path)
|
25
25
|
end
|
26
26
|
|
27
27
|
program_desc 'Open Compliance Tool'
|
@@ -51,6 +51,23 @@ class App
|
|
51
51
|
v.default_command :data
|
52
52
|
end
|
53
53
|
|
54
|
+
desc 'export data to CSV'
|
55
|
+
arg_name 'path/to/system/config.yaml'
|
56
|
+
command :csv do |csv|
|
57
|
+
csv.desc 'where to store outputs'
|
58
|
+
csv.default_value data_dir
|
59
|
+
csv.long_desc 'Default output directory respects env vars TMPDIR, TMP, TEMP'
|
60
|
+
csv.arg_name 'path/to/output/dir'
|
61
|
+
csv.flag [:d, :dir]
|
62
|
+
|
63
|
+
csv.action do |global_options, options, args|
|
64
|
+
export_dir = options[:dir]
|
65
|
+
config_file = find_config(args)
|
66
|
+
system = OCTool::Parser.new(config_file).load_system
|
67
|
+
system.dump export_dir
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
54
71
|
desc 'validate data and generate System Security Plan'
|
55
72
|
arg_name 'path/to/system/config.yaml'
|
56
73
|
command :ssp do |s|
|
@@ -92,12 +109,12 @@ class App
|
|
92
109
|
# Error logic here
|
93
110
|
# Return false to skip default error handling.
|
94
111
|
if ENV['DEBUG']
|
95
|
-
|
96
|
-
|
112
|
+
warn exception.message
|
113
|
+
warn exception.backtrace
|
97
114
|
pp exception
|
98
115
|
false
|
99
116
|
end
|
100
|
-
|
117
|
+
warn '[FAIL]'
|
101
118
|
true
|
102
119
|
end
|
103
120
|
end
|
data/lib/octool/parser.rb
CHANGED
@@ -4,6 +4,7 @@ module OCTool
|
|
4
4
|
# Custom error to show validation errors.
|
5
5
|
class ValidationError < StandardError
|
6
6
|
attr_reader :errors
|
7
|
+
|
7
8
|
def initialize(path, errors)
|
8
9
|
@path = path
|
9
10
|
@errors = errors
|
@@ -40,10 +41,9 @@ module OCTool
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def validate_file(path, type)
|
43
|
-
|
44
|
-
data =
|
45
|
-
|
46
|
-
errors = parser.errors
|
44
|
+
kwal = kwalifyer(type)
|
45
|
+
data = kwal.parse_file(path)
|
46
|
+
errors = kwal.errors
|
47
47
|
raise ValidationError.new(path, errors) unless errors.empty?
|
48
48
|
|
49
49
|
RecursiveOpenStruct.new(data, recurse_over_arrays: true, preserve_original_keys: true)
|
@@ -51,7 +51,7 @@ module OCTool
|
|
51
51
|
die e.message
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def kwalifyer(type)
|
55
55
|
schema_file = File.join(schema_dir, "#{type}.yaml")
|
56
56
|
schema = Kwalify::Yaml.load_file(schema_file)
|
57
57
|
validator = Kwalify::Validator.new(schema)
|
@@ -65,7 +65,7 @@ module OCTool
|
|
65
65
|
def schema_version
|
66
66
|
@schema_version ||= Kwalify::Yaml.load_file(@config_file)['schema_version']
|
67
67
|
rescue StandarError
|
68
|
-
|
68
|
+
warn '[FAIL] Unable to read schema_version'
|
69
69
|
exit(1)
|
70
70
|
end
|
71
71
|
|
@@ -76,11 +76,45 @@ module OCTool
|
|
76
76
|
sys = System.new(config)
|
77
77
|
config['includes'].each do |inc|
|
78
78
|
path = File.join(base_dir, inc['path'])
|
79
|
-
sys.data <<
|
79
|
+
sys.data << include_data(path, inc['type'])
|
80
80
|
end
|
81
81
|
sys
|
82
82
|
end
|
83
83
|
|
84
|
+
def include_data(path, type)
|
85
|
+
data = validate_file(path, type)
|
86
|
+
data['type'] = type
|
87
|
+
method("parsed_#{type}".to_sym).call(data)
|
88
|
+
end
|
89
|
+
|
90
|
+
def parsed_component(component)
|
91
|
+
component.attestations.map! do |a|
|
92
|
+
# Add a "component_key" field to each attestation.
|
93
|
+
a['component_key'] = component.component_key
|
94
|
+
a.satisfies.map! do |s|
|
95
|
+
# Add "attestation_key" to each control satisfied by this attestation.
|
96
|
+
s['attestation_key'] = a.summary
|
97
|
+
# Add "component_key" to each control satisfied by this attestation.
|
98
|
+
s['component_key'] = component.component_key
|
99
|
+
s
|
100
|
+
end
|
101
|
+
a
|
102
|
+
end
|
103
|
+
component
|
104
|
+
end
|
105
|
+
|
106
|
+
def parsed_standard(standard)
|
107
|
+
# Add 'standard_key' to each control family and to each control.
|
108
|
+
standard.families.map! { |f| f['standard_key'] = standard.standard_key; f }
|
109
|
+
standard.controls.map! { |c| c['standard_key'] = standard.standard_key; c }
|
110
|
+
standard
|
111
|
+
end
|
112
|
+
|
113
|
+
def parsed_certification(cert)
|
114
|
+
cert.requires.map! { |r| r['certification_key'] = cert.certification_key; r }
|
115
|
+
cert
|
116
|
+
end
|
117
|
+
|
84
118
|
alias load_system validate_data
|
85
119
|
alias load_file validate_file
|
86
120
|
end
|
data/lib/octool/ssp.rb
CHANGED
@@ -18,13 +18,13 @@ module OCTool
|
|
18
18
|
Paru::Pandoc.new
|
19
19
|
end
|
20
20
|
rescue UncaughtThrowError
|
21
|
-
|
21
|
+
warn '[FAIL] octool requires pandoc to generate the SSP. Is pandoc installed?'
|
22
22
|
exit(1)
|
23
23
|
end
|
24
24
|
|
25
25
|
def generate
|
26
26
|
unless File.writable?(@output_dir)
|
27
|
-
|
27
|
+
warn "[FAIL] #{@output_dir} is not writable"
|
28
28
|
exit(1)
|
29
29
|
end
|
30
30
|
render_template
|
data/lib/octool/system.rb
CHANGED
@@ -6,73 +6,78 @@ module OCTool
|
|
6
6
|
attr_accessor :config
|
7
7
|
attr_accessor :data
|
8
8
|
|
9
|
+
TABLE_NAMES = [
|
10
|
+
'components',
|
11
|
+
'satisfies',
|
12
|
+
'attestations',
|
13
|
+
'standards',
|
14
|
+
'controls',
|
15
|
+
'families',
|
16
|
+
'certifications',
|
17
|
+
'requires',
|
18
|
+
].freeze
|
19
|
+
|
9
20
|
def initialize(config)
|
10
21
|
@config = config
|
11
22
|
@data = []
|
12
23
|
end
|
13
24
|
|
14
25
|
def certifications
|
15
|
-
@certifications ||=
|
26
|
+
@certifications ||= data.select { |e| e.type == 'certification' }
|
16
27
|
end
|
17
28
|
|
18
29
|
def components
|
19
|
-
@components ||=
|
30
|
+
@components ||= data.select { |e| e.type == 'component' }
|
20
31
|
end
|
21
32
|
|
22
33
|
def standards
|
23
|
-
@standards ||=
|
34
|
+
@standards ||= data.select { |e| e.type == 'standard' }
|
24
35
|
end
|
25
36
|
|
26
37
|
# List of all attestations claimed by components in the system.
|
27
38
|
def attestations
|
28
|
-
@attestations ||=
|
29
|
-
@attestations = []
|
30
|
-
components.each do |c|
|
31
|
-
# Add a "component_key" field to each attestation.
|
32
|
-
c.attestations.map! { |e| e['component_key'] = c.component_key; e }
|
33
|
-
@attestations << c.attestations
|
34
|
-
end
|
35
|
-
@attestations.flatten!
|
36
|
-
end
|
39
|
+
@attestations ||= components.map(&:attestations).flatten
|
37
40
|
end
|
38
41
|
|
39
42
|
# List of all coverages.
|
40
43
|
def satisfies
|
41
|
-
@satisfies ||=
|
42
|
-
@satisfies = []
|
43
|
-
attestations.each do |a|
|
44
|
-
# Add an "attestation_key" field to each cover.
|
45
|
-
a.satisfies.map! { |e| e['component_key'] = a.commponent_key; e }
|
46
|
-
a.satisfies.map! { |e| e['attestation_key'] = a.attestation_summary; e }
|
47
|
-
@satisfies << a.satisfies
|
48
|
-
end
|
49
|
-
@satisfies.flatten!
|
50
|
-
end
|
44
|
+
@satisfies ||= attestations.map(&:satisfies).flatten
|
51
45
|
end
|
52
46
|
|
53
47
|
# List of all controls defined by standards in the system.
|
54
48
|
def controls
|
55
|
-
@controls
|
56
|
-
@controls = []
|
57
|
-
standards.each do |s|
|
58
|
-
# Add a "standard_key" field to each control.
|
59
|
-
s.controls.map! { |e| e['standard_key'] = s.standard_key; e }
|
60
|
-
@controls << s.controls
|
61
|
-
end
|
62
|
-
@controls.flatten!
|
63
|
-
end
|
49
|
+
@controls ||= standards.map(&:controls).flatten
|
64
50
|
end
|
65
51
|
|
66
52
|
# List of all families defined by standards in the system.
|
67
53
|
def families
|
68
|
-
@families
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
54
|
+
@families ||= standards.map(&:families).flatten
|
55
|
+
end
|
56
|
+
|
57
|
+
# List of required controls for all certifications.
|
58
|
+
def requires
|
59
|
+
@requires ||= certifications.map(&:requires).flatten
|
60
|
+
end
|
61
|
+
|
62
|
+
def dump(writable_dir)
|
63
|
+
TABLE_NAMES.each do |type|
|
64
|
+
write_csv method(type.to_sym).call, File.join(writable_dir, "#{type}.csv")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Convert array of hashes into a CSV.
|
69
|
+
def write_csv(ary, filename)
|
70
|
+
ary = ary.map do |e|
|
71
|
+
# Convert each element from RecursiveOStruct to a Hash.
|
72
|
+
e = e.is_a?(Hash) ? e : e.to_h
|
73
|
+
# Throw away nested hashes.
|
74
|
+
e.reject { |_, val| val.is_a?(Enumerable) }
|
75
|
+
end
|
76
|
+
warn "[INFO] write #{filename}"
|
77
|
+
CSV.open(filename, 'wb') do |csv|
|
78
|
+
column_names = ary.first.keys
|
79
|
+
csv << column_names
|
80
|
+
ary.each { |hash| csv << hash.values_at(*column_names) }
|
76
81
|
end
|
77
82
|
end
|
78
83
|
end
|
data/lib/octool/version.rb
CHANGED
data/lib/octool.rb
CHANGED
data/octool.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
== octool - Open Compliance Tool
|
2
2
|
|
3
|
-
v0.0.
|
3
|
+
v0.0.6
|
4
4
|
|
5
5
|
=== Global Options
|
6
6
|
=== --help
|
@@ -14,6 +14,18 @@ Display the program version
|
|
14
14
|
|
15
15
|
|
16
16
|
=== Commands
|
17
|
+
==== Command: <tt>csv path/to/system/config.yaml</tt>
|
18
|
+
export data to CSV
|
19
|
+
|
20
|
+
|
21
|
+
===== Options
|
22
|
+
===== -d|--dir path/to/output/dir
|
23
|
+
|
24
|
+
where to store outputs
|
25
|
+
|
26
|
+
[Default Value] /tmp
|
27
|
+
Default output directory respects env vars TMPDIR, TMP, TEMP
|
28
|
+
|
17
29
|
==== Command: <tt>help command</tt>
|
18
30
|
Shows a list of commands or help for one command
|
19
31
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: octool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Morgan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|