inspec-core 4.18.100 → 4.19.0
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 +1 -1
- data/inspec-core.gemspec +2 -2
- data/lib/inspec/base_cli.rb +4 -0
- data/lib/inspec/cli.rb +7 -17
- data/lib/inspec/config.rb +28 -6
- data/lib/inspec/fetcher/git.rb +1 -1
- data/lib/inspec/fetcher/local.rb +1 -1
- data/lib/inspec/fetcher/url.rb +1 -1
- data/lib/inspec/input.rb +9 -9
- data/lib/inspec/plugin/v2/installer.rb +23 -2
- data/lib/inspec/plugin/v2/plugin_types/reporter.rb +68 -0
- data/lib/inspec/profile.rb +16 -4
- data/lib/inspec/reporters.rb +4 -1
- data/lib/inspec/reporters/base.rb +22 -0
- data/lib/inspec/resources/service.rb +2 -2
- data/lib/inspec/resources/virtualization.rb +86 -2
- data/lib/inspec/resources/x509_certificate.rb +1 -1
- data/lib/inspec/rule.rb +8 -4
- data/lib/inspec/run_data.rb +64 -0
- data/lib/inspec/run_data/control.rb +83 -0
- data/lib/inspec/run_data/profile.rb +109 -0
- data/lib/inspec/run_data/result.rb +40 -0
- data/lib/inspec/run_data/statistics.rb +36 -0
- data/lib/inspec/shell.rb +8 -3
- data/lib/inspec/utils/json_profile_summary.rb +35 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-artifact/lib/inspec-artifact/base.rb +18 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +4 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +28 -6
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.rb +18 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/reporter.rb +27 -0
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +11 -8
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c6037004db1c4ef1ba337ea6ef710938a2ce1d02c45e56b0bdfe7349b146a92
|
4
|
+
data.tar.gz: 926e31bc929c5e5c76e3a5e89ed686218000a2ad5374c6b7901ac006ee2536a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36c0d1cf39247500f0bc33a633279c08bdaeab0c2dc848fc14f54405cb8c3b3fb1d86ae0ef0afc0ce1394c73b6de978fc61e4ff523b2dfc56d58536920caae47
|
7
|
+
data.tar.gz: c385ff9ee77aca4689dc4a83c8bef4984a3b509e6a7f459655e44a5f1a1944792c2ac1f78b0626cde72697c2b6fee1d4c2eb05ae566d928596e447d5d08f2e34
|
data/README.md
CHANGED
data/inspec-core.gemspec
CHANGED
@@ -27,11 +27,11 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_dependency "license-acceptance", ">= 0.2.13", "< 2.0"
|
28
28
|
spec.add_dependency "thor", ">= 0.20", "< 2.0"
|
29
29
|
spec.add_dependency "json_schemer", "~> 0.2.1"
|
30
|
-
spec.add_dependency "method_source", "
|
30
|
+
spec.add_dependency "method_source", ">= 0.8", "< 2.0"
|
31
31
|
spec.add_dependency "rubyzip", "~> 1.2", ">= 1.2.2"
|
32
32
|
spec.add_dependency "rspec", "~> 3.9"
|
33
33
|
spec.add_dependency "rspec-its", "~> 1.2"
|
34
|
-
spec.add_dependency "pry", "~> 0"
|
34
|
+
spec.add_dependency "pry", "~> 0.13"
|
35
35
|
spec.add_dependency "hashie", "~> 3.4"
|
36
36
|
spec.add_dependency "mixlib-log", "~> 3.0"
|
37
37
|
spec.add_dependency "sslshake", "~> 1.2"
|
data/lib/inspec/base_cli.rb
CHANGED
@@ -135,6 +135,10 @@ module Inspec
|
|
135
135
|
option :reporter, type: :array,
|
136
136
|
banner: "one two:/output/file/path",
|
137
137
|
desc: "Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml"
|
138
|
+
option :reporter_message_truncation, type: :string,
|
139
|
+
desc: "Number of characters to truncate failure messages in report data to (default: no truncation)"
|
140
|
+
option :reporter_backtrace_inclusion, type: :boolean,
|
141
|
+
desc: "Include a code backtrace in report data (default: true)"
|
138
142
|
option :input, type: :array, banner: "name1=value1 name2=value2",
|
139
143
|
desc: "Specify one or more inputs directly on the command line, as --input NAME=VALUE"
|
140
144
|
option :input_file, type: :array,
|
data/lib/inspec/cli.rb
CHANGED
@@ -4,6 +4,7 @@ require "inspec/utils/deprecation/deprecator"
|
|
4
4
|
require "inspec/dist"
|
5
5
|
require "inspec/backend"
|
6
6
|
require "inspec/dependencies/cache"
|
7
|
+
require "inspec/utils/json_profile_summary"
|
7
8
|
|
8
9
|
module Inspec # TODO: move this somewhere "better"?
|
9
10
|
autoload :BaseCLI, "inspec/base_cli"
|
@@ -77,24 +78,13 @@ class Inspec::InspecCLI < Inspec::BaseCLI
|
|
77
78
|
o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])
|
78
79
|
|
79
80
|
profile = Inspec::Profile.for_target(target, o)
|
80
|
-
info = profile.info
|
81
|
-
# add in inspec version
|
82
|
-
info[:generator] = {
|
83
|
-
name: "inspec",
|
84
|
-
version: Inspec::VERSION,
|
85
|
-
}
|
86
81
|
dst = o[:output].to_s
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
puts "----> creating #{dst}"
|
94
|
-
end
|
95
|
-
fdst = File.expand_path(dst)
|
96
|
-
File.write(fdst, JSON.dump(info))
|
97
|
-
end
|
82
|
+
|
83
|
+
# Write JSON
|
84
|
+
Inspec::Utils::JsonProfileSummary.produce_json(
|
85
|
+
info: profile.info,
|
86
|
+
write_path: dst
|
87
|
+
)
|
98
88
|
rescue StandardError => e
|
99
89
|
pretty_handle_exception(e)
|
100
90
|
end
|
data/lib/inspec/config.rb
CHANGED
@@ -328,21 +328,36 @@ module Inspec
|
|
328
328
|
def validate_reporters!(reporters)
|
329
329
|
return if reporters.nil?
|
330
330
|
|
331
|
-
#
|
332
|
-
|
333
|
-
|
334
|
-
cli
|
331
|
+
# These "reporters" are actually RSpec Formatters.
|
332
|
+
# json-rspec is our alias for RSpec's json formatter.
|
333
|
+
rspec_built_in_formatters = %w{
|
335
334
|
documentation
|
336
335
|
html
|
336
|
+
json-rspec
|
337
|
+
progress
|
338
|
+
}
|
339
|
+
|
340
|
+
# These are true reporters, but have not been migrated to be plugins yet.
|
341
|
+
# Tracked on https://github.com/inspec/inspec/issues/3667
|
342
|
+
inspec_reporters_that_are_not_yet_plugins = %w{
|
343
|
+
automate
|
344
|
+
cli
|
337
345
|
json
|
338
346
|
json-automate
|
339
347
|
json-min
|
340
|
-
json-rspec
|
341
348
|
junit
|
342
|
-
progress
|
343
349
|
yaml
|
344
350
|
}
|
345
351
|
|
352
|
+
# Additional reporters may be loaded via plugins. They will have already been detected at
|
353
|
+
# this point (see v2_loader.load_all in cli.rb) but they may not (and need not) be
|
354
|
+
# activated at this point. We only care about their existance and their name, for validation's sake.
|
355
|
+
plugin_reporters = Inspec::Plugin::V2::Registry.instance\
|
356
|
+
.find_activators(plugin_type: :reporter)\
|
357
|
+
.map(&:activator_name).map(&:to_s)
|
358
|
+
|
359
|
+
valid_types = rspec_built_in_formatters + inspec_reporters_that_are_not_yet_plugins + plugin_reporters
|
360
|
+
|
346
361
|
reporters.each do |reporter_name, reporter_config|
|
347
362
|
raise NotImplementedError, "'#{reporter_name}' is not a valid reporter type." unless valid_types.include?(reporter_name)
|
348
363
|
|
@@ -360,6 +375,13 @@ module Inspec
|
|
360
375
|
end
|
361
376
|
|
362
377
|
raise ArgumentError, "The option --reporter can only have a single report outputting to stdout." if stdout_reporters > 1
|
378
|
+
|
379
|
+
# reporter_message_truncation needs to either be the string "ALL", an Integer, or a string representing an integer
|
380
|
+
if (truncation = @merged_options["reporter_message_truncation"])
|
381
|
+
unless truncation == "ALL" || truncation.is_a?(Integer) || truncation.to_i.to_s == truncation
|
382
|
+
raise ArgumentError, "reporter_message_truncation is set to #{truncation}. It must be set to an integer value or ALL to indicate no truncation."
|
383
|
+
end
|
384
|
+
end
|
363
385
|
end
|
364
386
|
|
365
387
|
def validate_plugins!
|
data/lib/inspec/fetcher/git.rb
CHANGED
@@ -99,7 +99,7 @@ module Inspec::Fetcher
|
|
99
99
|
def cache_key
|
100
100
|
return resolved_ref unless @relative_path
|
101
101
|
|
102
|
-
OpenSSL::Digest
|
102
|
+
OpenSSL::Digest.hexdigest("SHA256", resolved_ref + @relative_path)
|
103
103
|
end
|
104
104
|
|
105
105
|
def archive_path
|
data/lib/inspec/fetcher/local.rb
CHANGED
@@ -104,7 +104,7 @@ module Inspec::Fetcher
|
|
104
104
|
return @archive_shasum if @archive_shasum
|
105
105
|
raise(Inspec::FetcherFailure, "Profile dependency local path '#{target}' does not exist") unless File.exist?(target)
|
106
106
|
|
107
|
-
@archive_shasum = OpenSSL::Digest
|
107
|
+
@archive_shasum = OpenSSL::Digest.digest("SHA256", File.read(target)).unpack("H*")[0]
|
108
108
|
end
|
109
109
|
|
110
110
|
def resolved_source
|
data/lib/inspec/fetcher/url.rb
CHANGED
@@ -127,7 +127,7 @@ module Inspec::Fetcher
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def sha256
|
130
|
-
@archive_shasum ||= OpenSSL::Digest
|
130
|
+
@archive_shasum ||= OpenSSL::Digest.digest("SHA256", File.read(@archive_path || temp_archive_path)).unpack("H*")[0]
|
131
131
|
end
|
132
132
|
|
133
133
|
def file_type_from_remote(remote)
|
data/lib/inspec/input.rb
CHANGED
@@ -98,15 +98,15 @@ module Inspec
|
|
98
98
|
# not been assigned a value. This allows a user to explicitly assign nil
|
99
99
|
# to an input.
|
100
100
|
class NO_VALUE_SET # rubocop: disable Naming/ClassAndModuleCamelCase
|
101
|
-
def initialize(name)
|
101
|
+
def initialize(name, warn_on_create = true)
|
102
102
|
@name = name
|
103
103
|
|
104
104
|
# output warn message if we are in a exec call
|
105
|
-
if Inspec::BaseCLI.inspec_cli_command == :exec
|
105
|
+
if warn_on_create && Inspec::BaseCLI.inspec_cli_command == :exec
|
106
106
|
Inspec::Log.warn(
|
107
107
|
"Input '#{@name}' does not have a value. "\
|
108
|
-
"Use --input-file to provide a value for '#{@name}' or specify a "\
|
109
|
-
"value with `
|
108
|
+
"Use --input-file or --input to provide a value for '#{@name}' or specify a "\
|
109
|
+
"value with `input('#{@name}', value: 'somevalue', ...)`."
|
110
110
|
)
|
111
111
|
end
|
112
112
|
end
|
@@ -277,7 +277,7 @@ module Inspec
|
|
277
277
|
end
|
278
278
|
|
279
279
|
# Determine the current winning value, but don't validate it
|
280
|
-
def current_value
|
280
|
+
def current_value(warn_on_missing = true)
|
281
281
|
# Examine the events to determine highest-priority value. Tie-break
|
282
282
|
# by using the last one set.
|
283
283
|
events_that_set_a_value = events.select(&:value_has_been_set?)
|
@@ -287,7 +287,7 @@ module Inspec
|
|
287
287
|
|
288
288
|
if winning_event.nil?
|
289
289
|
# No value has been set - return special no value object
|
290
|
-
NO_VALUE_SET.new(name)
|
290
|
+
NO_VALUE_SET.new(name, warn_on_missing)
|
291
291
|
else
|
292
292
|
winning_event.value # May still be nil
|
293
293
|
end
|
@@ -315,7 +315,7 @@ module Inspec
|
|
315
315
|
end
|
316
316
|
|
317
317
|
def has_value?
|
318
|
-
!current_value.is_a? NO_VALUE_SET
|
318
|
+
!current_value(false).is_a? NO_VALUE_SET
|
319
319
|
end
|
320
320
|
|
321
321
|
def to_hash
|
@@ -348,7 +348,7 @@ module Inspec
|
|
348
348
|
# skip if we are not doing an exec call (archive/vendor/check)
|
349
349
|
return unless Inspec::BaseCLI.inspec_cli_command == :exec
|
350
350
|
|
351
|
-
proposed_value = current_value
|
351
|
+
proposed_value = current_value(false)
|
352
352
|
if proposed_value.nil? || proposed_value.is_a?(NO_VALUE_SET)
|
353
353
|
error = Inspec::Input::RequiredError.new
|
354
354
|
error.input_name = name
|
@@ -363,7 +363,7 @@ module Inspec
|
|
363
363
|
type_req = type
|
364
364
|
return if type_req == "Any"
|
365
365
|
|
366
|
-
proposed_value = current_value
|
366
|
+
proposed_value = current_value(false)
|
367
367
|
|
368
368
|
invalid_type = false
|
369
369
|
if type_req == "Regexp"
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "singleton"
|
4
4
|
require "forwardable"
|
5
5
|
require "fileutils"
|
6
|
+
require "uri"
|
6
7
|
|
7
8
|
# Gem extensions for doing unusual things - not loaded by Gem default
|
8
9
|
require "rubygems/package"
|
@@ -56,6 +57,7 @@ module Inspec::Plugin::V2
|
|
56
57
|
# @option opts [String] :gem_file Path to a local gem file to install from
|
57
58
|
# @option opts [String] :path Path to a file to be used as the entry point for a path-based plugin
|
58
59
|
# @option opts [String] :version Version constraint for remote gem installs
|
60
|
+
# @option opts [String] :source Alternate URL to use instead of rubygems.org
|
59
61
|
def install(plugin_name, opts = {})
|
60
62
|
# TODO: - check plugins.json for validity before trying anything that needs to modify it.
|
61
63
|
validate_installation_opts(plugin_name, opts)
|
@@ -127,6 +129,11 @@ module Inspec::Plugin::V2
|
|
127
129
|
validate_search_opts(plugin_query, opts)
|
128
130
|
|
129
131
|
fetcher = Gem::SpecFetcher.fetcher
|
132
|
+
if opts[:source]
|
133
|
+
source_list = Gem::SourceList.from([opts[:source]])
|
134
|
+
fetcher = Gem::SpecFetcher.new(source_list)
|
135
|
+
end
|
136
|
+
|
130
137
|
matched_tuples = []
|
131
138
|
if opts[:exact]
|
132
139
|
matched_tuples = fetcher.detect(opts[:scope]) { |tuple| tuple.name == plugin_query }
|
@@ -284,8 +291,22 @@ module Inspec::Plugin::V2
|
|
284
291
|
|
285
292
|
def install_from_remote_gems(requested_plugin_name, opts)
|
286
293
|
plugin_dependency = Gem::Dependency.new(requested_plugin_name, opts[:version] || "> 0")
|
287
|
-
|
288
|
-
|
294
|
+
|
295
|
+
# BestSet is rubygems.org API + indexing, APISet is for custom sources
|
296
|
+
sources = if opts[:source]
|
297
|
+
Gem::Resolver::APISet.new(URI.join(opts[:source] + "/api/v1/dependencies"))
|
298
|
+
else
|
299
|
+
Gem::Resolver::BestSet.new
|
300
|
+
end
|
301
|
+
|
302
|
+
begin
|
303
|
+
install_gem_to_plugins_dir(plugin_dependency, [sources], opts[:update_mode])
|
304
|
+
rescue Gem::RemoteFetcher::FetchError => gem_ex
|
305
|
+
# TODO: Give a hint if the host was not resolvable or a 404 occured
|
306
|
+
ex = Inspec::Plugin::V2::InstallError.new(gem_ex.message)
|
307
|
+
ex.plugin_name = requested_plugin_name
|
308
|
+
raise ex
|
309
|
+
end
|
289
310
|
end
|
290
311
|
|
291
312
|
def install_gem_to_plugins_dir(new_plugin_dependency, # rubocop: disable Metrics/AbcSize
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative "../../../run_data"
|
2
|
+
|
3
|
+
module Inspec::Plugin::V2::PluginType
|
4
|
+
class Reporter < Inspec::Plugin::V2::PluginBase
|
5
|
+
register_plugin_type(:reporter)
|
6
|
+
|
7
|
+
attr_reader :run_data
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
@config = config
|
11
|
+
|
12
|
+
# Trim the run_data while still a Hash; if it is huge, this
|
13
|
+
# saves on conversion time
|
14
|
+
@run_data = config[:run_data] || {}
|
15
|
+
apply_report_resize_options
|
16
|
+
|
17
|
+
unless Inspec::RunData.compatible_schema?(self.class.run_data_schema_constraints)
|
18
|
+
# Best we can do is warn here, the InSpec run has finished
|
19
|
+
# TODO: one day, perhaps switch RunData implementations to try to satisfy constraints?
|
20
|
+
Inspec::Log.warn "Reporter does not support RunData API (#{Inspec::RunData::SCHEMA_VERSION}), Reporter constraints: '#{self.class.run_data_schema_constraints}'"
|
21
|
+
end
|
22
|
+
# Convert to RunData object for consumption by Reporter
|
23
|
+
@run_data = Inspec::RunData.new(@run_data)
|
24
|
+
@output = ""
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is a temporary duplication of code from lib/inspec/reporters/base.rb
|
28
|
+
# To be DRY'd up once the core reporters become plugins...
|
29
|
+
# Apply options such as message truncation and removal of backtraces
|
30
|
+
def apply_report_resize_options
|
31
|
+
runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
|
32
|
+
|
33
|
+
message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
|
34
|
+
trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
|
35
|
+
include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
|
36
|
+
|
37
|
+
@run_data[:profiles]&.each do |p|
|
38
|
+
p[:controls].each do |c|
|
39
|
+
c[:results]&.map! do |r|
|
40
|
+
r.delete(:backtrace) unless include_backtrace
|
41
|
+
if r.key?(:message) && r[:message] != "" && trunc > -1
|
42
|
+
r[:message] = r[:message][0...trunc] + "[Truncated to #{trunc} characters]"
|
43
|
+
end
|
44
|
+
r
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def output(str, newline = true)
|
51
|
+
@output << str
|
52
|
+
@output << "\n" if newline
|
53
|
+
end
|
54
|
+
|
55
|
+
def rendered_output
|
56
|
+
@output
|
57
|
+
end
|
58
|
+
|
59
|
+
# each reporter must implement #render
|
60
|
+
def render
|
61
|
+
raise NotImplementedError, "#{self.class} must implement a `#render` method to format its output."
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.run_data_schema_constraints
|
65
|
+
raise NotImplementedError, "#{self.class} must implement a `run_data_schema_constraints` class method to declare its compatibiltity with the RunData API."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/inspec/profile.rb
CHANGED
@@ -12,6 +12,7 @@ require "inspec/method_source"
|
|
12
12
|
require "inspec/dependencies/cache"
|
13
13
|
require "inspec/dependencies/lockfile"
|
14
14
|
require "inspec/dependencies/dependency_set"
|
15
|
+
require "inspec/utils/json_profile_summary"
|
15
16
|
|
16
17
|
module Inspec
|
17
18
|
class Profile
|
@@ -465,28 +466,39 @@ module Inspec
|
|
465
466
|
end
|
466
467
|
|
467
468
|
# remove existing archive
|
468
|
-
|
469
|
+
FileUtils.rm_f(dst) if dst.exist?
|
469
470
|
@logger.info "Generate archive #{dst}."
|
470
471
|
|
471
472
|
# filter files that should not be part of the profile
|
472
473
|
# TODO ignore all .files, but add the files to debug output
|
473
474
|
|
475
|
+
# Generate temporary inspec.json for archive
|
476
|
+
Inspec::Utils::JsonProfileSummary.produce_json(
|
477
|
+
info: info,
|
478
|
+
write_path: "#{root_path}inspec.json",
|
479
|
+
suppress_output: true
|
480
|
+
)
|
481
|
+
|
474
482
|
# display all files that will be part of the archive
|
475
483
|
@logger.debug "Add the following files to archive:"
|
476
484
|
files.each { |f| @logger.debug " " + f }
|
485
|
+
@logger.debug " inspec.json"
|
477
486
|
|
478
487
|
if opts[:zip]
|
479
488
|
# generate zip archive
|
480
489
|
require "inspec/archive/zip"
|
481
490
|
zag = Inspec::Archive::ZipArchiveGenerator.new
|
482
|
-
zag.archive(root_path, files, dst)
|
491
|
+
zag.archive(root_path, files.push("inspec.json"), dst)
|
483
492
|
else
|
484
493
|
# generate tar archive
|
485
494
|
require "inspec/archive/tar"
|
486
495
|
tag = Inspec::Archive::TarArchiveGenerator.new
|
487
|
-
tag.archive(root_path, files, dst)
|
496
|
+
tag.archive(root_path, files.push("inspec.json"), dst)
|
488
497
|
end
|
489
498
|
|
499
|
+
# Cleanup
|
500
|
+
FileUtils.rm_f("#{root_path}inspec.json")
|
501
|
+
|
490
502
|
@logger.info "Finished archive generation."
|
491
503
|
true
|
492
504
|
end
|
@@ -559,7 +571,7 @@ module Inspec
|
|
559
571
|
# get all dependency checksums
|
560
572
|
deps = Hash[locked_dependencies.list.map { |k, v| [k, v.profile.sha256] }]
|
561
573
|
|
562
|
-
res = OpenSSL::Digest
|
574
|
+
res = OpenSSL::Digest.new("SHA256")
|
563
575
|
files = source_reader.tests.to_a + source_reader.libraries.to_a +
|
564
576
|
source_reader.data_files.to_a +
|
565
577
|
[["inspec.yml", source_reader.metadata.content]] +
|
data/lib/inspec/reporters.rb
CHANGED
@@ -30,7 +30,10 @@ module Inspec::Reporters
|
|
30
30
|
when "yaml"
|
31
31
|
reporter = Inspec::Reporters::Yaml.new(config)
|
32
32
|
else
|
33
|
-
|
33
|
+
# If we made it here, it must be a plugin, and we know it exists (because we validated it in config.rb)
|
34
|
+
activator = Inspec::Plugin::V2::Registry.instance.find_activator(plugin_type: :reporter, activator_name: name.to_sym)
|
35
|
+
activator.activate!
|
36
|
+
reporter = activator.implementation_class.new(config)
|
34
37
|
end
|
35
38
|
|
36
39
|
# optional send_report method on reporter
|
@@ -5,9 +5,31 @@ module Inspec::Reporters
|
|
5
5
|
def initialize(config)
|
6
6
|
@config = config
|
7
7
|
@run_data = config[:run_data]
|
8
|
+
apply_report_resize_options unless @run_data.nil?
|
8
9
|
@output = ""
|
9
10
|
end
|
10
11
|
|
12
|
+
# Apply options such as message truncation and removal of backtraces
|
13
|
+
def apply_report_resize_options
|
14
|
+
runtime_config = Inspec::Config.cached.respond_to?(:final_options) ? Inspec::Config.cached.final_options : {}
|
15
|
+
|
16
|
+
message_truncation = runtime_config[:reporter_message_truncation] || "ALL"
|
17
|
+
trunc = message_truncation == "ALL" ? -1 : message_truncation.to_i
|
18
|
+
include_backtrace = runtime_config[:reporter_backtrace_inclusion].nil? ? true : runtime_config[:reporter_backtrace_inclusion]
|
19
|
+
|
20
|
+
@run_data[:profiles]&.each do |p|
|
21
|
+
p[:controls].each do |c|
|
22
|
+
c[:results]&.map! do |r|
|
23
|
+
r.delete(:backtrace) unless include_backtrace
|
24
|
+
if r.key?(:message) && r[:message] != "" && trunc > -1
|
25
|
+
r[:message] = r[:message][0...trunc] + "[Truncated to #{trunc} characters]"
|
26
|
+
end
|
27
|
+
r
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
11
33
|
def output(str, newline = true)
|
12
34
|
@output << str
|
13
35
|
@output << "\n" if newline
|