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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b1773ccc2811449ec1301e04c94fe2a565c9566
4
- data.tar.gz: 9886d0f7407336e7b778782f6caa54cfca8f8f63
3
+ metadata.gz: 175bd0dd088a192c67e4eedd12aa96df5e33a144
4
+ data.tar.gz: 869a4dc6ef1c6934a506585f84f681bb68820b64
5
5
  SHA512:
6
- metadata.gz: e96a86d1ab99fefc892834c2308963df602b03629e269dc5a02b1d103bf5b7347ed0e4e482e62d863f7ef7d14526629ea6fb8dcc46743013972272dbb6126b0c
7
- data.tar.gz: 433cc89a8ce6051507c4beae1f7aaa4769d3ae24c497a6118f0f035acdf43d9f4411eb759bbc651415c18ade1ff89ed2bda7e67a58c14018ef9fbf38218b915d
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
- By default the linter will search in the following paths.
78
+ The search paths will be loaded from the opencontrol.yaml file if it is available.
79
79
 
80
- These paths can all be overridden on the command line.
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
-
@@ -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
- 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 to
19
- true. Searches ./**/component.yaml or the search you
20
- 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 ./standards/*.yaml
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.
34
- -a, --all Run all types of validations (this is the default).
35
- -v, --version Show the version of this utility.
36
-
37
- Usage examples:
38
-
39
- # lint all components, standards and certifications in the current directory
40
- opencontrol-linter
41
-
42
- # lint all components subdir components
43
- opencontrol-linter --components './components/**/component.yaml'
44
-
45
- # lint all standards files found
46
- opencontrol-linter --standards
47
-
48
- # lint one component
49
- opencontrol-linter --components './components/AU_policy/component.yaml'
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
- DEFAULT_SPECIFICATION = {
54
+ CONFIG_FILENAME = './opencontrol.yaml'.freeze
55
+
56
+ PRESET = {
53
57
  action: :run,
54
- targets: [
55
- {
56
- type: :components,
57
- pattern: './components/**/component.yaml'
58
- },
59
- {
60
- type: :standards,
61
- pattern: './standards/*.yaml'
62
- },
63
- {
64
- type: :certifications,
65
- pattern: './certifications/*.yaml'
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
- 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'
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.targets_for_type(type, specification)
96
- specification[:targets].select { |t| t[:type] == type }
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.default_pattern_for_type(type)
100
- targets_for_type(type, DEFAULT_SPECIFICATION).first[:pattern]
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.add_target(type, opts, specification)
104
- # pick a reasonable default
105
- use_defaults = false
106
- use_defaults = default_pattern_for_type(type) if opts[type] == true
107
- specification[:targets].push(
108
- type: type,
109
- pattern: use_defaults || opts[type]
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.all_targets_selected?(opts, specification)
118
- opts[:all] || specification[:targets].empty?
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
- all_targets_selected?(opts, specification) && should_lint?(opts)
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 = DEFAULT_SPECIFICATION if use_default?(opts, 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
- exit(Opencontrol::Linter.run(specification)) if specification[:action] == :run
144
- show_version if specification[:action] == :version
145
- show_help if specification[:action] == :help
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
@@ -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.schema_for_document(type, document)
48
+ def self.schema_file_for_document(type, document)
50
49
  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]
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
- schema = schema_for_document(type, document)
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
- '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
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.validate_target(target)
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.collect do |filename|
93
- issues = validate(target[:type], filename)
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
- specification[:targets].collect do |target|
101
- validate_target(target)
102
- end.flatten
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
@@ -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 (#{issue.path}).
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}.
@@ -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.1'.freeze
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.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-25 00:00:00.000000000 Z
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: rubocop-rspec
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: 1.29.0
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: 1.29.0
221
+ version: 0.4.1
222
222
  - !ruby/object:Gem::Dependency
223
- name: simplecov
223
+ name: rubocop-rspec
224
224
  requirement: !ruby/object:Gem::Requirement
225
225
  requirements:
226
226
  - - "~>"
227
227
  - !ruby/object:Gem::Version
228
- version: 0.16.1
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: 0.16.1
235
+ version: 1.29.0
236
236
  - !ruby/object:Gem::Dependency
237
- name: rspec_junit_formatter
237
+ name: simplecov
238
238
  requirement: !ruby/object:Gem::Requirement
239
239
  requirements:
240
240
  - - "~>"
241
241
  - !ruby/object:Gem::Version
242
- version: 0.4.1
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.4.1
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 open control controls work together reliably.
252
+ Aims to provide quick tests that ensure controls work together reliably.
253
253
  email:
254
254
  executables:
255
255
  - opencontrol-linter