inspec-core 5.18.14 → 5.21.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +19 -16
- data/inspec-core.gemspec +22 -22
- data/lib/inspec/base_cli.rb +2 -0
- data/lib/inspec/cli.rb +6 -2
- data/lib/inspec/dsl.rb +10 -4
- 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/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 +2 -2
- data/lib/inspec/resources/lxc.rb +65 -9
- 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/service.rb +1 -1
- 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/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 +7 -1
- 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 +25 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f6f86730baadd988c363a823e5e46ba68c318e48b27bbaaba614ce7c33bb71c
|
4
|
+
data.tar.gz: f02ca42e9d4e525b82e9cfa61a04b122dc3b09c1e3c96f2ec4440c3fb3053f25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 597fed943b00ed280a749f05c97d01e29b4d5a85034835e9f242990588b35b740bf56a886b65202777d68b79b5cbd1faf1a48a69c1a4f1f8a00a83ecdece3527
|
7
|
+
data.tar.gz: 13aa012d46677b3cd31614dcc118c62b1aa1656f3007d6b105f7822a3c25a45b1b1284eef9fb9e761cf5a03cd8209ffe8518d54ed355c189a2f141788a000694
|
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"
|
@@ -39,26 +38,30 @@ group :test do
|
|
39
38
|
gem "simplecov", "~> 0.21"
|
40
39
|
gem "simplecov_json_formatter"
|
41
40
|
gem "webmock", "~> 3.0"
|
41
|
+
|
42
|
+
if Gem.ruby_version >= Gem::Version.new("3.0.0")
|
43
|
+
# html-proofer has a dep on io-event, which is ruby-3 only
|
44
|
+
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.
|
45
|
+
end
|
42
46
|
end
|
43
47
|
|
44
48
|
group :deploy do
|
45
49
|
gem "inquirer"
|
46
50
|
end
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
gem "
|
54
|
-
|
55
|
-
|
56
|
-
gem "
|
57
|
-
gem "kitchen-dokken", ">= 2.11"
|
58
|
-
gem "git"
|
52
|
+
group :kitchen do
|
53
|
+
gem "berkshelf"
|
54
|
+
|
55
|
+
# Chef 18 requires ruby 3
|
56
|
+
if Gem.ruby_version >= Gem::Version.new("3.0.0")
|
57
|
+
gem "chef", ">= 17.0"
|
58
|
+
else
|
59
|
+
# Ruby 2.7 presumably - TODO remove this when 2.7 is sunsetted
|
60
|
+
gem "chef", "~> 16.0"
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
|
-
|
63
|
-
gem "
|
63
|
+
gem "test-kitchen", ">= 2.8"
|
64
|
+
gem "kitchen-inspec", ">= 2.0"
|
65
|
+
gem "kitchen-dokken", ">= 2.11"
|
66
|
+
gem "git"
|
64
67
|
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
@@ -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
@@ -415,6 +415,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
415
415
|
desc: "Load one or more input files, a YAML file with values for the shell to use"
|
416
416
|
option :input, type: :array, banner: "name1=value1 name2=value2",
|
417
417
|
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."
|
418
|
+
option :enhanced_outcomes, type: :boolean,
|
419
|
+
desc: "Show enhanced outcomes in output"
|
418
420
|
def shell_func
|
419
421
|
o = config
|
420
422
|
deprecate_target_id(config)
|
@@ -461,11 +463,13 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
461
463
|
pretty_handle_exception(e)
|
462
464
|
end
|
463
465
|
|
466
|
+
option :enhanced_outcomes, type: :boolean,
|
467
|
+
desc: "Show enhanced outcomes output"
|
464
468
|
desc "schema NAME", "print the JSON schema", hide: true
|
465
469
|
def schema(name)
|
466
470
|
require "inspec/schema/output_schema"
|
467
|
-
|
468
|
-
puts Inspec::Schema::OutputSchema.json(name)
|
471
|
+
o = config
|
472
|
+
puts Inspec::Schema::OutputSchema.json(name, o)
|
469
473
|
rescue StandardError => e
|
470
474
|
puts e
|
471
475
|
puts "Valid schemas are #{Inspec::Schema::OutputSchema.names.join(", ")}"
|
data/lib/inspec/dsl.rb
CHANGED
@@ -91,13 +91,19 @@ module Inspec::DSL
|
|
91
91
|
if profile_version
|
92
92
|
new_profile_id = "#{profile_id}-#{profile_version}"
|
93
93
|
else
|
94
|
+
# This scary regex is used to match version following semantic Versioning (SemVer). Thanks to https://ihateregex.io/expr/semver/
|
95
|
+
regex_for_semver = /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/
|
94
96
|
dependencies.list.keys.each do |key|
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
97
|
+
# 1. Fetching VERSION from a profile dependency name which is in a format NAME-VERSION.
|
98
|
+
# 2. Matching original profile dependency name with profile name used with include or require control DSL.
|
99
|
+
fetching_semver = key.match(regex_for_semver).to_s
|
100
|
+
unless fetching_semver.nil? || fetching_semver.empty?
|
101
|
+
profile_id_key = key.split("-#{fetching_semver}")[0]
|
102
|
+
new_profile_id = key if profile_id_key == profile_id
|
103
|
+
end
|
99
104
|
end
|
100
105
|
end
|
106
|
+
# 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
107
|
dep_entry = new_profile_id ? dependencies.list[new_profile_id] : dependencies.list[profile_id]
|
102
108
|
|
103
109
|
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)
|
@@ -178,7 +178,19 @@ module Inspec::Plugin::V2
|
|
178
178
|
# TODO: enforce first-level version pinning
|
179
179
|
plugin_deps = [Gem::Dependency.new(plugin_gem_name.to_s, version_constraint)]
|
180
180
|
managed_gem_set = Gem::Resolver::VendorSet.new
|
181
|
-
|
181
|
+
|
182
|
+
list_managed_gems.each do |spec|
|
183
|
+
if Gem::Specification.load spec.gem_dir
|
184
|
+
managed_gem_set.add_vendor_gem(spec.name, spec.gem_dir)
|
185
|
+
else
|
186
|
+
# In case of invalid gemspec as mentioned in this PR https://github.com/brianmario/yajl-ruby/pull/223
|
187
|
+
# the add_vendor_gem breaks. So this is patch to fix the loading issue.
|
188
|
+
# Horribly, chdir to gemspec path to honor . in gemspec
|
189
|
+
Dir.chdir(spec.gem_dir) do |dir|
|
190
|
+
managed_gem_set.add_vendor_gem(spec.name, spec.gem_dir)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
182
194
|
|
183
195
|
# TODO: Next two lines merge our managed gems with the other gems available
|
184
196
|
# in our "local universe" - which may be the system, or it could be in a Bundler microcosm,
|
@@ -278,7 +290,12 @@ module Inspec::Plugin::V2
|
|
278
290
|
when :user_gem
|
279
291
|
status.entry_point = status.name.to_s
|
280
292
|
status.version = plugin_entry[:version]
|
281
|
-
|
293
|
+
# Fetch the summary of the gem from local gemspec file instead of remote call using Gem::SpecFetcher.fetcher.
|
294
|
+
unless plugin_entry[:version].nil? # safe check very rare case.
|
295
|
+
version_string = plugin_entry[:version].gsub(/[=,~,>,<]/, "").strip
|
296
|
+
plugin_name_with_version = "#{status.name}-#{version_string}"
|
297
|
+
status.description = fetch_gemspec(File.join(plugin_gem_path, "gems", plugin_name_with_version, "/", status.name.to_s + ".gemspec"))&.summary
|
298
|
+
end
|
282
299
|
when :path
|
283
300
|
status.entry_point = plugin_entry[:installation_path]
|
284
301
|
end
|
@@ -287,12 +304,6 @@ module Inspec::Plugin::V2
|
|
287
304
|
end
|
288
305
|
end
|
289
306
|
|
290
|
-
def fetch_plugin_specs(plugin_name)
|
291
|
-
fetcher = Gem::SpecFetcher.fetcher
|
292
|
-
plugin_dependency = Gem::Dependency.new(plugin_name)
|
293
|
-
fetcher.spec_for_dependency(plugin_dependency).flatten.first
|
294
|
-
end
|
295
|
-
|
296
307
|
def fixup_train_plugin_status(status)
|
297
308
|
status.api_generation = :'train-1'
|
298
309
|
if status.installation_type == :user_gem
|
@@ -11,6 +11,7 @@ module Inspec::Plugin::V2::PluginType
|
|
11
11
|
@running_controls_list = []
|
12
12
|
@control_checks_count_map = {}
|
13
13
|
@controls_count = nil
|
14
|
+
@notifications = {}
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
@@ -49,5 +50,58 @@ module Inspec::Plugin::V2::PluginType
|
|
49
50
|
@control_checks_count_map = RSpec.configuration.formatters.grep(Inspec::Formatters::Base).first.get_control_checks_count_map
|
50
51
|
end
|
51
52
|
end
|
53
|
+
|
54
|
+
def enhanced_outcomes
|
55
|
+
@enhanced_outcomes ||= RSpec.configuration.formatters.grep(Inspec::Formatters::Base).first.enhanced_outcomes
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_enhanced_outcomes(control_id)
|
59
|
+
if control_has_error(@notifications[control_id])
|
60
|
+
"error"
|
61
|
+
elsif control_has_impact_zero(@notifications[control_id])
|
62
|
+
"not_applicable"
|
63
|
+
elsif control_has_all_tests_skipped(@notifications[control_id])
|
64
|
+
"not_reviewed"
|
65
|
+
elsif control_has_any_tests_failed(@notifications[control_id])
|
66
|
+
"failed"
|
67
|
+
else
|
68
|
+
"passed"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def control_has_error(notifications)
|
73
|
+
notifications.any? do |notification_data|
|
74
|
+
notification, _status = notification_data
|
75
|
+
!notification.example.exception.nil? && !(notification.example.exception.is_a? RSpec::Expectations::ExpectationNotMetError) && !notification.example.exception.backtrace.nil? && (!notification.description.include? "No-op") # No-op exception occurs in case of not_applicable_if
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def control_has_all_tests_skipped(notifications)
|
80
|
+
notifications.all? do |notification_data|
|
81
|
+
_notification, status = notification_data
|
82
|
+
status == "skipped"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def control_has_any_tests_failed(notifications)
|
87
|
+
notifications.any? do |notification_data|
|
88
|
+
_notification, status = notification_data
|
89
|
+
status == "failed"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def control_has_impact_zero(notifications)
|
94
|
+
notification_data = notifications.first
|
95
|
+
notification_impact = notification_data.first.example.metadata[:impact]
|
96
|
+
notification_data && !notification_impact.nil? && notification_impact.to_f == 0.0
|
97
|
+
end
|
98
|
+
|
99
|
+
def collect_notifications(notification, control_id, status)
|
100
|
+
if @notifications[control_id].nil?
|
101
|
+
@notifications[control_id] = [[notification, status]]
|
102
|
+
else
|
103
|
+
@notifications[control_id].push([notification, status])
|
104
|
+
end
|
105
|
+
end
|
52
106
|
end
|
53
107
|
end
|