opencontrol-linter 0.1.1 → 0.1.2
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/README.md +6 -4
- data/lib/opencontrol/cli.rb +135 -83
- data/lib/opencontrol/linter.rb +46 -26
- data/lib/opencontrol/messages.rb +18 -1
- data/lib/opencontrol/version.rb +1 -1
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 175bd0dd088a192c67e4eedd12aa96df5e33a144
|
4
|
+
data.tar.gz: 869a4dc6ef1c6934a506585f84f681bb68820b64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ee06d87c4a273ac8731ab79a0073d094d094044f91db05c1c6fe5eee6e6f07eaa4a2a74a5d8f0a4401e76ef3be9e418fe865af5ae01e35242c845c2370d7cab
|
7
|
+
data.tar.gz: 2b32e890b5ecc89d4b52f3c0d7da04ce56a45e5f8fdd116b547ed9c7bb102bd75d675fb7f8a79496ba8173a813eb6da19f64e8225bb5882fbc10ad912a20392f
|
data/README.md
CHANGED
@@ -75,9 +75,11 @@ opencontrol-linter --components './components/AU_policy/component.yaml'
|
|
75
75
|
|
76
76
|
## Search Paths
|
77
77
|
|
78
|
-
|
78
|
+
The search paths will be loaded from the opencontrol.yaml file if it is available.
|
79
79
|
|
80
|
-
|
80
|
+
In the case that there is no opencontrol.yaml, by default the linter will search in the following paths.
|
81
|
+
|
82
|
+
These paths can all be overridden on the command line or in the opencontrol.yaml file.
|
81
83
|
```
|
82
84
|
components: '**/component.yaml' (recursive search for files named component)
|
83
85
|
standards: './standards/*.yaml'
|
@@ -88,7 +90,6 @@ opencontrol files: './opencontrol.yaml'
|
|
88
90
|
|
89
91
|
The following directory structure for compliance is typical. You can specify those that match your project.
|
90
92
|
```
|
91
|
-
Project Root
|
92
93
|
.
|
93
94
|
└── compliance
|
94
95
|
├── opencontrol.yaml
|
@@ -130,7 +131,9 @@ Open Control Linter supports the following Open Control schemas:
|
|
130
131
|
- Certification: (all v1.0 through v1.0)
|
131
132
|
|
132
133
|
## Related
|
134
|
+
|
133
135
|
http://opencontrol.cfapps.io/
|
136
|
+
|
134
137
|
https://github.com/opencontrol
|
135
138
|
|
136
139
|
## Team
|
@@ -139,4 +142,3 @@ Here's a list of Open Control Linter's core developers:
|
|
139
142
|
|
140
143
|
* [Adrian Kierman](https://github.com/adriankierman)
|
141
144
|
* James Connor
|
142
|
-
|
data/lib/opencontrol/cli.rb
CHANGED
@@ -10,75 +10,75 @@ module Opencontrol
|
|
10
10
|
# This module holds the Opencontrol Linter Command Line Interface.
|
11
11
|
module CLI
|
12
12
|
USAGE_TEXT = <<USAGE_TEXT.freeze
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
13
|
+
usage: opencontrol-linter
|
14
|
+
|
15
|
+
optional arguments:
|
16
|
+
-h, --help show this help message and exit
|
17
|
+
-c, --components
|
18
|
+
Specify component files should be checked. Defaults
|
19
|
+
to true. Searches ./**/component.yaml or the search
|
20
|
+
you optionally specify.
|
21
|
+
-n, --certifications
|
22
|
+
Specify certification (eg FISMA high)files should be
|
23
|
+
checked. Defaults to true. Searches
|
24
|
+
./certifications/*.yaml or the search you optionally
|
25
|
+
specify.
|
26
|
+
-s, --standards
|
27
|
+
Specify standard files (eg NIST 800.53) should be
|
28
|
+
checked. Defaults to true. Searches
|
29
|
+
./standards/*.yaml or the search you optionally
|
30
|
+
specify.
|
31
|
+
-o, --opencontrols, --opencontrol
|
32
|
+
Specify opencontrol file or files should be
|
33
|
+
checked. Defaults to true. Searches
|
34
|
+
./opencontrol.yaml or the search you optionally
|
35
|
+
specify.
|
36
|
+
-a, --all Run all types of validations (this is the default).
|
37
|
+
-v, --version Show the version of this utility.
|
38
|
+
|
39
|
+
Usage examples:
|
40
|
+
|
41
|
+
# lint all components, standards and certifications in the current directory
|
42
|
+
opencontrol-linter
|
43
|
+
|
44
|
+
# lint all components subdir components
|
45
|
+
opencontrol-linter --components './components/**/component.yaml'
|
46
|
+
|
47
|
+
# lint all standards files found
|
48
|
+
opencontrol-linter --standards
|
49
|
+
|
50
|
+
# lint one component
|
51
|
+
opencontrol-linter --components './components/AU_policy/component.yaml'
|
50
52
|
USAGE_TEXT
|
51
53
|
|
52
|
-
|
54
|
+
CONFIG_FILENAME = './opencontrol.yaml'.freeze
|
55
|
+
|
56
|
+
PRESET = {
|
53
57
|
action: :run,
|
54
|
-
targets:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
type: :opencontrols,
|
69
|
-
pattern: './opencontrol.yaml'
|
70
|
-
}
|
71
|
-
]
|
58
|
+
targets: {
|
59
|
+
components: [
|
60
|
+
'./components/**/component.yaml'
|
61
|
+
],
|
62
|
+
standards: [
|
63
|
+
'./standards/*.yaml'
|
64
|
+
],
|
65
|
+
certifications: [
|
66
|
+
'./certifications/*.yaml'
|
67
|
+
],
|
68
|
+
opencontrols: [
|
69
|
+
'./opencontrol.yaml'
|
70
|
+
]
|
71
|
+
}
|
72
72
|
}.freeze
|
73
73
|
|
74
74
|
ALIASES = {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
components: %w[component c],
|
76
|
+
standards: %w[standard s],
|
77
|
+
certifications: %w[certification n],
|
78
|
+
opencontrols: %w[opencontrol o],
|
79
|
+
all: 'a',
|
80
|
+
help: 'h',
|
81
|
+
version: 'v'
|
82
82
|
}.freeze
|
83
83
|
|
84
84
|
def self.show_help
|
@@ -92,41 +92,86 @@ USAGE_TEXT
|
|
92
92
|
0 # exit with no error
|
93
93
|
end
|
94
94
|
|
95
|
-
def self.
|
96
|
-
|
95
|
+
def self.add_target(type, opts, specification)
|
96
|
+
if use_default_pattern?(opts, type)
|
97
|
+
specification[:targets][type] = default_spec[:targets][type]
|
98
|
+
elsif opts[type].is_a?(String)
|
99
|
+
specification[:targets][type] = [opts[type]]
|
100
|
+
end
|
97
101
|
end
|
98
102
|
|
99
|
-
def self.
|
100
|
-
|
103
|
+
def self.use_default_pattern?(opts, type)
|
104
|
+
# this is set when the user uses a flag on the command line but doesnt
|
105
|
+
# add a specific file pattern - this way the user can restrict to just
|
106
|
+
# one type
|
107
|
+
opts[type] == true
|
101
108
|
end
|
102
109
|
|
103
|
-
def self.
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
110
|
+
def self.opencontrol_yaml_present?
|
111
|
+
File.exist?(CONFIG_FILENAME)
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.construct_defaults(config)
|
115
|
+
spec = {
|
116
|
+
action: :run,
|
117
|
+
targets: {}.merge(PRESET[:targets]).merge(config[:targets])
|
118
|
+
}
|
119
|
+
|
120
|
+
expand_components_filenames(spec)
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.load_config_from_yaml
|
124
|
+
yaml_config = YAML.load_file(CONFIG_FILENAME)
|
125
|
+
yaml_config = Hash[yaml_config.map { |(k, v)| [k.to_sym, v] }]
|
126
|
+
{
|
127
|
+
action: :run,
|
128
|
+
targets: yaml_config.select do |k, _v|
|
129
|
+
%i[components standards certifications].include?(k)
|
130
|
+
end
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.expand_components_filenames(spec)
|
135
|
+
# the config file usually omits the component files full filename
|
136
|
+
spec[:targets][:components] = spec[:targets][:components].collect do |f|
|
137
|
+
f += '/component.yaml' if File.directory?(f)
|
138
|
+
f
|
139
|
+
end
|
140
|
+
spec
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.default_spec
|
144
|
+
if opencontrol_yaml_present?
|
145
|
+
construct_defaults(load_config_from_yaml)
|
146
|
+
else
|
147
|
+
PRESET
|
148
|
+
end
|
111
149
|
end
|
112
150
|
|
113
151
|
def self.should_lint?(opts)
|
114
152
|
!(opts[:version] || opts[:help])
|
115
153
|
end
|
116
154
|
|
117
|
-
def self.
|
118
|
-
|
155
|
+
def self.all_targets_empty?(specification)
|
156
|
+
specification[:targets][:components].empty? &&
|
157
|
+
specification[:targets][:standards].empty? &&
|
158
|
+
specification[:targets][:certifications].empty? &&
|
159
|
+
specification[:targets][:opencontrols].empty?
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.all_selected?(opts, specification)
|
163
|
+
opts[:all] || all_targets_empty?(specification)
|
119
164
|
end
|
120
165
|
|
121
166
|
def self.use_default?(opts, specification)
|
122
|
-
|
167
|
+
all_selected?(opts, specification) && should_lint?(opts)
|
123
168
|
end
|
124
169
|
|
125
170
|
def self.parse_args(arguments)
|
126
171
|
opts = Rationalist.parse(arguments, alias: ALIASES)
|
127
172
|
specification = {
|
128
173
|
action: :run,
|
129
|
-
targets:
|
174
|
+
targets: Opencontrol::Linter.empty_targets
|
130
175
|
}
|
131
176
|
specification[:action] = :version if opts[:version]
|
132
177
|
specification[:action] = :help if opts[:help]
|
@@ -134,15 +179,22 @@ USAGE_TEXT
|
|
134
179
|
add_target(:standards, opts, specification) if opts[:standards]
|
135
180
|
add_target(:certifications, opts, specification) if opts[:certifications]
|
136
181
|
add_target(:opencontrols, opts, specification) if opts[:opencontrols]
|
137
|
-
specification =
|
182
|
+
specification = default_spec if use_default?(opts, specification)
|
138
183
|
specification
|
139
184
|
end
|
140
185
|
|
141
186
|
def self.run_with_args(args)
|
142
187
|
specification = parse_args(args)
|
143
|
-
|
144
|
-
|
145
|
-
|
188
|
+
result = 0
|
189
|
+
case specification[:action]
|
190
|
+
when :run
|
191
|
+
result = Opencontrol::Linter.run(specification)
|
192
|
+
when :version
|
193
|
+
result = show_version
|
194
|
+
when :help
|
195
|
+
result = show_help
|
196
|
+
end
|
197
|
+
exit(result)
|
146
198
|
end
|
147
199
|
end
|
148
200
|
end
|
data/lib/opencontrol/linter.rb
CHANGED
@@ -9,7 +9,6 @@ require 'pp'
|
|
9
9
|
module Opencontrol
|
10
10
|
# This module holds the Opencontrol Linter Command Line Interface.
|
11
11
|
module Linter
|
12
|
-
|
13
12
|
# @param [String] version
|
14
13
|
def self.find_schema(type, version)
|
15
14
|
dir = __dir__
|
@@ -46,18 +45,9 @@ module Opencontrol
|
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
|
-
def self.
|
48
|
+
def self.schema_file_for_document(type, document)
|
50
49
|
version = document['schema_version'] || '1.0.0'
|
51
|
-
|
52
|
-
load_schema(schema_file)
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.targets_for_type(type, specification)
|
56
|
-
specification[:targets].select { |t| t[:type] == type }
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.default_pattern_for_type(type)
|
60
|
-
targets_for_type(type, DEFAULT_SPECIFICATION).first[:pattern]
|
50
|
+
find_schema(type, version)
|
61
51
|
end
|
62
52
|
|
63
53
|
def self.validate(type, filename)
|
@@ -65,7 +55,12 @@ module Opencontrol
|
|
65
55
|
# document = Kwalify::Yaml.load_file(filename)
|
66
56
|
## or
|
67
57
|
document = YAML.load_file(filename)
|
68
|
-
|
58
|
+
schema_filename = schema_file_for_document(type, document)
|
59
|
+
unless File.exist?(schema_filename)
|
60
|
+
return [schema_not_found_issue(filename, schema_filename)]
|
61
|
+
end
|
62
|
+
|
63
|
+
schema = load_schema(schema_filename)
|
69
64
|
|
70
65
|
validator = Kwalify::Validator.new(schema)
|
71
66
|
validator.validate(document)
|
@@ -73,36 +68,61 @@ module Opencontrol
|
|
73
68
|
|
74
69
|
def self.files_not_found_issue
|
75
70
|
Kwalify::BaseError.new(
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
'No validation files found for the pattern supplied. \
|
72
|
+
Adding an issue to avoid failing silently.',
|
73
|
+
nil,
|
74
|
+
nil,
|
75
|
+
nil,
|
76
|
+
:linter_files_not_found_issue
|
82
77
|
)
|
83
78
|
end
|
84
79
|
|
85
|
-
def self.
|
80
|
+
def self.schema_not_found_issue(filename, schema_filename)
|
81
|
+
Kwalify::BaseError.new(
|
82
|
+
'No schema files found for the pattern supplied.',
|
83
|
+
filename,
|
84
|
+
schema_filename,
|
85
|
+
nil,
|
86
|
+
:schema_files_not_found_issue
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.validate_pattern(target)
|
86
91
|
filenames = Dir[target[:pattern]]
|
92
|
+
issues = []
|
87
93
|
if filenames.empty?
|
88
94
|
issues = [files_not_found_issue]
|
89
95
|
show_issues(issues, target[:pattern])
|
90
96
|
return issues
|
91
97
|
end
|
92
|
-
filenames.
|
93
|
-
issues
|
98
|
+
filenames.each do |filename|
|
99
|
+
issues += validate(target[:type], filename)
|
94
100
|
show_issues(issues, filename)
|
95
|
-
issues
|
96
101
|
end
|
102
|
+
issues
|
97
103
|
end
|
98
104
|
|
99
105
|
def self.validate_all(specification)
|
100
|
-
|
101
|
-
|
102
|
-
|
106
|
+
issues = []
|
107
|
+
specification[:targets].each do |type, patterns|
|
108
|
+
patterns.each do |pattern|
|
109
|
+
issues += validate_pattern(type: type, pattern: pattern)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
issues
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.empty_targets
|
116
|
+
{
|
117
|
+
components: [],
|
118
|
+
standards: [],
|
119
|
+
certifications: [],
|
120
|
+
opencontrols: []
|
121
|
+
}
|
103
122
|
end
|
104
123
|
|
105
124
|
def self.run(specification)
|
125
|
+
specification[:targets] = empty_targets.merge(specification[:targets])
|
106
126
|
issues = validate_all(specification)
|
107
127
|
if !issues.empty?
|
108
128
|
puts "Complete. #{issues.length} issues found.".red
|
data/lib/opencontrol/messages.rb
CHANGED
@@ -20,10 +20,27 @@ module Opencontrol
|
|
20
20
|
<<-MESSAGE
|
21
21
|
At: YAML path #{issue.path}.
|
22
22
|
Expected: A key allowed by the schema.
|
23
|
-
Actual: A key was found that is not defined in the schema
|
23
|
+
Actual: A key was found that is not defined in the schema
|
24
|
+
(#{issue.path}).
|
24
25
|
To fix this: Its possible the key found is a typo,
|
25
26
|
Remove #{issue.path} or correct the key.
|
26
27
|
MESSAGE
|
28
|
+
when :schema_files_not_found_issue
|
29
|
+
<<-MESSAGE
|
30
|
+
At: File path #{issue.path}.
|
31
|
+
Expected: A valid schema version that is currently supported.
|
32
|
+
Actual: No valid schema file found
|
33
|
+
(#{issue.value}).
|
34
|
+
To fix this: Either provide a valid schema file or adjust the schema
|
35
|
+
version to a known schema. See
|
36
|
+
https://github.com/adriankierman/opencontrol-linter
|
37
|
+
or
|
38
|
+
https://github.com/opencontrol/schemas/tree/master/kwalify
|
39
|
+
for schemas.
|
40
|
+
Typically you will want to correct the schema
|
41
|
+
version number indicated in your file at
|
42
|
+
#{issue.path}.
|
43
|
+
MESSAGE
|
27
44
|
else
|
28
45
|
<<-MESSAGE
|
29
46
|
At: YAML path #{issue.path}.
|
data/lib/opencontrol/version.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Opencontrol
|
4
4
|
# This module holds the Opencontrol Linter version information.
|
5
5
|
module Version
|
6
|
-
STRING = '0.1.
|
6
|
+
STRING = '0.1.2'.freeze
|
7
7
|
|
8
8
|
MSG = '%<version>s (using Parser %<parser_version>s, running on ' \
|
9
9
|
'%<ruby_engine>s %<ruby_version>s %<ruby_platform>s)'.freeze
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opencontrol-linter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Kierman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-02-
|
12
|
+
date: 2019-02-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: colorize
|
@@ -206,50 +206,50 @@ dependencies:
|
|
206
206
|
- !ruby/object:Gem::Version
|
207
207
|
version: 3.8.0
|
208
208
|
- !ruby/object:Gem::Dependency
|
209
|
-
name:
|
209
|
+
name: rspec_junit_formatter
|
210
210
|
requirement: !ruby/object:Gem::Requirement
|
211
211
|
requirements:
|
212
212
|
- - "~>"
|
213
213
|
- !ruby/object:Gem::Version
|
214
|
-
version:
|
214
|
+
version: 0.4.1
|
215
215
|
type: :development
|
216
216
|
prerelease: false
|
217
217
|
version_requirements: !ruby/object:Gem::Requirement
|
218
218
|
requirements:
|
219
219
|
- - "~>"
|
220
220
|
- !ruby/object:Gem::Version
|
221
|
-
version:
|
221
|
+
version: 0.4.1
|
222
222
|
- !ruby/object:Gem::Dependency
|
223
|
-
name:
|
223
|
+
name: rubocop-rspec
|
224
224
|
requirement: !ruby/object:Gem::Requirement
|
225
225
|
requirements:
|
226
226
|
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
|
-
version:
|
228
|
+
version: 1.29.0
|
229
229
|
type: :development
|
230
230
|
prerelease: false
|
231
231
|
version_requirements: !ruby/object:Gem::Requirement
|
232
232
|
requirements:
|
233
233
|
- - "~>"
|
234
234
|
- !ruby/object:Gem::Version
|
235
|
-
version:
|
235
|
+
version: 1.29.0
|
236
236
|
- !ruby/object:Gem::Dependency
|
237
|
-
name:
|
237
|
+
name: simplecov
|
238
238
|
requirement: !ruby/object:Gem::Requirement
|
239
239
|
requirements:
|
240
240
|
- - "~>"
|
241
241
|
- !ruby/object:Gem::Version
|
242
|
-
version: 0.
|
242
|
+
version: 0.16.1
|
243
243
|
type: :development
|
244
244
|
prerelease: false
|
245
245
|
version_requirements: !ruby/object:Gem::Requirement
|
246
246
|
requirements:
|
247
247
|
- - "~>"
|
248
248
|
- !ruby/object:Gem::Version
|
249
|
-
version: 0.
|
249
|
+
version: 0.16.1
|
250
250
|
description: |2
|
251
251
|
Automatic Open Control schema checking tool.
|
252
|
-
Aims to provide quick tests that ensure
|
252
|
+
Aims to provide quick tests that ensure controls work together reliably.
|
253
253
|
email:
|
254
254
|
executables:
|
255
255
|
- opencontrol-linter
|