inspec-core 4.19.2 → 4.21.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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/inspec-core.gemspec +1 -1
  4. data/lib/inspec/base_cli.rb +5 -2
  5. data/lib/inspec/cli.rb +6 -5
  6. data/lib/inspec/config.rb +0 -1
  7. data/lib/inspec/input_registry.rb +33 -1
  8. data/lib/inspec/reporters.rb +12 -7
  9. data/lib/inspec/resources/interface.rb +55 -0
  10. data/lib/inspec/resources/interfaces.rb +119 -0
  11. data/lib/inspec/run_data.rb +9 -2
  12. data/lib/inspec/utils/deprecation/config_file.rb +21 -0
  13. data/lib/inspec/utils/telemetry/run_context_probe.rb +48 -0
  14. data/lib/inspec/version.rb +1 -1
  15. data/lib/plugins/inspec-reporter-html2/README.md +53 -0
  16. data/lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2.rb +18 -0
  17. data/lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2/reporter.rb +24 -0
  18. data/lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2/version.rb +8 -0
  19. data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +46 -0
  20. data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +77 -0
  21. data/lib/plugins/inspec-reporter-html2/templates/default.css +107 -0
  22. data/lib/plugins/inspec-reporter-html2/templates/default.js +79 -0
  23. data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +20 -0
  24. data/lib/plugins/inspec-reporter-html2/templates/result.html.erb +15 -0
  25. data/lib/plugins/inspec-reporter-html2/templates/selector.html.erb +8 -0
  26. data/lib/plugins/inspec-reporter-json-min/README.md +10 -0
  27. data/lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min.rb +13 -0
  28. data/lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min/reporter.rb +50 -0
  29. data/lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min/version.rb +5 -0
  30. metadata +21 -5
  31. data/lib/inspec/reporters/json_min.rb +0 -48
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3f655ad7598f4a71bab9caff608eca6990e6c66242d1c11519d105c89168fcb
4
- data.tar.gz: f6679028fc6283e7482143368d09edf70cb74d648bd45ede5d2bb8e4eb6ec165
3
+ metadata.gz: cefaf29ca67cbd5cdc90ac2bc3a41e990f38f966761d324489d46f8c9a32fdc5
4
+ data.tar.gz: 933e72e1021a81bffac47c3de56378ea0945682c6ed8f51b0e9751bd42859398
5
5
  SHA512:
6
- metadata.gz: ea24f149c474dc40974f05d017d3544ce2f4e3b762f1474f7c9146d01cf3c074a8526406bc7bb1b325cd973251f0ffc5cad06a86d7686dda0e7bf6a226f834c0
7
- data.tar.gz: cb74991d735738e58dbf04ed6c0dc5e32c923d83fe61cc7143a8af611050f001bb0d174949ed34a8ba7f97cd16735ca96e8d845e970abda579a12f44dec6fc22
6
+ metadata.gz: 0b4919f052f1f9f7bccdbf4116c2d33fded92f508f6c3057bed3a56a8214c7fa20754e281e3f50f04a5807be4c8693740e2952a0441f96447c44d2bc43059c67
7
+ data.tar.gz: 1c6b5778d3fe67831b7bd680dd1475f1ca7ddbb1becc24fbbeb1d245e8f6698f2c36d94d5f565564572039a87a94a6f82e9d7ddd50b70475a45c280f43766eca
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ gem "inspec", path: "."
9
9
  # in it in order to package the executable. Hence the odd backwards dependency.
10
10
  gem "inspec-bin", path: "./inspec-bin"
11
11
 
12
- gem "ffi", [">= 1.9.14", "< 1.13"] # 1.13 does not work on Windows: https://github.com/ffi/ffi/issues/784
12
+ gem "ffi", ">= 1.9.14", "!= 1.13.0"
13
13
 
14
14
  group :omnibus do
15
15
  gem "rb-readline"
@@ -31,6 +31,7 @@ group :test do
31
31
  gem "m"
32
32
  gem "pry", "~> 0.10"
33
33
  gem "pry-byebug"
34
+ gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
34
35
  end
35
36
 
36
37
  group :integration do
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
39
39
  spec.add_dependency "faraday", ">= 0.9.0"
40
40
  spec.add_dependency "tty-table", "~> 0.10"
41
41
  spec.add_dependency "tty-prompt", "~> 0.17"
42
- spec.add_dependency "tomlrb", "~> 1.2"
42
+ spec.add_dependency "tomlrb", "~> 1.2.0"
43
43
  spec.add_dependency "addressable", "~> 2.4"
44
44
  spec.add_dependency "parslet", "~> 1.5"
45
45
  spec.add_dependency "semverse", "~> 3.0"
@@ -140,7 +140,7 @@ module Inspec
140
140
  option :reporter_backtrace_inclusion, type: :boolean,
141
141
  desc: "Include a code backtrace in report data (default: true)"
142
142
  option :input, type: :array, banner: "name1=value1 name2=value2",
143
- desc: "Specify one or more inputs directly on the command line, as --input NAME=VALUE"
143
+ desc: "Specify one or more inputs directly on the command line, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
144
144
  option :input_file, type: :array,
145
145
  desc: "Load one or more input files, a YAML file with values for the profile to use"
146
146
  option :waiver_file, type: :array,
@@ -155,6 +155,9 @@ module Inspec
155
155
  desc: "Show progress while executing tests."
156
156
  option :distinct_exit, type: :boolean, default: true,
157
157
  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."
158
+ option :silence_deprecations, type: :array,
159
+ banner: "[all]|[GROUP GROUP...]",
160
+ desc: "Suppress deprecation warnings. See install_dir/etc/deprecations.json for list of GROUPs or use 'all'."
158
161
  end
159
162
 
160
163
  def self.format_platform_info(params: {}, indent: 0, color: 39)
@@ -228,7 +231,7 @@ module Inspec
228
231
 
229
232
  private
230
233
 
231
- ALL_OF_OUR_REPORTERS = %w{json json-min json-rspec json-automate junit html yaml documentation progress}.freeze # BUT WHY?!?!
234
+ ALL_OF_OUR_REPORTERS = %w{json json-min json-rspec json-automate junit html html2 yaml documentation progress}.freeze # BUT WHY?!?!
232
235
 
