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 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