inspec-core 5.18.14 → 5.22.3
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/Gemfile +19 -17
- data/inspec-core.gemspec +22 -22
- data/lib/inspec/base_cli.rb +19 -17
- data/lib/inspec/cli.rb +27 -25
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dsl.rb +9 -5
- data/lib/inspec/enhanced_outcomes.rb +19 -0
- data/lib/inspec/env_printer.rb +1 -1
- data/lib/inspec/exceptions.rb +2 -0
- data/lib/inspec/formatters/base.rb +69 -16
- data/lib/inspec/plugin/v2/loader.rb +19 -8
- data/lib/inspec/plugin/v2/plugin_types/reporter.rb +1 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +54 -0
- data/lib/inspec/profile.rb +9 -8
- data/lib/inspec/reporters/base.rb +1 -0
- data/lib/inspec/reporters/cli.rb +94 -3
- data/lib/inspec/reporters/json.rb +3 -1
- data/lib/inspec/reporters/yaml.rb +3 -1
- data/lib/inspec/reporters.rb +2 -1
- data/lib/inspec/resources/file.rb +1 -1
- data/lib/inspec/resources/http.rb +5 -5
- data/lib/inspec/resources/lxc.rb +65 -9
- data/lib/inspec/resources/mongodb_session.rb +5 -0
- data/lib/inspec/resources/nftables.rb +251 -0
- data/lib/inspec/resources/oracledb_session.rb +13 -4
- data/lib/inspec/resources/podman.rb +353 -0
- data/lib/inspec/resources/podman_container.rb +84 -0
- data/lib/inspec/resources/podman_image.rb +108 -0
- data/lib/inspec/resources/podman_network.rb +81 -0
- data/lib/inspec/resources/podman_pod.rb +101 -0
- data/lib/inspec/resources/podman_volume.rb +87 -0
- data/lib/inspec/resources/postgres_session.rb +2 -1
- data/lib/inspec/resources/service.rb +1 -1
- data/lib/inspec/resources.rb +1 -0
- data/lib/inspec/rule.rb +54 -17
- data/lib/inspec/run_data/control.rb +6 -0
- data/lib/inspec/run_data/statistics.rb +8 -2
- data/lib/inspec/runner.rb +18 -8
- data/lib/inspec/runner_rspec.rb +3 -2
- data/lib/inspec/schema/exec_json.rb +78 -2
- data/lib/inspec/schema/output_schema.rb +4 -1
- data/lib/inspec/schema/profile_json.rb +46 -0
- data/lib/inspec/schema.rb +91 -0
- data/lib/inspec/utils/convert.rb +8 -0
- data/lib/inspec/utils/podman.rb +24 -0
- data/lib/inspec/utils/simpleconfig.rb +10 -2
- data/lib/inspec/utils/waivers/csv_file_reader.rb +34 -0
- data/lib/inspec/utils/waivers/excel_file_reader.rb +39 -0
- data/lib/inspec/utils/waivers/json_file_reader.rb +15 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +61 -0
- data/lib/matchers/matchers.rb +15 -2
- data/lib/plugins/inspec-init/templates/profiles/alicloud/README.md +27 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/controls/example.rb +10 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/inputs.yml +1 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/inspec.yml +14 -0
- data/lib/plugins/inspec-reporter-html2/README.md +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +7 -1
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +10 -6
- data/lib/plugins/inspec-reporter-html2/templates/default.css +12 -0
- data/lib/plugins/inspec-reporter-html2/templates/selector.html.erb +7 -1
- data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +5 -2
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +39 -13
- metadata +26 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 257ccbe0a55a1779ee75f8d6e9e8e0ff612990c123e5cdb10d8cf1e19dbade54
|
4
|
+
data.tar.gz: 820f9a0ec86451f48f65f229befe175cf937648ddb5669df1c8a7c27ebfb234b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8150cdd9aca6ac14ae762dd4b6d09867dab6651f0a0705a28f7256a94683a1fd59b7841bfc69e1a362c253d6c2a847d2e9a03b901dd20118ecc1566b4496a8a9
|
7
|
+
data.tar.gz: a3469cb7fa6786e1d9416e9493fed402ccfb6c8e6ac0a2d40a0029ab63c09b09671cf6729736899ed1a039ca75e36a6a57428deba9a8c5d6dbf0975711a06d13
|
data/Gemfile
CHANGED
@@ -23,9 +23,8 @@ group :omnibus do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
group :test do
|
26
|
-
gem "chefstyle", "~> 2.
|
26
|
+
gem "chefstyle", "~> 2.2.2"
|
27
27
|
gem "concurrent-ruby", "~> 1.0"
|
28
|
-
gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
|
29
28
|
gem "json_schemer", ">= 0.2.1", "< 0.2.19"
|
30
29
|
gem "m"
|
31
30
|
gem "minitest-sprint", "~> 1.0"
|
@@ -35,30 +34,33 @@ group :test do
|
|
35
34
|
gem "pry-byebug"
|
36
35
|
gem "pry", "~> 0.10"
|
37
36
|
gem "rake", ">= 10"
|
38
|
-
gem "ruby-progressbar", "~> 1.8"
|
39
37
|
gem "simplecov", "~> 0.21"
|
40
38
|
gem "simplecov_json_formatter"
|
41
39
|
gem "webmock", "~> 3.0"
|
40
|
+
|
41
|
+
if Gem.ruby_version >= Gem::Version.new("3.0.0")
|
42
|
+
# html-proofer has a dep on io-event, which is ruby-3 only
|
43
|
+
gem "html-proofer", "~> 3.19.4", platforms: :ruby # do not attempt to run proofer on windows. Pinned to 3.19.4 as test is breaking in updated versions.
|
44
|
+
end
|
42
45
|
end
|
43
46
|
|
44
47
|
group :deploy do
|
45
48
|
gem "inquirer"
|
46
49
|
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
gem "
|
54
|
-
|
55
|
-
|
56
|
-
gem "
|
57
|
-
gem "kitchen-dokken", ">= 2.11"
|
58
|
-
gem "git"
|
51
|
+
group :kitchen do
|
52
|
+
gem "berkshelf"
|
53
|
+
|
54
|
+
# Chef 18 requires ruby 3
|
55
|
+
if Gem.ruby_version >= Gem::Version.new("3.0.0")
|
56
|
+
gem "chef", ">= 17.0"
|
57
|
+
else
|
58
|
+
# Ruby 2.7 presumably - TODO remove this when 2.7 is sunsetted
|
59
|
+
gem "chef", "~> 16.0"
|
59
60
|
end
|
60
|
-
end
|
61
61
|
|
62
|
-
|
63
|
-
gem "
|
62
|
+
gem "test-kitchen", ">= 2.8"
|
63
|
+
gem "kitchen-inspec", ">= 2.0"
|
64
|
+
gem "kitchen-dokken", ">= 2.11"
|
65
|
+
gem "git"
|
64
66
|
end
|
data/inspec-core.gemspec
CHANGED
@@ -18,32 +18,32 @@ Gem::Specification.new do |spec|
|
|
18
18
|
# the gemfile and gemspec are necessary for appbundler so don't remove it
|
19
19
|
spec.files =
|
20
20
|
Dir.glob("{{lib,etc}/**/*,LICENSE,Gemfile,inspec-core.gemspec}")
|
21
|
-
.grep_v(%r{(?<!inspec-init/templates/profiles/)(aws|azure|gcp)})
|
21
|
+
.grep_v(%r{(?<!inspec-init/templates/profiles/)(aws|azure|gcp|alicloud)})
|
22
22
|
.grep_v(%r{lib/plugins/.*/test/})
|
23
23
|
.reject { |f| File.directory?(f) }
|
24
24
|
|
25
25
|
# Implementation dependencies
|
26
|
-
spec.add_dependency "chef-telemetry",
|
27
|
-
spec.add_dependency "license-acceptance",
|
28
|
-
spec.add_dependency "thor",
|
29
|
-
spec.add_dependency "method_source",
|
30
|
-
spec.add_dependency "rubyzip",
|
31
|
-
spec.add_dependency "rspec",
|
32
|
-
spec.add_dependency "rspec-its",
|
33
|
-
spec.add_dependency "pry",
|
34
|
-
spec.add_dependency "hashie",
|
35
|
-
spec.add_dependency "mixlib-log",
|
36
|
-
spec.add_dependency "sslshake",
|
37
|
-
spec.add_dependency "parallel",
|
38
|
-
spec.add_dependency "faraday",
|
39
|
-
spec.add_dependency "
|
40
|
-
spec.add_dependency "tty-table",
|
41
|
-
spec.add_dependency "tty-prompt",
|
42
|
-
spec.add_dependency "tomlrb",
|
43
|
-
spec.add_dependency "addressable",
|
44
|
-
spec.add_dependency "parslet",
|
45
|
-
spec.add_dependency "semverse",
|
46
|
-
spec.add_dependency "multipart-post",
|
26
|
+
spec.add_dependency "chef-telemetry", "~> 1.0", ">= 1.0.8" # 1.0.8+ removes the http dep
|
27
|
+
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 3.0"
|
28
|
+
spec.add_dependency "thor", ">= 0.20", "< 2.0"
|
29
|
+
spec.add_dependency "method_source", ">= 0.8", "< 2.0"
|
30
|
+
spec.add_dependency "rubyzip", ">= 1.2.2", "< 3.0"
|
31
|
+
spec.add_dependency "rspec", ">= 3.9", "<= 3.11"
|
32
|
+
spec.add_dependency "rspec-its", "~> 1.2"
|
33
|
+
spec.add_dependency "pry", "~> 0.13"
|
34
|
+
spec.add_dependency "hashie", ">= 3.4", "< 5.0"
|
35
|
+
spec.add_dependency "mixlib-log", "~> 3.0"
|
36
|
+
spec.add_dependency "sslshake", "~> 1.2"
|
37
|
+
spec.add_dependency "parallel", "~> 1.9"
|
38
|
+
spec.add_dependency "faraday", ">= 1", "< 3"
|
39
|
+
spec.add_dependency "faraday-follow_redirects", "~> 0.3"
|
40
|
+
spec.add_dependency "tty-table", "~> 0.10"
|
41
|
+
spec.add_dependency "tty-prompt", "~> 0.17"
|
42
|
+
spec.add_dependency "tomlrb", ">= 1.2", "< 2.1"
|
43
|
+
spec.add_dependency "addressable", "~> 2.4"
|
44
|
+
spec.add_dependency "parslet", ">= 1.5", "< 2.0" # Pinned < 2.0, see #5389
|
45
|
+
spec.add_dependency "semverse", "~> 3.0"
|
46
|
+
spec.add_dependency "multipart-post", "~> 2.0"
|
47
47
|
|
48
48
|
spec.add_dependency "train-core", "~> 3.10"
|
49
49
|
end
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -100,11 +100,11 @@ module Inspec
|
|
100
100
|
option :ssl, type: :boolean,
|
101
101
|
desc: "Use SSL for transport layer encryption (WinRM)."
|
102
102
|
option :ssl_peer_fingerprint, type: :string,
|
103
|
-
desc: "Specify peer fingerprint
|
103
|
+
desc: "Specify SSL peer fingerprint in place of certificates for SSL authentication (WinRM)."
|
104
104
|
option :self_signed, type: :boolean,
|
105
105
|
desc: "Allow remote scans with self-signed certificates (WinRM)."
|
106
106
|
option :ca_trust_file, type: :string,
|
107
|
-
desc: "Specify CA
|
107
|
+
desc: "Specify CA certificate required for SSL authentication (WinRM)."
|
108
108
|
option :client_cert, type: :string,
|
109
109
|
desc: "Specify client certificate for SSL authentication"
|
110
110
|
option :client_key, type: :string,
|
@@ -121,32 +121,32 @@ module Inspec
|
|
121
121
|
desc: "Read configuration from JSON file (`-` reads from stdin)."
|
122
122
|
option :json_config, type: :string, hide: true
|
123
123
|
option :proxy_command, type: :string,
|
124
|
-
desc: "Specifies the command to use to connect to the server"
|
124
|
+
desc: "Specifies the command to use to connect to the server."
|
125
125
|
option :bastion_host, type: :string,
|
126
|
-
desc: "Specifies the bastion host if applicable"
|
126
|
+
desc: "Specifies the bastion host if applicable."
|
127
127
|
option :bastion_user, type: :string,
|
128
|
-
desc: "Specifies the bastion user if applicable"
|
128
|
+
desc: "Specifies the bastion user if applicable."
|
129
129
|
option :bastion_port, type: :string,
|
130
|
-
desc: "Specifies the bastion port if applicable"
|
130
|
+
desc: "Specifies the bastion port if applicable."
|
131
131
|
option :insecure, type: :boolean, default: false,
|
132
|
-
desc: "Disable SSL verification on select targets"
|
132
|
+
desc: "Disable SSL verification on select targets."
|
133
133
|
option :target_id, type: :string,
|
134
|
-
desc: "Provide
|
134
|
+
desc: "Provide an ID which will be included on reports - deprecated"
|
135
135
|
option :winrm_shell_type, type: :string, default: "powershell",
|
136
|
-
desc: "Specify
|
136
|
+
desc: "Specify which shell type to use (powershell, elevated, or cmd), which defaults to powershell (WinRM)."
|
137
137
|
option :docker_url, type: :string,
|
138
|
-
desc: "Provides path to Docker API endpoint (Docker)"
|
138
|
+
desc: "Provides path to Docker API endpoint (Docker). Defaults to unix:///var/run/docker.sock on Unix systems and tcp://localhost:2375 on Windows."
|
139
139
|
option :ssh_config_file, type: :array,
|
140
|
-
desc: "A list of paths to the ssh config file, e.g ~/.ssh/config or /etc/ssh/ssh_config"
|
140
|
+
desc: "A list of paths to the ssh config file, e.g ~/.ssh/config or /etc/ssh/ssh_config."
|
141
141
|
option :podman_url, type: :string,
|
142
|
-
desc: "Provides path to Podman API endpoint"
|
142
|
+
desc: "Provides the path to the Podman API endpoint. Defaults to unix:///run/user/$UID/podman/podman.sock for rootless container, unix:///run/podman/podman.sock for rootful container (for this you need to execute inspec as root user)."
|
143
143
|
end
|
144
144
|
|
145
145
|
def self.profile_options
|
146
146
|
option :profiles_path, type: :string,
|
147
147
|
desc: "Folder which contains referenced profiles."
|
148
148
|
option :vendor_cache, type: :string,
|
149
|
-
desc: "Use the given path for caching dependencies
|
149
|
+
desc: "Use the given path for caching dependencies, (default: ~/.inspec/cache)."
|
150
150
|
option :auto_install_gems, type: :boolean, default: false,
|
151
151
|
desc: "Auto installs gem dependencies of the profile or resource pack."
|
152
152
|
end
|
@@ -174,7 +174,7 @@ module Inspec
|
|
174
174
|
option :input, type: :array, banner: "name1=value1 name2=value2",
|
175
175
|
desc: "Specify one or more inputs directly on the command line, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
|
176
176
|
option :input_file, type: :array,
|
177
|
-
desc: "Load one or more input files, a YAML file with values for the profile to use"
|
177
|
+
desc: "Load one or more input files, a YAML file with values for the profile to use."
|
178
178
|
option :waiver_file, type: :array,
|
179
179
|
desc: "Load one or more waiver files."
|
180
180
|
option :attrs, type: :array,
|
@@ -182,14 +182,14 @@ module Inspec
|
|
182
182
|
option :create_lockfile, type: :boolean,
|
183
183
|
desc: "Write out a lockfile based on this execution (unless one already exists)"
|
184
184
|
option :backend_cache, type: :boolean,
|
185
|
-
desc: "Allow caching for backend command output. (default: true)"
|
185
|
+
desc: "Allow caching for backend command output. (default: true)."
|
186
186
|
option :show_progress, type: :boolean,
|
187
187
|
desc: "Show progress while executing tests."
|
188
188
|
option :distinct_exit, type: :boolean, default: true,
|
189
189
|
desc: "Exit with code 101 if any tests fail, and 100 if any are skipped (default). If disabled, exit 0 on skips and 1 for failures."
|
190
190
|
option :silence_deprecations, type: :array,
|
191
191
|
banner: "[all]|[GROUP GROUP...]",
|
192
|
-
desc: "Suppress deprecation warnings. See install_dir/etc/deprecations.json for list of GROUPs or use 'all'."
|
192
|
+
desc: "Suppress deprecation warnings. See install_dir/etc/deprecations.json for a list of GROUPs or use 'all'."
|
193
193
|
option :diff, type: :boolean, default: true,
|
194
194
|
desc: "Use --no-diff to suppress 'diff' output of failed textual test results."
|
195
195
|
option :sort_results_by, type: :string, default: "file", banner: "--sort-results-by=none|control|file|random",
|
@@ -197,7 +197,7 @@ module Inspec
|
|
197
197
|
option :filter_empty_profiles, type: :boolean, default: false,
|
198
198
|
desc: "Filter empty profiles (profiles without controls) from the report."
|
199
199
|
option :filter_waived_controls, type: :boolean,
|
200
|
-
desc: "Do not execute waived controls in InSpec at all. Must use with --waiver-file. Ignores `run` setting of waiver file."
|
200
|
+
desc: "Do not execute waived controls in InSpec at all. Must use with --waiver-file. Ignores the `run` setting of the waiver file."
|
201
201
|
option :retain_waiver_data, type: :boolean,
|
202
202
|
desc: "EXPERIMENTAL: Only works in conjunction with --filter-waived-controls, retains waiver data about controls that were skipped"
|
203
203
|
option :command_timeout, type: :numeric,
|
@@ -205,6 +205,8 @@ module Inspec
|
|
205
205
|
long_desc: "Maximum seconds to allow commands to run during execution. A timed out command is considered an error."
|
206
206
|
option :reporter_include_source, type: :boolean, default: false,
|
207
207
|
desc: "Include full source code of controls in the CLI report"
|
208
|
+
option :enhanced_outcomes, type: :boolean,
|
209
|
+
desc: "Show enhanced outcomes in output"
|
208
210
|
end
|
209
211
|
|
210
212
|
def self.help(*args)
|
data/lib/inspec/cli.rb
CHANGED
@@ -61,9 +61,9 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
61
61
|
require "license_acceptance/cli_flags/thor"
|
62
62
|
include LicenseAcceptance::CLIFlags::Thor
|
63
63
|
|
64
|
-
desc "json PATH", "read all tests in PATH and generate a JSON summary"
|
64
|
+
desc "json PATH", "read all tests in the PATH and generate a JSON summary."
|
65
65
|
option :output, aliases: :o, type: :string,
|
66
|
-
desc: "Save the created profile to a path"
|
66
|
+
desc: "Save the created profile to a path."
|
67
67
|
option :controls, type: :array,
|
68
68
|
desc: "A list of controls to include. Ignore all other tests."
|
69
69
|
option :tags, type: :array,
|
@@ -81,7 +81,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
81
81
|
option :format, type: :string,
|
82
82
|
desc: "The output format to use: json, raw, yaml. If valid format is not provided then it will use the default for the given 'what'."
|
83
83
|
option :output, aliases: :o, type: :string,
|
84
|
-
desc: "Save the created output to a path"
|
84
|
+
desc: "Save the created output to a path."
|
85
85
|
option :controls, type: :array,
|
86
86
|
desc: "For --what=profile, a list of controls to include. Ignore all other tests."
|
87
87
|
option :tags, type: :array,
|
@@ -145,9 +145,11 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
145
145
|
pretty_handle_exception(e)
|
146
146
|
end
|
147
147
|
|
148
|
-
desc "check PATH", "
|
148
|
+
desc "check PATH", "Verify the metadata in the `inspec.yml` file,\
|
149
|
+
verify that control blocks have the correct fields (title, description, impact),\
|
150
|
+
and define that all controls have visible tests and the controls are not using deprecated InSpec DSL code"
|
149
151
|
option :format, type: :string,
|
150
|
-
desc: "The output format to use
|
152
|
+
desc: "The output format to use. Valid values: `json` and `doc`. Default value: `doc`."
|
151
153
|
option :with_cookstyle, type: :boolean,
|
152
154
|
desc: "Enable or disable cookstyle checks.", default: false
|
153
155
|
profile_options
|
@@ -228,10 +230,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
228
230
|
vendor_deps(path, o)
|
229
231
|
end
|
230
232
|
|
231
|
-
desc "archive PATH", "
|
233
|
+
desc "archive PATH", "Archive a profile to a tar file (default) or zip file."
|
232
234
|
profile_options
|
233
235
|
option :output, aliases: :o, type: :string,
|
234
|
-
desc: "Save the archive to a path"
|
236
|
+
desc: "Save the archive to a path."
|
235
237
|
option :zip, type: :boolean, default: false,
|
236
238
|
desc: "Generates a zip archive."
|
237
239
|
option :tar, type: :boolean, default: false,
|
@@ -275,14 +277,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
275
277
|
pretty_handle_exception(e)
|
276
278
|
end
|
277
279
|
|
278
|
-
desc "exec LOCATIONS", "Run all
|
280
|
+
desc "exec LOCATIONS", "Run all test files at the specified locations."
|
279
281
|
long_desc <<~EOT
|
280
|
-
|
281
|
-
|
282
|
-
Loads the given profile(s) and fetches their dependencies if needed. Then
|
283
|
-
connects to the target and executes any controls contained in the profiles.
|
284
|
-
One or more reporters are used to generate output.
|
285
|
-
|
282
|
+
The subcommand loads the given profiles, fetches their dependencies if needed, then connects to the target and executes any controls in the profiles.
|
283
|
+
One or more reporters are used to generate the output.
|
286
284
|
```
|
287
285
|
Exit codes:
|
288
286
|
0 Normal exit, all tests passed
|
@@ -296,7 +294,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
296
294
|
|
297
295
|
Below are some examples of using `exec` with different test LOCATIONS:
|
298
296
|
|
299
|
-
Automate:
|
297
|
+
Chef Automate:
|
300
298
|
```
|
301
299
|
#{Inspec::Dist::EXEC_NAME} automate login
|
302
300
|
#{Inspec::Dist::EXEC_NAME} exec compliance://username/linux-baseline
|
@@ -306,7 +304,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
306
304
|
#{Inspec::Dist::EXEC_NAME} compliance login
|
307
305
|
```
|
308
306
|
|
309
|
-
Supermarket:
|
307
|
+
Chef Supermarket:
|
310
308
|
```
|
311
309
|
#{Inspec::Dist::EXEC_NAME} exec supermarket://username/linux-baseline
|
312
310
|
```
|
@@ -343,12 +341,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
343
341
|
#{Inspec::Dist::EXEC_NAME} exec https://github.com/dev-sec/linux-baseline.git
|
344
342
|
```
|
345
343
|
|
346
|
-
Web hosted
|
344
|
+
Web hosted file (also supports .zip):
|
347
345
|
```
|
348
346
|
#{Inspec::Dist::EXEC_NAME} exec https://webserver/linux-baseline.tar.gz
|
349
347
|
```
|
350
348
|
|
351
|
-
Web hosted
|
349
|
+
Web hosted file with basic authentication (supports .zip):
|
352
350
|
```
|
353
351
|
#{Inspec::Dist::EXEC_NAME} exec https://username:password@webserver/linux-baseline.tar.gz
|
354
352
|
```
|
@@ -371,7 +369,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
371
369
|
pretty_handle_exception(e)
|
372
370
|
end
|
373
371
|
|
374
|
-
desc "detect", "
|
372
|
+
desc "detect", "detects the target OS."
|
375
373
|
target_options
|
376
374
|
option :format, type: :string
|
377
375
|
def detect
|
@@ -396,7 +394,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
396
394
|
pretty_handle_exception(e)
|
397
395
|
end
|
398
396
|
|
399
|
-
desc "shell", "open an interactive debugging shell"
|
397
|
+
desc "shell", "open an interactive debugging shell."
|
400
398
|
target_options
|
401
399
|
option :command, aliases: :c,
|
402
400
|
desc: "A single command string to run instead of launching the shell"
|
@@ -415,6 +413,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
415
413
|
desc: "Load one or more input files, a YAML file with values for the shell to use"
|
416
414
|
option :input, type: :array, banner: "name1=value1 name2=value2",
|
417
415
|
desc: "Specify one or more inputs directly on the command line to the shell, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
|
416
|
+
option :enhanced_outcomes, type: :boolean,
|
417
|
+
desc: "Show enhanced outcomes in output"
|
418
418
|
def shell_func
|
419
419
|
o = config
|
420
420
|
deprecate_target_id(config)
|
@@ -453,7 +453,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
453
453
|
pretty_handle_exception(e)
|
454
454
|
end
|
455
455
|
|
456
|
-
desc "env", "
|
456
|
+
desc "env", "Outputs shell-appropriate completion configuration."
|
457
457
|
def env(shell = nil)
|
458
458
|
p = Inspec::EnvPrinter.new(self.class, shell)
|
459
459
|
p.print_and_exit!
|
@@ -461,11 +461,13 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
461
461
|
pretty_handle_exception(e)
|
462
462
|
end
|
463
463
|
|
464
|
+
option :enhanced_outcomes, type: :boolean,
|
465
|
+
desc: "Show enhanced outcomes output"
|
464
466
|
desc "schema NAME", "print the JSON schema", hide: true
|
465
467
|
def schema(name)
|
466
468
|
require "inspec/schema/output_schema"
|
467
|
-
|
468
|
-
puts Inspec::Schema::OutputSchema.json(name)
|
469
|
+
o = config
|
470
|
+
puts Inspec::Schema::OutputSchema.json(name, o)
|
469
471
|
rescue StandardError => e
|
470
472
|
puts e
|
471
473
|
puts "Valid schemas are #{Inspec::Schema::OutputSchema.names.join(", ")}"
|
@@ -477,7 +479,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
477
479
|
puts Inspec::Telemetry::RunContextProbe.guess_run_context
|
478
480
|
end
|
479
481
|
|
480
|
-
desc "version", "prints the version of this tool"
|
482
|
+
desc "version", "prints the version of this tool."
|
481
483
|
option :format, type: :string
|
482
484
|
def version
|
483
485
|
if config["format"] == "json"
|
@@ -491,7 +493,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
491
493
|
|
492
494
|
desc "clear_cache", "clears the InSpec cache. Useful for debugging."
|
493
495
|
option :vendor_cache, type: :string,
|
494
|
-
desc: "Use the given path for caching dependencies
|
496
|
+
desc: "Use the given path for caching dependencies, (default: `~/.inspec/cache`)."
|
495
497
|
def clear_cache
|
496
498
|
o = config
|
497
499
|
configure_logger(o)
|
@@ -26,7 +26,7 @@ module Inspec
|
|
26
26
|
dep_list = {}
|
27
27
|
dependencies.each do |d|
|
28
28
|
# if depedent profile does not have a source version then only name is used in dependency hash
|
29
|
-
key_name = (d.source_version ? "#{d.name}
|
29
|
+
key_name = (d.source_version.blank? ? "#{d.name}" : "#{d.name}-#{d.source_version}") rescue "#{d.name}"
|
30
30
|
dep_list[key_name] = d
|
31
31
|
end
|
32
32
|
new(cwd, cache, dep_list, backend)
|
@@ -42,7 +42,7 @@ module Inspec
|
|
42
42
|
dep_list = {}
|
43
43
|
dep_tree.each do |d|
|
44
44
|
# if depedent profile does not have a source version then only name is used in dependency hash
|
45
|
-
key_name = (d.source_version ? "#{d.name}
|
45
|
+
key_name = (d.source_version.blank? ? "#{d.name}" : "#{d.name}-#{d.source_version}") rescue "#{d.name}"
|
46
46
|
dep_list[key_name] = d
|
47
47
|
dep_list.merge!(flatten_dep_tree(d.dependencies))
|
48
48
|
end
|
data/lib/inspec/dsl.rb
CHANGED
@@ -91,13 +91,17 @@ module Inspec::DSL
|
|
91
91
|
if profile_version
|
92
92
|
new_profile_id = "#{profile_id}-#{profile_version}"
|
93
93
|
else
|
94
|
-
dependencies.list.
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
94
|
+
dependencies.list.each do |key, value|
|
95
|
+
# 1. Fetching VERSION from a profile dependency name which is in a format NAME-VERSION.
|
96
|
+
# 2. Matching original profile dependency name with profile name used with include or require control DSL.
|
97
|
+
source_version = value.source_version
|
98
|
+
unless source_version.blank?
|
99
|
+
profile_id_key = key.split("-#{source_version}")[0]
|
100
|
+
new_profile_id = key if profile_id_key == profile_id
|
101
|
+
end
|
99
102
|
end
|
100
103
|
end
|
104
|
+
# If dep profile does not contain a source version, key does not contain a version as well. In that case new_profile_id will be always nil and instead profile_id would be used to fetch profile from dependency list.
|
101
105
|
dep_entry = new_profile_id ? dependencies.list[new_profile_id] : dependencies.list[profile_id]
|
102
106
|
|
103
107
|
if dep_entry.nil?
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Inspec
|
2
|
+
module EnhancedOutcomes
|
3
|
+
|
4
|
+
def self.determine_status(results, impact)
|
5
|
+
# No-op exception occurs in case of not_applicable_if
|
6
|
+
if results.any? { |r| !r[:exception].nil? && !r[:backtrace].nil? && r[:resource_class] != "noop" }
|
7
|
+
"error"
|
8
|
+
elsif !impact.nil? && impact.to_f == 0.0
|
9
|
+
"not_applicable"
|
10
|
+
elsif results.all? { |r| r[:status] == "skipped" }
|
11
|
+
"not_reviewed"
|
12
|
+
elsif results.any? { |r| r[:status] == "failed" }
|
13
|
+
"failed"
|
14
|
+
else
|
15
|
+
"passed"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/inspec/env_printer.rb
CHANGED
@@ -35,7 +35,7 @@ module Inspec
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def print_completion_for_shell
|
38
|
-
erb = ERB.new(File.read(completion_template_path),
|
38
|
+
erb = ERB.new(File.read(completion_template_path), trim_mode: "-")
|
39
39
|
puts erb.result(TemplateContext.new(@command_class).get_bindings)
|
40
40
|
end
|
41
41
|
|
data/lib/inspec/exceptions.rb
CHANGED
@@ -10,5 +10,7 @@ module Inspec
|
|
10
10
|
class SecretsBackendNotFound < ArgumentError; end
|
11
11
|
class ProfileValidationKeyNotFound < ArgumentError; end
|
12
12
|
class ProfileSigningKeyNotFound < ArgumentError; end
|
13
|
+
class WaiversFileNotReadable < ArgumentError; end
|
14
|
+
class WaiversFileDoesNotExist < ArgumentError; end
|
13
15
|
end
|
14
16
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require "rspec/core"
|
2
2
|
require "rspec/core/formatters/base_formatter"
|
3
3
|
require "set" unless defined?(Set)
|
4
|
+
require "inspec/enhanced_outcomes"
|
4
5
|
|
5
6
|
module Inspec::Formatters
|
6
7
|
class Base < RSpec::Core::Formatters::BaseFormatter
|
7
8
|
RSpec::Core::Formatters.register self, :close, :dump_summary, :stop
|
8
9
|
|
9
|
-
attr_accessor :backend, :run_data
|
10
|
+
attr_accessor :backend, :run_data, :enhanced_outcomes
|
10
11
|
|
11
12
|
def initialize(output)
|
12
13
|
super(output)
|
@@ -17,6 +18,7 @@ module Inspec::Formatters
|
|
17
18
|
@backend = nil
|
18
19
|
@all_controls_count = nil
|
19
20
|
@control_checks_count_map = {}
|
21
|
+
@enhanced_outcomes = nil
|
20
22
|
end
|
21
23
|
|
22
24
|
# RSpec Override: #dump_summary
|
@@ -50,7 +52,6 @@ module Inspec::Formatters
|
|
50
52
|
else
|
51
53
|
hash[:message] = exception_message(e)
|
52
54
|
end
|
53
|
-
|
54
55
|
next if e.is_a? RSpec::Expectations::ExpectationNotMetError
|
55
56
|
|
56
57
|
hash[:exception] = e.class.name
|
@@ -68,6 +69,8 @@ module Inspec::Formatters
|
|
68
69
|
# flesh out the profiles key with additional profile information
|
69
70
|
run_data[:profiles] = profiles_info
|
70
71
|
|
72
|
+
add_enhanced_outcomes_to_controls if enhanced_outcomes
|
73
|
+
|
71
74
|
# add the platform information for this particular target
|
72
75
|
run_data[:platform] = {
|
73
76
|
name: platform(:name),
|
@@ -110,6 +113,20 @@ module Inspec::Formatters
|
|
110
113
|
|
111
114
|
private
|
112
115
|
|
116
|
+
def add_enhanced_outcomes_to_controls
|
117
|
+
all_unique_controls.each do |control|
|
118
|
+
control[:status] = determine_control_enhanced_outcome(control)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def determine_control_enhanced_outcome(control)
|
123
|
+
if control[:results]
|
124
|
+
Inspec::EnhancedOutcomes.determine_status(control[:results], control[:impact])
|
125
|
+
else
|
126
|
+
"passed"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
113
130
|
def all_unique_controls
|
114
131
|
unique_controls = Set.new
|
115
132
|
run_data[:profiles].each do |profile|
|
@@ -120,25 +137,59 @@ module Inspec::Formatters
|
|
120
137
|
end
|
121
138
|
|
122
139
|
def statistics
|
140
|
+
error = 0
|
141
|
+
not_applicable = 0
|
142
|
+
not_reviewed = 0
|
123
143
|
failed = 0
|
124
|
-
skipped = 0
|
125
144
|
passed = 0
|
145
|
+
skipped = 0
|
146
|
+
enhanced_outcomes_summary = {}
|
147
|
+
if enhanced_outcomes
|
148
|
+
all_unique_controls.each do |control|
|
149
|
+
|
150
|
+
if control[:status] == "error"
|
151
|
+
error += 1
|
152
|
+
elsif control[:status] == "not_applicable"
|
153
|
+
not_applicable += 1
|
154
|
+
elsif control[:status] == "not_reviewed"
|
155
|
+
not_reviewed += 1
|
156
|
+
elsif control[:status] == "failed"
|
157
|
+
failed += 1
|
158
|
+
elsif control[:status] == "passed"
|
159
|
+
passed += 1
|
160
|
+
end
|
126
161
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
if control[:results].any? { |r| r[:status] == "failed" }
|
131
|
-
failed += 1
|
132
|
-
elsif control[:results].any? { |r| r[:status] == "skipped" }
|
133
|
-
skipped += 1
|
134
|
-
else
|
135
|
-
passed += 1
|
136
|
-
end
|
137
|
-
end
|
162
|
+
# added this additionally because stats summary is also used for determining exit code in runner rspec
|
163
|
+
skipped += 1 if control[:results].any? { |r| r[:status] == "skipped" }
|
138
164
|
|
139
|
-
|
165
|
+
end
|
166
|
+
total = error + not_applicable + not_reviewed + failed + passed
|
167
|
+
enhanced_outcomes_summary = {
|
168
|
+
not_applicable: {
|
169
|
+
total: not_applicable,
|
170
|
+
},
|
171
|
+
not_reviewed: {
|
172
|
+
total: not_reviewed,
|
173
|
+
},
|
174
|
+
error: {
|
175
|
+
total: error,
|
176
|
+
},
|
177
|
+
}
|
178
|
+
else
|
179
|
+
all_unique_controls.each do |control|
|
180
|
+
next unless control[:results]
|
140
181
|
|
141
|
-
|
182
|
+
if control[:results].any? { |r| r[:status] == "failed" }
|
183
|
+
failed += 1
|
184
|
+
elsif control[:results].any? { |r| r[:status] == "skipped" }
|
185
|
+
skipped += 1
|
186
|
+
else
|
187
|
+
passed += 1
|
188
|
+
end
|
189
|
+
end
|
190
|
+
total = failed + passed + skipped
|
191
|
+
end
|
192
|
+
final_summary = {
|
142
193
|
total: total,
|
143
194
|
passed: {
|
144
195
|
total: passed,
|
@@ -150,6 +201,8 @@ module Inspec::Formatters
|
|
150
201
|
total: failed,
|
151
202
|
},
|
152
203
|
}
|
204
|
+
|
205
|
+
final_summary.merge!(enhanced_outcomes_summary)
|
153
206
|
end
|
154
207
|
|
155
208
|
def exception_message(exception)
|