inspec-core 4.32.0 → 4.33.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a32d0575d09a6902a6a3fbce06ed7aaf7757e3604039334ecc9aa9adc9830298
4
- data.tar.gz: 3df4dd2409d4456c4f42fe666bddd9407c3eadff754f852206bbcd81927967b2
3
+ metadata.gz: ec42612f75dc95f62517b85b024c039ad15965f7c98dfaecb9494161b9f85611
4
+ data.tar.gz: 6373b89393e737cacdcb859ca510758afb9ce7e16d89e90d86877205a3d8d335
5
5
  SHA512:
6
- metadata.gz: 298d75a54ef15d4f880eff7b049d361281511ca3705476550747c4f863ac3d97325fd1796cf99de4af44e179a0003c04db142ed3fda59547cd82dad3a4ec57ca
7
- data.tar.gz: 14733ae7b9dbeec40c07654d83a65eed7e2d81dc18b2c9c813de4a99465b13117d0c2dbde25e6b51b26cf275c49cf78ac3eba8a991eb59e6914414f812fe89b2
6
+ metadata.gz: f1591b7c166d00fe78037f703eb55292384b2c2b13195db150da008b198424177809078db9509054af664f91aca8bae06f93f41939d808263cc78baf0414f29c
7
+ data.tar.gz: 5124bfc3a8b676bd097efc319233fec94d3fd3739b727e1b92678c7929d280c093c46136b80607f166d164e0bd85586b9ce560e2ebed0eadbd7f35d09bd517b9
@@ -168,9 +168,11 @@ module Inspec
168
168
  desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
169
169
  option :filter_empty_profiles, type: :boolean, default: false,
170
170
  desc: "Filter empty profiles (profiles without controls) from the report."
171
- option :command_timeout, type: :numeric, default: 3600,
172
- desc: "Maximum seconds to allow commands to run during execution. Default 3600.",
173
- long_desc: "Maximum seconds to allow commands to run during execution. Default 3600. A timed out command is considered an error."
171
+ option :command_timeout, type: :numeric,
172
+ desc: "Maximum seconds to allow commands to run during execution.",
173
+ long_desc: "Maximum seconds to allow commands to run during execution. A timed out command is considered an error."
174
+ option :reporter_include_source, type: :boolean, default: false,
175
+ desc: "Include full source code of controls in the CLI report"
174
176
  end
175
177
 
176
178
  def self.help(*args)
data/lib/inspec/cli.rb CHANGED
@@ -321,9 +321,9 @@ class Inspec::InspecCLI < Inspec::BaseCLI
321
321
  desc: "A space-delimited list of local folders containing profiles whose libraries and resources will be loaded into the new shell"
322
322
  option :distinct_exit, type: :boolean, default: true,
323
323
  desc: "Exit with code 100 if any tests fail, and 101 if any are skipped but none failed (default). If disabled, exit 0 on skips and 1 for failures."
324
- option :command_timeout, type: :numeric, default: 3600,
325
- desc: "Maximum seconds to allow a command to run. Default 3600.",
326
- long_desc: "Maximum seconds to allow commands to run. Default 3600. A timed out command is considered an error."
324
+ option :command_timeout, type: :numeric,
325
+ desc: "Maximum seconds to allow a command to run.",
326
+ long_desc: "Maximum seconds to allow commands to run. A timed out command is considered an error."
327
327
  option :inspect, type: :boolean, default: false, desc: "Use verbose/debugging output for resources."
328
328
  option :input_file, type: :array,
329
329
  desc: "Load one or more input files, a YAML file with values for the shell to use"
@@ -41,12 +41,14 @@ module Inspec::Reporters
41
41
  MULTI_TEST_CONTROL_SUMMARY_MAX_LEN = 60
42
42
 
43
43
  def render
44
+ @src_extent_map = {}
44
45
  run_data[:profiles].each do |profile|
45
46
  if profile[:status] == "skipped"
46
47
  platform = run_data[:platform]
47
48
  output("Skipping profile: '#{profile[:name]}' on unsupported platform: '#{platform[:name]}/#{platform[:release]}'.")
48
49
  next
49
50
  end
51
+ read_control_source(profile)
50
52
  @control_count = 0
51
53
  output("")
52
54
  print_profile_header(profile)
@@ -89,6 +91,7 @@ module Inspec::Reporters
89
91
  next if control.results.nil?