233
236
  def suppress_log_output?(opts)
234
237
  return false if opts["reporter"].nil?
@@ -375,6 +375,12 @@ class Inspec::InspecCLI < Inspec::BaseCLI
375
375
  puts "Valid schemas are #{Inspec::Schema::OutputSchema.names.join(", ")}"
376
376
  end
377
377
 
378
+ desc "run_context", "used to test run-context detection", hide: true
379
+ def run_context
380
+ require "inspec/utils/telemetry/run_context_probe"
381
+ puts Inspec::Telemetry::RunContextProbe.guess_run_context
382
+ end
383
+
378
384
  desc "version", "prints the version of this tool"
379
385
  option :format, type: :string
380
386
  def version
@@ -387,11 +393,6 @@ class Inspec::InspecCLI < Inspec::BaseCLI
387
393
  end
388
394
  map %w{-v --version} => :version
389
395
 
390
- desc "nothing", "does nothing"
391
- def nothing
392
- puts "you did nothing"
393
- end
394
-
395
396
  private
396
397
 
397
398
  def run_command(opts)
@@ -344,7 +344,6 @@ module Inspec
344
344
  cli
345
345
  json
346
346
  json-automate
347
- json-min
348
347
  junit
349
348
  yaml
350
349
  }
@@ -166,8 +166,9 @@ module Inspec
166
166
  end
167
167
  end
168
168
  input_name, input_value = pair.split("=")
169
+ input_value = parse_cli_input_value(input_name, input_value)
169
170
  evt = Inspec::Input::Event.new(
170
- value: input_value.chomp(","), # Trim trailing comma if any
171
+ value: input_value,
171
172
  provider: :cli,
172
173
  priority: 50
173
174
  )
@@ -175,6 +176,37 @@ module Inspec
175
176
  end
176
177
  end
177
178
 
179
+ # Remove trailing commas, resolve type.
180
+ def parse_cli_input_value(input_name, given_value)
181
+ value = given_value.chomp(",") # Trim trailing comma if any
182
+ case value
183
+ when /^true|false$/i
184
+ value = !!(value =~ /true/i)
185
+ when /^-?\d+$/
186
+ value = value.to_i
187
+ when /^-?\d+\.\d+$/
188
+ value = value.to_f
189
+ when /^(\[|\{).*(\]|\})$/
190
+ # Look for complex values and try to parse them.
191
+ require "yaml"
192
+ begin
193
+ value = YAML.load(value)
194
+ rescue Psych::SyntaxError => yaml_error
195
+ # It could be that we just tried to run JSON through the YAML parser.
196
+ require "json"
197
+ begin
198
+ value = JSON.parse(value)
199
+ rescue JSON::ParserError => json_error
200
+ msg = "Unparseable value '#{value}' for --input #{input_name}.\n"
201
+ msg += "When treated as YAML, error: #{yaml_error.message}\n"
202
+ msg += "When treated as JSON, error: #{json_error.message}"
203
+ Inspec::Log.warn msg
204
+ end
205
+ end
206
+ end
207
+ value
208
+ end
209
+
178
210
  def bind_inputs_from_runner_api(profile_name, input_hash)
179
211
  # TODO: move this into a core plugin
180
212
 
@@ -2,7 +2,6 @@ require "inspec/reporters/base"
2
2
  require "inspec/reporters/cli"
3
3
  require "inspec/reporters/json"
4
4
  require "inspec/reporters/json_automate"
5
- require "inspec/reporters/json_min"
6
5
  require "inspec/reporters/junit"
7
6
  require "inspec/reporters/automate"
8
7
  require "inspec/reporters/yaml"
@@ -21,8 +20,6 @@ module Inspec::Reporters
21
20
  # right to introduce breaking changes to this reporter at any time.
22
21
  when "json-automate"
23
22
  reporter = Inspec::Reporters::JsonAutomate.new(config)
24
- when "json-min"
25
- reporter = Inspec::Reporters::JsonMin.new(config)
26
23
  when "junit"
27
24
  reporter = Inspec::Reporters::Junit.new(config)
28
25
  when "automate"
@@ -60,15 +57,23 @@ module Inspec::Reporters
60
57
  case name
61
58
  when "json"
62
59
  reporter = Inspec::Reporters::Json.new(config)
63
- when "json-min"
64
- reporter = Inspec::Reporters::JsonMin.new(config)
65
60
  when "json-automate"
66
61
  reporter = Inspec::Reporters::JsonAutomate.new(config)
67
62
  when "yaml"
68
63
  reporter = Inspec::Reporters::Yaml.new(config)
69
64
  else
70
- # use base run_data hash for any other report
71
- return run_data
65
+ # If we made it here, it might be a plugin
66
+ begin
67
+ activator = Inspec::Plugin::V2::Registry.instance.find_activator(plugin_type: :reporter, activator_name: name.to_sym)
68
+ activator.activate!
69
+ reporter = activator.implementation_class.new(config)
70
+ unless reporter.respond_to(:report?)
71
+ return run_data
72
+ end
73
+ rescue Inspec::Plugin::V2::LoadError
74
+ # Must not have been a plugin - just return the run_data
75
+ return run_data
76
+ end
72
77
  end
73
78
 
74
79
  reporter.report
@@ -47,10 +47,18 @@ module Inspec::Resources
47
47
  ipv6_addresses && !ipv6_addresses.empty?
48
48
  end
49
49
 
50
+ def ipv4_address
51
+ ipv4_addresses.first
52
+ end
53
+
50
54
  def ipv4_addresses
51
55
  ipv4_cidrs.map { |i| i.split("/")[0] }
52
56
  end
53
57
 
58
+ def ipv6_address
59
+ ipv6_addresses.first
60
+ end
61
+
54
62
  def ipv6_addresses
55
63
  ipv6_cidrs.map { |i| i.split("/")[0] }
56
64
  end
@@ -85,6 +93,7 @@ module Inspec::Resources
85
93
  @cache ||= begin
86
94
  provider = LinuxInterface.new(inspec) if inspec.os.linux?
87
95
  provider = WindowsInterface.new(inspec) if inspec.os.windows?
96
+ provider = BsdInterface.new(inspec) if inspec.os.bsd? # includes macOS
88
97
  Hash(provider && provider.interface_info(@iface))
89
98
  end
