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