opencontrol-linter 0.1 → 0.1.1
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 +48 -0
- data/lib/opencontrol.rb +1 -0
- data/lib/opencontrol/cli.rb +23 -106
- data/lib/opencontrol/linter.rb +115 -0
- data/lib/opencontrol/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b1773ccc2811449ec1301e04c94fe2a565c9566
|
4
|
+
data.tar.gz: 9886d0f7407336e7b778782f6caa54cfca8f8f63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e96a86d1ab99fefc892834c2308963df602b03629e269dc5a02b1d103bf5b7347ed0e4e482e62d863f7ef7d14526629ea6fb8dcc46743013972272dbb6126b0c
|
7
|
+
data.tar.gz: 433cc89a8ce6051507c4beae1f7aaa4769d3ae24c497a6118f0f035acdf43d9f4411eb759bbc651415c18ade1ff89ed2bda7e67a58c14018ef9fbf38218b915d
|
data/README.md
CHANGED
@@ -73,6 +73,54 @@ opencontrol-linter --components './components/AU_policy/component.yaml'
|
|
73
73
|
|
74
74
|
```
|
75
75
|
|
76
|
+
## Search Paths
|
77
|
+
|
78
|
+
By default the linter will search in the following paths.
|
79
|
+
|
80
|
+
These paths can all be overridden on the command line.
|
81
|
+
```
|
82
|
+
components: '**/component.yaml' (recursive search for files named component)
|
83
|
+
standards: './standards/*.yaml'
|
84
|
+
certifications: './certifications/*.yaml'
|
85
|
+
opencontrol files: './opencontrol.yaml'
|
86
|
+
|
87
|
+
```
|
88
|
+
|
89
|
+
The following directory structure for compliance is typical. You can specify those that match your project.
|
90
|
+
```
|
91
|
+
Project Root
|
92
|
+
.
|
93
|
+
└── compliance
|
94
|
+
├── opencontrol.yaml
|
95
|
+
├── certifications
|
96
|
+
│ └── FredRAMP-high.yaml
|
97
|
+
├── components
|
98
|
+
│ ├── AU_policy
|
99
|
+
│ │ └── component.yaml
|
100
|
+
│ └── AWS_core
|
101
|
+
│ └── component.yaml
|
102
|
+
└── standards
|
103
|
+
└── FRIST-800-53.yaml
|
104
|
+
|
105
|
+
```
|
106
|
+
|
107
|
+
## Development
|
108
|
+
|
109
|
+
Clone this repo
|
110
|
+
```
|
111
|
+
git clone https://github.com/adriankierman/opencontrol-linter.git
|
112
|
+
|
113
|
+
```
|
114
|
+
Install Dependencies
|
115
|
+
```
|
116
|
+
bundle install
|
117
|
+
```
|
118
|
+
|
119
|
+
To run tests:
|
120
|
+
```
|
121
|
+
rake spec
|
122
|
+
```
|
123
|
+
|
76
124
|
## Compatibility
|
77
125
|
|
78
126
|
Open Control Linter supports the following Open Control schemas:
|
data/lib/opencontrol.rb
CHANGED
data/lib/opencontrol/cli.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'kwalify'
|
2
1
|
require 'yaml'
|
3
2
|
require 'opencontrol'
|
4
3
|
require 'rationalist'
|
@@ -28,6 +27,10 @@ module Opencontrol
|
|
28
27
|
Specify standard files (eg NIST 800.53) should be
|
29
28
|
checked. Defaults to true. Searches ./standards/*.yaml
|
30
29
|
or the search you optionally specify.
|
30
|
+
-o, --opencontrols, --opencontrol
|
31
|
+
Specify opencontrol file or files should be
|
32
|
+
checked. Defaults to true. Searches ./opencontrol.yaml
|
33
|
+
or the search you optionally specify.
|
31
34
|
-a, --all Run all types of validations (this is the default).
|
32
35
|
-v, --version Show the version of this utility.
|
33
36
|
|
@@ -51,7 +54,7 @@ USAGE_TEXT
|
|
51
54
|
targets: [
|
52
55
|
{
|
53
56
|
type: :components,
|
54
|
-
pattern: '
|
57
|
+
pattern: './components/**/component.yaml'
|
55
58
|
},
|
56
59
|
{
|
57
60
|
type: :standards,
|
@@ -60,10 +63,24 @@ USAGE_TEXT
|
|
60
63
|
{
|
61
64
|
type: :certifications,
|
62
65
|
pattern: './certifications/*.yaml'
|
66
|
+
},
|
67
|
+
{
|
68
|
+
type: :opencontrols,
|
69
|
+
pattern: './opencontrol.yaml'
|
63
70
|
}
|
64
71
|
]
|
65
72
|
}.freeze
|
66
73
|
|
74
|
+
ALIASES = {
|
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
|
+
}.freeze
|
83
|
+
|
67
84
|
def self.show_help
|
68
85
|
puts USAGE_TEXT
|
69
86
|
0 # exit with no error
|
@@ -75,46 +92,6 @@ USAGE_TEXT
|
|
75
92
|
0 # exit with no error
|
76
93
|
end
|
77
94
|
|
78
|
-
# @param [String] version
|
79
|
-
def self.find_schema(type, version)
|
80
|
-
dir = __dir__
|
81
|
-
case type
|
82
|
-
when :components
|
83
|
-
"#{dir}/../../vendor/schemas/kwalify/component/v#{version}.yaml"
|
84
|
-
when :standards
|
85
|
-
"#{dir}/../../vendor/schemas/kwalify/standard/v#{version}.yaml"
|
86
|
-
when :certifications
|
87
|
-
"#{dir}/../../vendor/schemas/kwalify/certification/v#{version}.yaml"
|
88
|
-
else
|
89
|
-
throw "Unknown type of schema specified #{type} " \
|
90
|
-
"tried to get schema version #{version}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.load_schema(schema_file)
|
95
|
-
## load schema data
|
96
|
-
# Kwalify::Yaml.load_file(schema_file)
|
97
|
-
## or
|
98
|
-
YAML.load_file(schema_file)
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.show_issues(issues, filename)
|
102
|
-
if issues && !issues.empty?
|
103
|
-
puts "✗ #{filename}".red
|
104
|
-
issues.each do |issue|
|
105
|
-
puts Opencontrol::Messages.detail(issue).yellow
|
106
|
-
end
|
107
|
-
else
|
108
|
-
puts "✓ #{filename}".green
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.schema_for_document(type, document)
|
113
|
-
version = document['schema_version'] || '1.0.0'
|
114
|
-
schema_file = find_schema(type, version)
|
115
|
-
load_schema(schema_file)
|
116
|
-
end
|
117
|
-
|
118
95
|
def self.targets_for_type(type, specification)
|
119
96
|
specification[:targets].select { |t| t[:type] == type }
|
120
97
|
end
|
@@ -133,48 +110,6 @@ USAGE_TEXT
|
|
133
110
|
)
|
134
111
|
end
|
135
112
|
|
136
|
-
def self.validate(type, filename)
|
137
|
-
## load document
|
138
|
-
# document = Kwalify::Yaml.load_file(filename)
|
139
|
-
## or
|
140
|
-
document = YAML.load_file(filename)
|
141
|
-
schema = schema_for_document(type, document)
|
142
|
-
|
143
|
-
validator = Kwalify::Validator.new(schema)
|
144
|
-
validator.validate(document)
|
145
|
-
end
|
146
|
-
|
147
|
-
def self.files_not_found_issue
|
148
|
-
Kwalify::BaseError.new(
|
149
|
-
'No validation files found for the pattern supplied. \
|
150
|
-
Adding an issue to avoid failing silently.',
|
151
|
-
nil,
|
152
|
-
nil,
|
153
|
-
nil,
|
154
|
-
:linter_files_not_found_issue
|
155
|
-
)
|
156
|
-
end
|
157
|
-
|
158
|
-
def self.validate_target(target)
|
159
|
-
filenames = Dir[target[:pattern]]
|
160
|
-
if filenames.empty?
|
161
|
-
issues = [files_not_found_issue]
|
162
|
-
show_issues(issues, target[:pattern])
|
163
|
-
return issues
|
164
|
-
end
|
165
|
-
filenames.collect do |filename|
|
166
|
-
issues = validate(target[:type], filename)
|
167
|
-
show_issues(issues, filename)
|
168
|
-
issues
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def self.validate_all(specification)
|
173
|
-
specification[:targets].collect do |target|
|
174
|
-
validate_target(target)
|
175
|
-
end.flatten
|
176
|
-
end
|
177
|
-
|
178
113
|
def self.should_lint?(opts)
|
179
114
|
!(opts[:version] || opts[:help])
|
180
115
|
end
|
@@ -187,15 +122,6 @@ USAGE_TEXT
|
|
187
122
|
all_targets_selected?(opts, specification) && should_lint?(opts)
|
188
123
|
end
|
189
124
|
|
190
|
-
ALIASES = {
|
191
|
-
components: %w[component c],
|
192
|
-
standards: %w[standard s],
|
193
|
-
certifications: %w[certification n],
|
194
|
-
all: 'a',
|
195
|
-
help: 'h',
|
196
|
-
version: 'v'
|
197
|
-
}.freeze
|
198
|
-
|
199
125
|
def self.parse_args(arguments)
|
200
126
|
opts = Rationalist.parse(arguments, alias: ALIASES)
|
201
127
|
specification = {
|
@@ -207,25 +133,16 @@ USAGE_TEXT
|
|
207
133
|
add_target(:components, opts, specification) if opts[:components]
|
208
134
|
add_target(:standards, opts, specification) if opts[:standards]
|
209
135
|
add_target(:certifications, opts, specification) if opts[:certifications]
|
136
|
+
add_target(:opencontrols, opts, specification) if opts[:opencontrols]
|
210
137
|
specification = DEFAULT_SPECIFICATION if use_default?(opts, specification)
|
211
138
|
specification
|
212
139
|
end
|
213
140
|
|
214
|
-
def self.run(specification)
|
215
|
-
issues = validate_all(specification)
|
216
|
-
if !issues.empty?
|
217
|
-
puts "Complete. #{issues.length} issues found.".red
|
218
|
-
else
|
219
|
-
puts 'Complete. No problems found.'.green
|
220
|
-
end
|
221
|
-
issues.length
|
222
|
-
end
|
223
|
-
|
224
141
|
def self.run_with_args(args)
|
225
142
|
specification = parse_args(args)
|
226
|
-
exit(run(specification)) if specification[:action] == :run
|
227
|
-
show_version
|
228
|
-
show_help
|
143
|
+
exit(Opencontrol::Linter.run(specification)) if specification[:action] == :run
|
144
|
+
show_version if specification[:action] == :version
|
145
|
+
show_help if specification[:action] == :help
|
229
146
|
end
|
230
147
|
end
|
231
148
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'kwalify'
|
2
|
+
require 'yaml'
|
3
|
+
require 'opencontrol'
|
4
|
+
require 'colorize'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
module Opencontrol
|
10
|
+
# This module holds the Opencontrol Linter Command Line Interface.
|
11
|
+
module Linter
|
12
|
+
|
13
|
+
# @param [String] version
|
14
|
+
def self.find_schema(type, version)
|
15
|
+
dir = __dir__
|
16
|
+
case type
|
17
|
+
when :components
|
18
|
+
"#{dir}/../../vendor/schemas/kwalify/component/v#{version}.yaml"
|
19
|
+
when :standards
|
20
|
+
"#{dir}/../../vendor/schemas/kwalify/standard/v#{version}.yaml"
|
21
|
+
when :certifications
|
22
|
+
"#{dir}/../../vendor/schemas/kwalify/certification/v#{version}.yaml"
|
23
|
+
when :opencontrols
|
24
|
+
"#{dir}/../../vendor/schemas/kwalify/opencontrol/v#{version}.yaml"
|
25
|
+
else
|
26
|
+
throw "Unknown type of schema specified #{type} " \
|
27
|
+
"tried to get schema version #{version}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.load_schema(schema_file)
|
32
|
+
## load schema data
|
33
|
+
# Kwalify::Yaml.load_file(schema_file)
|
34
|
+
## or
|
35
|
+
YAML.load_file(schema_file)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.show_issues(issues, filename)
|
39
|
+
if issues && !issues.empty?
|
40
|
+
puts "✗ #{filename}".red
|
41
|
+
issues.each do |issue|
|
42
|
+
puts Opencontrol::Messages.detail(issue).yellow
|
43
|
+
end
|
44
|
+
else
|
45
|
+
puts "✓ #{filename}".green
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.schema_for_document(type, document)
|
50
|
+
version = document['schema_version'] || '1.0.0'
|
51
|
+
schema_file = find_schema(type, version)
|
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]
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.validate(type, filename)
|
64
|
+
## load document
|
65
|
+
# document = Kwalify::Yaml.load_file(filename)
|
66
|
+
## or
|
67
|
+
document = YAML.load_file(filename)
|
68
|
+
schema = schema_for_document(type, document)
|
69
|
+
|
70
|
+
validator = Kwalify::Validator.new(schema)
|
71
|
+
validator.validate(document)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.files_not_found_issue
|
75
|
+
Kwalify::BaseError.new(
|
76
|
+
'No validation files found for the pattern supplied. \
|
77
|
+
Adding an issue to avoid failing silently.',
|
78
|
+
nil,
|
79
|
+
nil,
|
80
|
+
nil,
|
81
|
+
:linter_files_not_found_issue
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.validate_target(target)
|
86
|
+
filenames = Dir[target[:pattern]]
|
87
|
+
if filenames.empty?
|
88
|
+
issues = [files_not_found_issue]
|
89
|
+
show_issues(issues, target[:pattern])
|
90
|
+
return issues
|
91
|
+
end
|
92
|
+
filenames.collect do |filename|
|
93
|
+
issues = validate(target[:type], filename)
|
94
|
+
show_issues(issues, filename)
|
95
|
+
issues
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.validate_all(specification)
|
100
|
+
specification[:targets].collect do |target|
|
101
|
+
validate_target(target)
|
102
|
+
end.flatten
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.run(specification)
|
106
|
+
issues = validate_all(specification)
|
107
|
+
if !issues.empty?
|
108
|
+
puts "Complete. #{issues.length} issues found.".red
|
109
|
+
else
|
110
|
+
puts 'Complete. No problems found.'.green
|
111
|
+
end
|
112
|
+
issues.length
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
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'.freeze
|
6
|
+
STRING = '0.1.1'.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:
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Kierman
|
@@ -263,6 +263,7 @@ files:
|
|
263
263
|
- exe/opencontrol-linter
|
264
264
|
- lib/opencontrol.rb
|
265
265
|
- lib/opencontrol/cli.rb
|
266
|
+
- lib/opencontrol/linter.rb
|
266
267
|
- lib/opencontrol/messages.rb
|
267
268
|
- lib/opencontrol/version.rb
|
268
269
|
- vendor/README.md
|