90
99
  end
@@ -98,6 +107,52 @@ module Inspec::Resources
98
107
  end
99
108
  end
100
109
 
110
+ class BsdInterface < InterfaceInfo
111
+ def interface_info(iface)
112
+ cmd = inspec.command("ifconfig #{iface}")
113
+ return nil if cmd.exit_status.to_i != 0
114
+
115
+ lines = cmd.stdout.split("\n")
116
+ iface_info = {
117
+ name: iface,
118
+ ipv4_addresses: [], # Actually CIDRs
119
+ ipv6_addresses: [], # are expected to go here
120
+ }
121
+
122
+ iface_info[:up] = lines[0].include?("UP")
123
+ lines.each do |line|
124
+ # IPv4 case
125
+ m = line.match(/^\s+inet\s+((?:\d{1,3}\.){3}\d{1,3})\s+netmask\s+(0x[a-f0-9]{8})/)
126
+ if m
127
+ ip = m[1]
128
+ hex_mask = m[2]
129
+ cidr = hex_mask.to_i(16).to_s(2).count("1")
130
+ iface_info[:ipv4_addresses] << "#{ip}/#{cidr}"
131
+ next
132
+ end
133
+
134
+ # IPv6 case
135
+ m = line.match(/^\s+inet6\s+([a-f0-9:]+)%#{iface}\s+prefixlen\s+(\d+)/)
136
+ if m
137
+ ip = m[1]
138
+ cidr = m[2]
139
+ iface_info[:ipv6_addresses] << "#{ip}/#{cidr}"
140
+ next
141
+ end
142
+
143
+ # Speed detect, crummy - can't detect wifi, finds any number in the string
144
+ # Ethernet autoselect (1000baseT <full-duplex>)
145
+ m = line.match(/^\s+media:\D+(\d+)/)
146
+ if m
147
+ iface_info[:speed] = m[1].to_i
148
+ next
149
+ end
150
+ end
151
+
152
+ iface_info
153
+ end
154
+ end
155
+
101
156
  class LinuxInterface < InterfaceInfo
102
157
  def interface_info(iface)
103
158
  # will return "[mtu]\n1500\n[type]\n1"
@@ -0,0 +1,119 @@
1
+ require "inspec/utils/filter"
2
+ require "inspec/resources/command"
3
+
4
+ module Inspec::Resources
5
+ class Interfaces < Inspec.resource(1)
6
+ name "interfaces"
7
+ supports platform: "unix"
8
+ supports platform: "windows"
9
+ desc "Use the interfaces InSpec audit resource to test properties for multiple network interfaces installed on the system"
10
+ example <<~EXAMPLE
11
+ describe interfaces do
12
+ its('names') { should include 'eth0' }
13
+ end
14
+ EXAMPLE
15
+
16
+ attr_reader :iface_data
17
+
18
+ def to_s
19
+ "Interfaces"
20
+ end
21
+
22
+ filter = FilterTable.create
23
+ filter.register_column(:names, field: "name")
24
+ .install_filter_methods_on_resource(self, :scan_interfaces)
25
+
26
+ def ipv4_address
27
+ require "ipaddr"
28
+
29
+ # Loop over interface names
30
+ # Select those that are up and have an ipv4 address
31
+ interfaces = names.map { |n| inspec.interface(n) }.select do |i|
32
+ i.ipv4_address? && i.up?
33
+ end
34
+
35
+ addrs = interfaces.map(&:ipv4_addresses).flatten.map { |a| IPAddr.new(a) }
36
+
37
+ # Look for progressively "better" IP addresses
38
+ [
39
+ # Loopback and private IP ranges
40
+ IPAddr.new("127.0.0.0/8"),
41
+ IPAddr.new("192.168.0.0/16"),
42
+ IPAddr.new("172.16.0.0/12"),
43
+ IPAddr.new("10.0.0.0/8"),
44
+ ].each do |private_range|
45
+ filtered_addrs = addrs.reject { |a| private_range.include?(a) }
46
+ if filtered_addrs.empty?
47
+ # Everything we had was a private or loopback IP. Return the "best" thing we were left with.
48
+ return addrs.first.to_s
49
+ end
50
+
51
+ addrs = filtered_addrs
52
+ end
53
+ addrs.first.to_s
54
+ end
55
+
56
+ private
57
+
58
+ def scan_interfaces
59
+ @iface_data ||= begin
60
+ provider = LinuxInterfaceLister.new(inspec) if inspec.os.linux?
61
+ provider = WindowsInterfaceLister.new(inspec) if inspec.os.windows?
62
+ provider = BsdInterfaceLister.new(inspec) if inspec.os.bsd? # includes macOS
63
+ Array(provider && provider.scan_interfaces)
64
+ end
65
+ end
66
+
67
+ class InterfaceLister
68
+ attr_reader :inspec
69
+ def initialize(inspec)
70
+ @inspec = inspec
71
+ end
72
+ end
73
+
74
+ class BsdInterfaceLister < InterfaceLister
75
+ def scan_interfaces
76
+ iface_data = []
77
+ cmd = inspec.command("ifconfig -a")
78
+ cmd.stdout.split("\n").each do |line|
79
+ # lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
80
+ m = line.match(/^(\S+):/)
81
+ if m
82
+ iface_data << { "name" => m[1] }
83
+ end
84
+ end
85
+ iface_data
86
+ end
87
+ end
88
+
89
+ class LinuxInterfaceLister < InterfaceLister
90
+ def scan_interfaces
91
+ iface_data = []
92
+ cmd = inspec.command("ls /sys/class/net")
93
+ cmd.stdout.split("\n").each do |iface|
94
+ iface_data << { "name" => iface }
95
+ end
96
+ iface_data
97
+ end
98
+ end
99
+
100
+ class WindowsInterfaceLister < InterfaceLister
101
+ def scan_interfaces
102
+ iface_data = []
103
+ cmd = inspec.command("Get-NetAdapter | Select-Object -Property Name | ConvertTo-Json")
104
+ begin
105
+ adapter_info = JSON.parse(cmd.stdout)
106
+ # May be a Hash if only one, or Array if multiple - normalize to Array
107
+ adapter_info = [ adapter_info ] if adapter_info.is_a? Hash
108
+ rescue JSON::ParserError => _e
109
+ return nil
110
+ end
111
+ adapter_info.each do |info|
112
+ iface_data << { "name" => info["Name"] }
113
+ end
114
+ iface_data
115
+ end
116
+ end
117
+
118
+ end
119
+ end
@@ -1,12 +1,19 @@
1
1
 
2
2
  module Inspec
3
3
  module HashLikeStruct
4
+ # Only list keys whose value are non-nil
4
5
  def keys
5
- members
6
+ members.reject { |k| self[k].nil? }
6
7
  end
7
8
 
9
+ # Only list non-nil members for backwards compatibility
8
10
  def key?(item)
9
- members.include?(item)
11
+ members.include?(item) && non_nil?(item)
12
+ end
13
+
14
+ # This is provided for clarity - many locations make this test
15
+ def non_nil?(item)
16
+ !self[item].nil?
10
17
  end
11
18
  end
12
19
 
@@ -1,6 +1,7 @@
1
1
  require "stringio"
2
2
  require "json"
3
3
  require "inspec/globals"
4
+ require "inspec/config"
4
5
 
5
6
  module Inspec
6
7
  module Deprecation
@@ -32,6 +33,7 @@ module Inspec
32
33
  @groups = {}
33
34
  @unknown_group_action = :warn
34
35
  validate!
36
+ silence_deprecations_from_cli
35
37
  end
36
38
 
37
39
  private
@@ -45,6 +47,25 @@ module Inspec
45
47
  File.open(default_path)
46
48
  end
47
49
 
50
+ def silence_deprecations_from_cli
51
+ # Read --silence-deprecations CLI option
52
+ cfg = Inspec::Config.cached
53
+ return unless cfg[:silence_deprecations]
54
+
55
+ groups_to_silence = cfg[:silence_deprecations]
56
+ silence_all = groups_to_silence.include?("all")
57
+
58
+ groups.each do |group_name, group|
59
+ # Only silence things that warn. Don't silence things that exit;
60
+ # those harsher measures are usually protecting removed code and ignoring
61
+ # and continuing regardless would be perilous and lead to errors.
62
+ if %i{warn fail_control}.include?(group.action) &&
63
+ (silence_all || groups_to_silence.include?(group_name.to_s))
64
+ group.action = :ignore
65
+ end
66
+ end
67
+ end
68
+
48
69
  #====================================================================================================#
49
70
  # Validation
50
71
  #====================================================================================================#
@@ -0,0 +1,48 @@
1
+ module Inspec
2
+ module Telemetry
3
+ # Guesses the run context of InSpec - how were we invoked?
4
+ # All stack values here are determined experimentally
5
+
6
+ class RunContextProbe
7
+ def self.guess_run_context(stack = nil)
8
+ stack ||= caller_locations
9
+ return "test-kitchen" if kitchen?(stack)
10
+ return "cli" if run_by_thor?(stack)
11
+ return "audit-cookbook" if audit_cookbook?(stack)
12
+
13
+ "unknown"
14
+ end
15
+
16
+ def self.run_by_thor?(stack)
17
+ stack_match(stack: stack, path: "thor/command", label: "run") &&
18
+ stack_match(stack: stack, path: "thor/invocation", label: "invoke_command")
19
+ end
20
+
21
+ def self.kitchen?(stack)
22
+ stack_match(stack: stack, path: "kitchen/instance", label: "verify_action") &&
23
+ stack_match(stack: stack, path: "kitchen/instance", label: "verify")
24
+ end
25
+
26
+ def self.audit_cookbook?(stack)
27
+ stack_match(stack: stack, path: "chef/handler", label: "run_report_handlers") &&
28
+ stack_match(stack: stack, path: "handler/audit_report", label: "report")
29
+ end
30
+
31
+ def self.stack_match(stack: [], label: nil, path: nil)
32
+ return false if stack.nil?
33
+
34
+ stack.any? do |frame|
35
+ if label && path
36
+ frame.label == label && frame.absolute_path.include?(path)
37
+ elsif label
38
+ frame.label == label
39
+ elsif path
40
+ frame.absolute_path.include?(path)
41
+ else
42
+ false
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.19.2".freeze
2
+ VERSION = "4.21.3".freeze
3
3
  end
@@ -0,0 +1,53 @@
1
+ # inspec-reporter-html2 Plugin
2
+
3
+ An "improved" HTML output reporter specifically for Chef InSpec. Unlike the default `html` reporter, which is RSpec-based, this reporter knows about Chef InSpec structures like Controls and Profiles, and includes full metadata such as control tags, etc.
4
+
5
+ ## To Install This Plugin
6
+
7
+ This plugin ships with Chef InSpec and requires no installation.
8
+
9
+ It should appear when you run:
10
+
11
+ ```
12
+ you@machine $ inspec plugin list
13
+ ```
14
+
15
+ ## How to use this plugin
16
+
17
+ To generate an HTML report using this plugin and save the output to a file named `report.html`, run:
18
+
19
+ ```
20
+ you@machine $ inspec exec some_profile --reporter html2:report.html
21
+ ```
22
+
23
+ Note the `2` in the reporter name. If you omit it and run `--reporter html` instead, you will run the legacy RSpec HTML reporter.
24
+
25
+ ## Configuring the Plugin
26
+
27
+ The `html2` reporter requires no configuration to function. However, two options--`alternate_css_file` and `alternate_js_file`--are available for customization. The options are set in the JSON-formatted configuration file that Chef InSpec consumes. For details, see [our configuration file documentation](https://www.inspec.io/docs/reference/config/).
28
+
29
+ For example:
30
+
31
+ ```json
32
+ {
33
+ "version": "1.2",
34
+ "plugins": {
35
+ "inspec-reporter-html2": {
36
+ "alternate_js_file":"/var/www/js/my-javascript.js",
37
+ "alternate_css_file":"/var/www/css/my-style.css"
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### alternate\_css\_file
44
+
45
+ Specifies the full path to the location of a CSS file that will be read and inlined into the HTML report. The default CSS will not be included.
46
+
47
+ ### alternate\_js\_file
48
+
49
+ Specifies the full path to the location of a JavaScript file that will be read and inlined into the HTML report. The default JavaScript will not be included. The JavaScript file should implement at least a `pageLoaded()` function, which will be called by the `onload` event of the HTML `body` element.
50
+
51
+ ## Developing This Plugin
52
+
53
+ This plugin is part of the Chef InSpec source code. While it has its own tests, the general contribution policy is dictated by the Chef InSpec project at https://github.com/inspec/inspec/blob/master/CONTRIBUTING.md
@@ -0,0 +1,18 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ require "inspec-reporter-html2/version"
5
+ module InspecPlugins
6
+ module Html2Reporter
7
+ class Plugin < ::Inspec.plugin(2)
8
+ # Internal machine name of the plugin. InSpec will use this in errors, etc.
9
+ plugin_name :'inspec-reporter-html2'
10
+
11
+ # Define a new Reporter.
12
+ reporter :html2 do
13
+ require "inspec-reporter-html2/reporter"
14
+ InspecPlugins::Html2Reporter::Reporter
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ require "erb"
2
+ require "inspec/config"
3
+
4
+ module InspecPlugins::Html2Reporter
5
+ class Reporter < Inspec.plugin(2, :reporter)
6
+ def render
7
+ template_path = File.expand_path(__FILE__ + "../../../../templates")
8
+
9
+ # Read config data from the user's config file. Supports two settings, both of which are absolute filesystem paths:
10
+ # alternate_css_file - contents will be used instead of default CSS
11
+ # alternate_js_file - contents will be used instead of default JavaScript
12
+ cfg = Inspec::Config.cached.fetch_plugin_config("inspec-reporter-html2")
13
+ js_path = cfg[:alternate_js_file] || (template_path + "/default.js")
14
+ css_path = cfg[:alternate_css_file] || (template_path + "/default.css")
15
+
16
+ template = ERB.new(File.read(template_path + "/body.html.erb"))
17
+ output(template.result(binding))
18
+ end
19
+
20
+ def self.run_data_schema_constraints
21
+ "~> 0.0"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # This file simply makes it easier for CI engines to update
2
+ # the version stamp, and provide a clean way for the gemspec
3
+ # to learn the current version.
4
+ module InspecPlugins
5
+ module Html2Reporter
6
+ VERSION = "0.1.0".freeze
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <!-- saved from url=(0014)about:internet -->
3
+ <!-- prior comment allows JS to execute on IE when saved as a local file, "MOTW" -->
4
+ <html lang="en">
5
+ <head>
6
+ <title><%= Inspec::Dist::PRODUCT_NAME %> Results</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
+ <style type="text/css">
9
+ /* Must inline all CSS files, this is a single-file output that may be airgapped */
10
+ <%= ERB.new(File.read(css_path), nil, nil, "_css").result(binding) %>
11
+ </style>
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+ /* Must inline all JavaScript files, this is a single-file output that may be airgapped */
15
+ <%= ERB.new(File.read(js_path), nil, nil, "_js").result(binding) %>
16
+ // ]]>
17
+ </script>
18
+ </head>
19
+ <body onload="pageLoaded()">
20
+ <%= ERB.new(File.read(template_path + "/selector.html.erb"), nil, nil, "_select").result(binding) %>
21
+ <div class="inspec-report">
22
+ <h1><%= Inspec::Dist::PRODUCT_NAME %> Report</h1>
23
+ <% run_data.profiles.each do |profile| %>
24
+ <%= ERB.new(File.read(template_path + "/profile.html.erb"), nil, nil, "_prof").result(binding) %>
25
+ <% end %>
26
+
27
+ <div class="inspec-summary">
28
+ <table id="platform" class="info">
29
+ <tr><th colspan=2><h4 id="platform-label">Platform Information</h4></th></tr>
30
+ <tr class= "name"><th>Name:</th><td><%= run_data.platform.name %></td></tr>
31
+ <tr class= "release"><th>Release:</th><td><%= run_data.platform.release %></td></tr>
32
+ <tr class= "target"><th>Target:</th><td><%= run_data.platform.target %></td></tr>
33
+ </table>
34
+ <table id="statistics" class="info">
35
+ <tr><th colspan="2"><h4 id="statistics-label">Control Statistics</h4></th></tr>
36
+ <tr class= "passed"><th>Passed:</th><td><%= run_data.statistics.controls.passed.total %></td></tr>
37
+ <tr class= "skipped"><th>Skipped:</th><td><%= run_data.statistics.controls.skipped.total %></td></tr>
38
+ <tr class= "failed"><th>Failed:</th><td><%= run_data.statistics.controls.failed.total %></td></tr>
39
+ <tr class= "duration"><th>Duration:</th><td><%= run_data.statistics.duration %> seconds</td></tr>
40
+ <tr class= "date"><th>Time Finished:</th><td><%= Time.now %></td></tr>
41
+ </table>
42
+ <span id="inspec-version"><%= Inspec::Dist::PRODUCT_NAME %> version <%= run_data.version %></span>
43
+ </div>
44
+ </div>
45
+ </body>
46
+ </html>
@@ -0,0 +1,77 @@
1
+ <% slugged_id = control.id.tr(" ", "_") %>
2
+ <%
3
+ # Determine status of control
4
+ status = "passed"
5
+ if control.results.any? { |r| r.status == "failed" }
6
+ status = "failed"
7
+ elsif control.results.any? { |r| r.status == "skipped" }
8
+ status = "skipped"
9
+ end
10
+ %>
11
+
12
+ <div class="control control-status-<%= status %>" id="control-<%= slugged_id %>">
13
+
14
+ <%
15
+ # Determine range of impact
16
+ i = control.impact || 0.0
17
+ impact_level = "none"
18
+ if i < 0.3
19
+ impact_level = "low"
20
+ elsif i < 0.7
21
+ impact_level = "medium"
22
+ else
23
+ impact_level = "high"
24
+ end
25
+ %>
26
+
27
+ <h3 class="control-title">Control <code><%= control.id %></code></h3>
28
+ <table class="control-metadata info" id="control-metadata-<%= slugged_id %>">
29
+ <tr class="status status-<%= status %>"><th>Status:</th><td><div><%= status.capitalize %></div></td></tr>
30
+ <% if control.title %><tr class="title"><th>Title:</th><td><%= control.title %></td></tr> <% end %>
31
+ <% if control.desc %><tr class="desc"><th>Description:</th><td><%= control.desc %></td></tr> <% end %>
32
+ <% if control.impact %><tr class="impact impact-<%= impact_level %>"><th>Impact:</th><td><%= control.impact %></td></tr> <% end %>
33
+ <% unless control.tags.empty? %>
34
+ <tr class="tags">
35
+ <th>Tags:</th>
36
+ <td>
37
+ <table class="tags">
38
+ <% control.tags.each do |tag_name, tag_text| %>
39
+ <tr><td><%= tag_name %></td><td><%= tag_text %></td></tr>
40
+ <% end %>
41
+ </table>
42
+ </td>
43
+ </tr>
44
+ <% end %>
45
+ <% unless control.refs.empty? %>
46
+ <tr class="refs">
47
+ <th>References:</th>
48
+ <td>
49
+ <ul>
50
+ <% control.refs.each do |r| %>
51
+ <li><a href="<%= r.url %>"><%= r.ref %></a></li>
52
+ <% end %>
53
+ </ul>
54
+ </td>
55
+ </tr>
56
+ <% end %>
57
+ <tr class="code">
58
+ <th>Source Code:</th>
59
+ <td>
60
+ <input type="button" class="show-source-code" id="show-code-<%= slugged_id %>" value="Show Source"/>
61
+ <input type="button" class="hide-source-code hidden" id="hide-code-<%= slugged_id %>" value="Hide Source"/>
62
+ <pre class="source-code hidden" id="source-code-<%= slugged_id %>">
63
+ <code>
64
+ <%= control.code %>
65
+ </code>
66
+ </pre>
67
+ </td>
68
+ </tr>
69
+ <!-- TODO waiver data -->
70
+
71
+ </table>
72
+
73
+ <% control.results.each do |result| %>
74
+ <%= ERB.new(File.read(template_path + "/result.html.erb"), nil, nil, "_rslt").result(binding) %>
75
+ <% end %>
76
+
77
+ </div>
@@ -0,0 +1,107 @@
1
+ body {
2
+ margin: 20px 10% 20px 10%;
3
+ padding: 0;
4
+ background: #fff;
5
+ }
6
+ h1, h2, h3, h4, h5 {
7
+ font-family: "Lucida Grande", Helvetica, sans-serif;
8
+ }
9
+ h1, h2 {
10
+ padding: 10px;
11
+ text-align: center
12
+ }
13
+ table.info th, table.info th {
14
+ padding: 2px;
15
+ }
16
+ table.info th {
17
+ text-align: right;
18
+ }
19
+ .hidden {
20
+ display: none;
21
+ }
22
+ pre code {
23
+ background-color: #eee;
24
+ border: 1px solid #999;
25
+ display: block;
26
+ padding: 20px;
27
+ }
28
+
29
+ .profile, .control, .profile-metadata {
30
+ border: 1px solid #ccc;
31
+ padding: 10px;
32
+ margin: 5px auto;
33
+ }
34
+
35
+ .resource-title {
36
+ margin-left: 2.5%;
37
+ }
38
+
39
+ .control-title code,
40
+ .resource-title code {
41
+ font-size: larger;
42
+ }
43
+ .control-metadata .status div,
44
+ .result-metadata .status div {
45
+ color: white;
46
+ font-weight: bold;
47
+ width: fit-content;
48
+ padding: 0px 2px;
49
+ }
50
+
51
+ .control-metadata .status-passed div,
52
+ .result-metadata .status-passed div {
53
+ background-color: darkgreen;
54
+ }
55
+ .control-metadata .status-failed div,
56
+ .result-metadata .status-failed div {
57
+ background-color: red;
58
+ }
59
+ .control-metadata .status-skipped div,
60
+ .result-metadata .status-skipped div {
61
+ background-color: grey;
62
+ }
63
+ .result-metadata,
64
+ .control-metadata {
65
+ margin: 0 0 0 5%;
66
+ }
67
+
68
+ .selector-panel {
69
+ position: fixed;
70
+ z-index: 100;
71
+ background-color: #ccc;
72
+ padding: 10px;
73
+ top: 0;
74
+ margin-left: -10%;
75
+ border-bottom-right-radius: 10px;
76
+ }
77
+
78
+ @media print {
79
+ .selector-panel {
80
+ visibility: hidden;
81
+ }
82
+ }
83
+
84
+ .inspec-summary {
85
+ border: 1px solid #ccc;
86
+ padding: 10px;
87
+ margin: 5px auto;
88
+ width: fit-content
89
+ }
90
+
91
+ .inspec-summary h4 {
92
+ margin-bottom: 0px;
93
+ }
94
+
95
+ .inspec-summary #platform, .inspec-summary #statistics {
96
+ display: inline;
97
+ }
98
+
99
+ #statistics .date td {
100
+ width: 100px
101
+ }
102
+
103
+ #inspec-version {
104
+ display: block;
105
+ text-align: center;
106
+ font-style: italic;
107
+ }
@@ -0,0 +1,79 @@
1
+
2
+ /* CSS primitives */
3
+ function addCssClass(id, cls) {
4
+ document.getElementById(id).className += (" " + cls);
5
+ }
6
+
7
+ function removeCssClass(id, cls) {
8
+ var el = document.getElementById(id);
9
+ var classes = el.className.replace(cls,'');
10
+ el.className = classes;
11
+ }
12
+
13
+ function handleShowSource(evt) {
14
+ var control_id = evt.srcElement.id.replace("show-code-", "")
15
+ addCssClass(evt.srcElement.id, "hidden")
16
+ removeCssClass("hide-code-" + control_id, "hidden")
17
+ removeCssClass("source-code-" + control_id, "hidden")
18
+ }
19
+
20
+ function handleHideSource(evt) {
21
+ var control_id = evt.srcElement.id.replace("hide-code-", "")
22
+ addCssClass(evt.srcElement.id, "hidden")
23
+ addCssClass("source-code-" + control_id, "hidden")
24
+ removeCssClass("show-code-" + control_id, "hidden")
25
+ }
26
+
27
+ function handleSelectorChange(evt) {
28
+ var should_show = evt.srcElement.checked
29
+ var which_group = evt.srcElement.id.replace("-checkbox","")
30
+ var controls = document.getElementsByClassName("control-status-" + which_group)
31
+ var i;
32
+ if (should_show) {
33
+ for (i = 0; i < controls.length; i++) {
34
+ removeCssClass(controls[i].id, "hidden")
35
+ }
36
+ } else {
37
+ for (i = 0; i < controls.length; i++) {
38
+ addCssClass(controls[i].id, "hidden")
39
+ }
40
+ }
41
+ }
42
+
43
+ function handleChildProfileChange(evt) {
44
+ var should_show = evt.srcElement.checked
45
+ var child_profiles = document.getElementsByClassName("child-profile")
46
+ var i;
47
+ if (should_show) {
48
+ for (i = 0; i < child_profiles.length; i++) {
49
+ removeCssClass(child_profiles[i].id, "hidden")
50
+ }
51
+ } else {
52
+ for (i = 0; i < child_profiles.length; i++) {
53
+ addCssClass(child_profiles[i].id, "hidden")
54
+ }
55
+ }
56
+ }
57
+
58
+ /* Main entry point */
59
+ function pageLoaded() {
60
+ var i;
61
+
62
+ // wire up show source links
63
+ var show_links = document.getElementsByClassName("show-source-code");
64
+ for (i = 0; i < show_links.length; i++) {
65
+ show_links[i].onclick = handleShowSource;
66
+ }
67
+ // wire up hide source links
68
+ var hide_links = document.getElementsByClassName("hide-source-code");
69
+ for (i = 0; i < hide_links.length; i++) {
70
+ hide_links[i].onclick = handleHideSource;
71
+ }
72
+ // wire up selector checkboxes
73
+ var selectors = document.getElementsByClassName("selector-checkbox");
74
+ for (i = 0; i < selectors.length; i++) {
75
+ selectors[i].onchange = handleSelectorChange;
76
+ }
77
+ // wire up child profile checkbox
78
+ document.getElementById("child-profile-checkbox").onchange = handleChildProfileChange;
79
+ }
@@ -0,0 +1,20 @@
1
+ <div class="profile <%= profile.parent_profile ? "child-profile hidden" : "" %>" id="profile-<%= profile.name %>">
2
+ <% display_name = profile.title || profile.name %>
3
+ <h2 class="profile_title">Profile <%= display_name %> (<%= profile.name %>)</h2>
4
+
5
+ <table class="profile-metadata info" id="profile-metadata-<%= profile.name %>">
6
+ <tr class="profile-version"><th>Version:</th><td><%= profile.version %></td></tr>
7
+ <% if profile.summary %>
8
+ <tr class="profile-summary"><th>Summary:</th><td><%= profile.summary %></td></tr>
9
+ <% end %>
10
+ <% if profile.skip_message %>
11
+ <tr class="profile-skip-message"><th>Skip Message:</th><td><%= profile.skip_message %></td></tr>
12
+ <% end %>
13
+ </table>
14
+
15
+ <% if profile.status == "loaded" %>
16
+ <% profile.controls.each do |control| %>
17
+ <%= ERB.new(File.read(template_path + "/control.html.erb"), nil, nil, "_ctl").result(binding) %>
18
+ <% end %>
19
+ <% end %>
20
+ </div>
@@ -0,0 +1,15 @@
1
+ <% slugged_id = result.resource_title.to_s.gsub(/\W/, "_") %>
2
+ <div class="result" id="result-<%= slugged_id %>">
3
+ <h4 class="resource-title">Resource <code><%= result.resource_title.to_s %></code></h4>
4
+ <table class="result-metadata info">
5
+ <tr class="expectation_message"><th>Test:</th><td><code><%= result.expectation_message %></code></td></tr>
6
+ <tr class="status status-<%= result.status %>"><th>Status:</th><td><div><%= result.status.capitalize %></div></td></tr>
7
+ <% if result.status == "failed" %>
8
+ <tr class="fail_message"><th>Failure Message:</th><td><code><%= result.message %></code></td></tr>
9
+ <% end %>
10
+ <% if result.status == "skipped" %>
11
+ <tr class="skip_message"><th>Skip Message:</th><td><%= result.skip_message %></td></tr>
12
+ <% end %>
13
+ <tr class="duration"><th>Duration:</th><td><%= result.run_time %> seconds</td></tr>
14
+ </table>
15
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="selector-panel">
2
+ <p id="selector-instructions">Display controls that are:</p>
3
+ <input class="selector-checkbox" id="passed-checkbox" type="checkbox" checked="checked"/><label for="passed-checkbox">Passed</label>
4
+ <input class="selector-checkbox" id="skipped-checkbox" type="checkbox" checked="checked"/><label for="skipped-checkbox">Skipped</label>
5
+ <input class="selector-checkbox" id="failed-checkbox" type="checkbox" checked="checked"/><label for="failed-checkbox">Failed</label>
6
+ <p id="selector-instructions">Display profiles that are:</p>
7
+ <input class="profile-selector-checkbox" id="child-profile-checkbox" type="checkbox" /><label for="child-profile-checkbox">Dependent Profiles</label>
8
+ </div>
@@ -0,0 +1,10 @@
1
+ # JSON Minimal Reporter Plugin
2
+
3
+ ## To Install This Plugin
4
+
5
+ This plugin is included with InSpec. There is no need to install it.
6
+
7
+ ## What This Plugin Does
8
+
9
+ This plugin provides the `json-min` reporter, which produces test output in JSON format with less detail than the `json` reporter.
10
+
@@ -0,0 +1,13 @@
1
+ require_relative "inspec-reporter-json-min/version"
2
+
3
+ module InspecPlugins
4
+ module JsonMinReporter
5
+ class Plugin < ::Inspec.plugin(2)
6
+ plugin_name :"inspec-reporter-json-min"
7
+ reporter :"json-min" do
8
+ require_relative "inspec-reporter-json-min/reporter"
9
+ InspecPlugins::JsonMinReporter::Reporter
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ require "json"
2
+
3
+ module InspecPlugins::JsonMinReporter
4
+ class Reporter < Inspec.plugin(2, :reporter)
5
+ def self.run_data_schema_constraints
6
+ "~> 0.0"
7
+ end
8
+
9
+ def render
10
+ output(report.to_json, false)
11
+ end
12
+
13
+ def report # rubocop:disable Metrics/AbcSize
14
+ report = {
15
+ controls: [],
16
+ statistics: { duration: run_data.statistics.duration },
17
+ version: run_data.version,
18
+ }
19
+
20
+ # collect all test results and add them to the report
21
+ run_data.profiles.each do |profile|
22
+ profile_id = profile.name
23
+
24
+ profile.controls.each do |control|
25
+ control_id = control.id
26
+
27
+ control.results.each do |result|
28
+ result_for_report = {
29
+ id: control_id,
30
+ profile_id: profile_id,
31
+ profile_sha256: profile.sha256,
32
+ status: result.status,
33
+ code_desc: result.code_desc,
34
+ }
35
+
36
+ result_for_report[:skip_message] = result.skip_message if result.non_nil?(:skip_message)
37
+ result_for_report[:resource] = result.resource if result.non_nil?(:resource)
38
+ result_for_report[:message] = result.message if result.non_nil?(:message)
39
+ result_for_report[:exception] = result.exception if result.non_nil?(:exception)
40
+ result_for_report[:backtrace] = result.backtrace if result.non_nil?(:backtrace)
41
+
42
+ report[:controls] << result_for_report
43
+ end
44
+ end
45
+ end
46
+
47
+ report
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ module InspecPlugins
2
+ module JsonMinReporter
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.19.2
4
+ version: 4.21.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-04 00:00:00.000000000 Z
11
+ date: 2020-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -264,14 +264,14 @@ dependencies:
264
264
  requirements:
265
265
  - - "~>"
266
266
  - !ruby/object:Gem::Version
267
- version: '1.2'
267
+ version: 1.2.0
268
268
  type: :runtime
269
269
  prerelease: false
270
270
  version_requirements: !ruby/object:Gem::Requirement
271
271
  requirements:
272
272
  - - "~>"
273
273
  - !ruby/object:Gem::Version
274
- version: '1.2'
274
+ version: 1.2.0
275
275
  - !ruby/object:Gem::Dependency
276
276
  name: addressable
277
277
  requirement: !ruby/object:Gem::Requirement
@@ -483,7 +483,6 @@ files:
483
483
  - lib/inspec/reporters/cli.rb
484
484
  - lib/inspec/reporters/json.rb
485
485
  - lib/inspec/reporters/json_automate.rb
486
- - lib/inspec/reporters/json_min.rb
487
486
  - lib/inspec/reporters/junit.rb
488
487
  - lib/inspec/reporters/yaml.rb
489
488
  - lib/inspec/require_loader.rb
@@ -537,6 +536,7 @@ files:
537
536
  - lib/inspec/resources/inetd_conf.rb
538
537
  - lib/inspec/resources/ini.rb
539
538
  - lib/inspec/resources/interface.rb
539
+ - lib/inspec/resources/interfaces.rb
540
540
  - lib/inspec/resources/ip6tables.rb
541
541
  - lib/inspec/resources/iptables.rb
542
542
  - lib/inspec/resources/json.rb
@@ -667,6 +667,7 @@ files:
667
667
  - lib/inspec/utils/telemetry/collector.rb
668
668
  - lib/inspec/utils/telemetry/data_series.rb
669
669
  - lib/inspec/utils/telemetry/global_methods.rb
670
+ - lib/inspec/utils/telemetry/run_context_probe.rb
670
671
  - lib/inspec/version.rb
671
672
  - lib/matchers/matchers.rb
672
673
  - lib/plugins/README.md
@@ -724,6 +725,21 @@ files:
724
725
  - lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli.rb
725
726
  - lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb
726
727
  - lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/plugin.rb
728
+ - lib/plugins/inspec-reporter-html2/README.md
729
+ - lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2.rb
730
+ - lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2/reporter.rb
731
+ - lib/plugins/inspec-reporter-html2/lib/inspec-reporter-html2/version.rb
732
+ - lib/plugins/inspec-reporter-html2/templates/body.html.erb
733
+ - lib/plugins/inspec-reporter-html2/templates/control.html.erb
734
+ - lib/plugins/inspec-reporter-html2/templates/default.css
735
+ - lib/plugins/inspec-reporter-html2/templates/default.js
736
+ - lib/plugins/inspec-reporter-html2/templates/profile.html.erb
737
+ - lib/plugins/inspec-reporter-html2/templates/result.html.erb
738
+ - lib/plugins/inspec-reporter-html2/templates/selector.html.erb
739
+ - lib/plugins/inspec-reporter-json-min/README.md
740
+ - lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min.rb
741
+ - lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min/reporter.rb
742
+ - lib/plugins/inspec-reporter-json-min/lib/inspec-reporter-json-min/version.rb
727
743
  - lib/plugins/shared/core_plugin_test_helper.rb
728
744
  - lib/plugins/things-for-train-integration.rb
729
745
  - lib/source_readers/flat.rb
@@ -1,48 +0,0 @@
1
- require "json"
2
-
3
- module Inspec::Reporters
4
- class JsonMin < Base
5
- def render
6
- output(report.to_json, false)
7
- end
8
-
9
- def report # rubocop:disable Metrics/AbcSize
10
- report = {
11
- controls: [],
12
- statistics: { duration: run_data[:statistics][:duration] },
13
- version: run_data[:version],
14
- }
15
-
16
- # collect all test results and add them to the report
17
- run_data[:profiles].each do |profile|
18
- profile_id = profile[:name]
19
- next unless profile[:controls]
20
-
21
- profile[:controls].each do |control|
22
- control_id = control[:id]
23
- next unless control[:results]
24
-
25
- control[:results].each do |result|
26
- result_for_report = {
27
- id: control_id,
28
- profile_id: profile_id,
29
- profile_sha256: profile[:sha256],
30
- status: result[:status],
31
- code_desc: result[:code_desc],
32
- }
33
-
34
- result_for_report[:skip_message] = result[:skip_message] if result.key?(:skip_message)
35
- result_for_report[:resource] = result[:resource] if result.key?(:resource)
36
- result_for_report[:message] = result[:message] if result.key?(:message)
37
- result_for_report[:exception] = result[:exception] if result.key?(:exception)
38
- result_for_report[:backtrace] = result[:backtrace] if result.key?(:backtrace)
39
-
40
- report[:controls] << result_for_report
41
- end
42
- end
43
- end
44
-
45
- report
46
- end
47
- end
48
- end