90
92
 
91
93
  output(format_control_header(control))
94
+ output(format_control_source(control)) if Inspec::Config.cached[:reporter_include_source]
92
95
  control.results.each do |result|
93
96
  output(format_result(control, result, :standard))
94
97
  @control_count += 1
@@ -127,6 +130,62 @@ module Inspec::Reporters
127
130
  )
128
131
  end
129
132
 
133
+ def format_control_source(control)
134
+ src = @control_source[control.id]
135
+ message = "Control Source from #{src[:path]}:#{src[:start]}..#{src[:end]}\n"
136
+ message += src[:content]
137
+ format_message(
138
+ color: "skipped",
139
+ indentation: 5,
140
+ message: message
141
+ )
142
+ end
143
+
144
+ def read_control_source(profile)
145
+ return unless Inspec::Config.cached[:reporter_include_source]
146
+
147
+ @control_source = {}
148
+ src_extent_map = {}
149
+
150
+ # First pass: build map of paths => ids => [start]
151
+ all_unique_controls.each do |control|
152
+ id = control[:id]
153
+ path = control[:source_location][:ref]
154
+ start = control[:source_location][:line]
155
+ next if path.nil? || start.nil?
156
+
157
+ src_extent_map[path] ||= []
158
+ src_extent_map[path] << { start: start, id: id }
159
+ end
160
+
161
+ # Now sort the controls by their starting line in their control file
162
+ src_extent_map.values.each do |extent_list|
163
+ extent_list.sort! { |a, b| a[:start] <=> b[:start] }
164
+ end
165
+
166
+ # Third pass: Read in files and split into lines
167
+ src_extent_map.keys.each do |path|
168
+ control_file_lines = File.read(path).lines # TODO error handling
169
+ last_line_in_file = control_file_lines.count
170
+ extent_list = src_extent_map[path]
171
+ extent_list.each_with_index do |extent, idx|
172
+ if idx == extent_list.count - 1 # Last entry
173
+ extent[:end] = last_line_in_file
174
+ else
175
+ extent[:end] = extent_list[idx + 1][:start] - 1
176
+ end
177
+
178
+ @control_source[extent[:id]] =
179
+ {
180
+ path: path,
181
+ start: extent[:start],
182
+ end: extent[:end],
183
+ content: control_file_lines.slice(extent[:start] - 1, extent[:end] - extent[:start] + 1).join(""),
184
+ }
185
+ end
186
+ end
187
+ end
188
+
130
189
  def format_result(control, result, type)
131
190
  impact = control.impact_string_for_result(result)
132
191
 
@@ -312,6 +371,10 @@ module Inspec::Reporters
312
371
  data[:impact]
313
372
  end
314
373
 
374
+ def source_location
375
+ data[:source_location]
376
+ end
377
+
315
378
  def anonymous?
316
379
  id.start_with?("(generated from ")
317
380
  end
@@ -31,17 +31,11 @@ module Inspec::Resources
31
31
  end
32
32
 
33
33
  @command = cmd
34
-
35
- cli_timeout = Inspec::Config.cached["command_timeout"].to_i
34
+ cli_timeout = Inspec::Config.cached["command_timeout"]&.to_i
36
35
  # Can access this via Inspec::InspecCLI.commands["exec"].options[:command_timeout].default,
37
36
  # but that may not be loaded for kitchen-inspec and other pure gem consumers
38
- default_cli_timeout = 3600
39
- cli_timeout = default_cli_timeout if cli_timeout == 0 # Under test-kitchen we get a 0 timeout, which can't be a resonable value
40
- if cli_timeout != default_cli_timeout
41
- @timeout = cli_timeout
42
- else
43
- @timeout = options[:timeout]&.to_i || default_cli_timeout
44
- end
37
+ cli_timeout = nil if cli_timeout == 0 # Under test-kitchen we get a 0 timeout, which can't be a resonable value
38
+ @timeout = cli_timeout || options[:timeout]&.to_i
45
39
 
46
40
  if options[:redact_regex]
47
41
  unless options[:redact_regex].is_a?(Regexp)
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.32.0".freeze
2
+ VERSION = "4.33.1".freeze
3
3
  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.32.0
4
+ version: 4.33.1
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: 2021-04-14 00:00:00.000000000 Z
11
+ date: 2021-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry