inspec-core 4.25.1 → 4.31.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/inspec-core.gemspec +2 -1
  4. data/lib/inspec/base_cli.rb +9 -0
  5. data/lib/inspec/cli.rb +17 -0
  6. data/lib/inspec/config.rb +14 -1
  7. data/lib/inspec/control_eval_context.rb +29 -3
  8. data/lib/inspec/fetcher/git.rb +16 -2
  9. data/lib/inspec/input_registry.rb +1 -0
  10. data/lib/inspec/profile.rb +11 -15
  11. data/lib/inspec/profile_context.rb +3 -0
  12. data/lib/inspec/reporters/cli.rb +1 -1
  13. data/lib/inspec/reporters/json.rb +6 -1
  14. data/lib/inspec/reporters/json_automate.rb +1 -1
  15. data/lib/inspec/resources/apt.rb +1 -1
  16. data/lib/inspec/resources/auditd_conf.rb +2 -0
  17. data/lib/inspec/resources/command.rb +19 -1
  18. data/lib/inspec/resources/crontab.rb +8 -2
  19. data/lib/inspec/resources/nginx_conf.rb +39 -0
  20. data/lib/inspec/resources/oracledb_session.rb +1 -1
  21. data/lib/inspec/resources/ssh_config.rb +1 -1
  22. data/lib/inspec/runner_rspec.rb +1 -1
  23. data/lib/inspec/utils/filter.rb +8 -2
  24. data/lib/inspec/utils/run_data_filters.rb +9 -0
  25. data/lib/inspec/version.rb +1 -1
  26. data/lib/matchers/matchers.rb +1 -1
  27. data/lib/plugins/inspec-init/templates/profiles/aws/README.md +10 -10
  28. data/lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb +3 -3
  29. data/lib/plugins/inspec-init/templates/profiles/aws/{attributes.yml → inputs.yml} +0 -0
  30. data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +2 -3
  31. data/lib/plugins/inspec-init/templates/profiles/gcp/README.md +7 -7
  32. data/lib/plugins/inspec-init/templates/profiles/gcp/controls/example.rb +1 -1
  33. data/lib/plugins/inspec-init/templates/profiles/gcp/{attributes.yml → inputs.yml} +0 -0
  34. data/lib/plugins/inspec-init/templates/profiles/gcp/inspec.yml +3 -4
  35. metadata +20 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4db76b09c46f02e91dca61f334693d773d0c0c470104ef8d28b89a443b1b6c55
4
- data.tar.gz: 9834a18148bf8f2851f7a030e3766b3932f6592e7a3fdfb5a354daf7c8cdfff1
3
+ metadata.gz: de259f902d4d891726e44204083a9fa2ab6b2b7507914036cc1af230e82dbc6b
4
+ data.tar.gz: 16d2ce9dbe236411f8169b378c51bedd5e2fc87ee84429b14de8e7312f6576cd
5
5
  SHA512:
6
- metadata.gz: 2c8330268f60a8b8d895e33ee3fb75b3076b81be5c3e8816250ad8775ea00d76332796181aba8da27c15c251c0b6ce8379279c693158c969bbe1003e0985bd7a
7
- data.tar.gz: 3e6e5096e98c3198a650bfa4c6f88a66db84fdbf366d451bae21e38a1e430e0cb77b9d1ebe5a85d03c354390e8eb884bddb586ef28d5ece4d9a57d7830838bb9
6
+ metadata.gz: 6f6646ab26611a0d49bce5bb8dd927ac678cb1ab032d5c5de055e5e769ef667f4147f4bae82613450c21c9ca0ebcd99302f33741ba51c95094b45714a6f69303
7
+ data.tar.gz: c19721ef5d63cedae91fe69103f7f4ec4237ce4e16ab563895eff655b2ff32ec1ba15daf412cf23ed11966a9d94b5941b5c74ac6ba47c4c209f82a5db1240641
data/Gemfile CHANGED
@@ -28,10 +28,10 @@ group :omnibus do
28
28
  end
29
29
 
30
30
  group :test do
31
- gem "chefstyle", "~> 1.5.7"
31
+ gem "chefstyle", "~> 1.7.1"
32
32
  gem "concurrent-ruby", "~> 1.0"
33
33
  gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
34
- gem "json_schemer", ">= 0.2.1", "< 0.2.18"
34
+ gem "json_schemer", ">= 0.2.1", "< 0.2.19"
35
35
  gem "m"
36
36
  gem "minitest-sprint", "~> 1.0"
37
37
  gem "minitest", "~> 5.5"
data/inspec-core.gemspec CHANGED
@@ -36,11 +36,12 @@ Gem::Specification.new do |spec|
36
36
  spec.add_dependency "sslshake", "~> 1.2"
37
37
  spec.add_dependency "parallel", "~> 1.9"
38
38
  spec.add_dependency "faraday", ">= 0.9.0", "< 1.4"
39
+ spec.add_dependency "faraday_middleware", "~> 1.0"
39
40
  spec.add_dependency "tty-table", "~> 0.10"
40
41
  spec.add_dependency "tty-prompt", "~> 0.17"
41
42
  spec.add_dependency "tomlrb", ">= 1.2", "< 2.1"
42
43
  spec.add_dependency "addressable", "~> 2.4"
43
- spec.add_dependency "parslet", ">= 1.5", "< 3.0"
44
+ spec.add_dependency "parslet", ">= 1.5", "< 2.0" # Pinned < 2.0, see #5389
44
45
  spec.add_dependency "semverse", "~> 3.0"
45
46
  spec.add_dependency "multipart-post", "~> 2.0"
46
47
 
@@ -118,6 +118,10 @@ module Inspec
118
118
  desc: "Disable SSL verification on select targets"
119
119
  option :target_id, type: :string,
120
120
  desc: "Provide a ID which will be included on reports"
121
+ option :winrm_shell_type, type: :string, default: "powershell",
122
+ desc: "Specify a shell type for winrm (eg. 'elevated' or 'powershell')"
123
+ option :docker_url, type: :string,
124
+ desc: "Provides path to Docker API endpoint (Docker)"
121
125
  end
122
126
 
123
127
  def self.profile_options
@@ -162,6 +166,11 @@ module Inspec
162
166
  desc: "Use --no-diff to suppress 'diff' output of failed textual test results."
163
167
  option :sort_results_by, type: :string, default: "file", banner: "--sort-results-by=none|control|file|random",
164
168
  desc: "After normal execution order, results are sorted by control ID, or by file (default), or randomly. None uses legacy unsorted mode."
169
+ option :filter_empty_profiles, type: :boolean, default: false,
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."
165
174
  end
166
175
 
167
176
  def self.help(*args)
data/lib/inspec/cli.rb CHANGED
@@ -321,6 +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
327
  option :inspect, type: :boolean, default: false, desc: "Use verbose/debugging output for resources."
325
328
  def shell_func
326
329
  o = config
@@ -395,6 +398,20 @@ class Inspec::InspecCLI < Inspec::BaseCLI
395
398
  end
396
399
  map %w{-v --version} => :version
397
400
 
401
+ desc "clear_cache", "clears the InSpec cache. Useful for debugging."
402
+ option :vendor_cache, type: :string,
403
+ desc: "Use the given path for caching dependencies. (default: ~/.inspec/cache)"
404
+ def clear_cache
405
+ o = config
406
+ configure_logger(o)
407
+ cache_path = o[:vendor_cache] || "~/.inspec/cache"
408
+ FileUtils.rm_r Dir.glob(File.expand_path(cache_path))
409
+
410
+ o[:logger] = Logger.new($stdout)
411
+ o[:logger].level = get_log_level(o[:log_level])
412
+ o[:logger].info "== InSpec cache cleared successfully =="
413
+ end
414
+
398
415
  private
399
416
 
400
417
  def run_command(opts)
data/lib/inspec/config.rb CHANGED
@@ -128,12 +128,25 @@ module Inspec
128
128
  end
129
129
 
130
130
  #-----------------------------------------------------------------------#
131
- # Fetching Plugin Data
131
+ # Handling Plugin Data
132
132
  #-----------------------------------------------------------------------#
133
133
  def fetch_plugin_config(plugin_name)
134
134
  Thor::CoreExt::HashWithIndifferentAccess.new(@plugin_cfg[plugin_name] || {})
135
135
  end
136
136
 
137
+ def set_plugin_config(plugin_name, plugin_config)
138
+ plugin_name = plugin_name.to_s unless plugin_name.is_a? String
139
+
140
+ @plugin_cfg[plugin_name] = plugin_config
141
+ end
142
+
143
+ def merge_plugin_config(plugin_name, additional_plugin_config)
144
+ plugin_name = plugin_name.to_s unless plugin_name.is_a? String
145
+
146
+ @plugin_cfg[plugin_name] = {} if @plugin_cfg[plugin_name].nil?
147
+ @plugin_cfg[plugin_name].merge!(additional_plugin_config)
148
+ end
149
+
137
150
  # clear the cached config
138
151
  def self.__reset
139
152
  @cached_config = nil
@@ -53,8 +53,9 @@ module Inspec
53
53
 
54
54
  def control(id, opts = {}, &block)
55
55
  opts[:skip_only_if_eval] = @skip_only_if_eval
56
-
57
- register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
56
+ if control_exist_in_controls_list?(id) || controls_list_empty?
57
+ register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
58
+ end
58
59
  end
59
60
  alias rule control
60
61
 
@@ -68,10 +69,14 @@ module Inspec
68
69
  id = "(generated from #{loc} #{SecureRandom.hex})"
69
70
 
70
71
  res = nil
72
+
71
73
  rule = Inspec::Rule.new(id, profile_id, resources_dsl, {}) do
72
74
  res = describe(*args, &block)
73
75
  end
74
- register_control(rule, &block)
76
+
77
+ if control_exist_in_controls_list?(id) || controls_list_empty?
78
+ register_control(rule, &block)
79
+ end
75
80
 
76
81
  res
77
82
  end
@@ -176,5 +181,26 @@ module Inspec
176
181
  "#{File.basename(path)}:#{line}"
177
182
  end
178
183
  end
184
+
185
+ # Returns true if configuration hash is not empty and it contains the list of controls is not empty
186
+ def profile_config_exist?
187
+ !@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_controls_list.empty?
188
+ end
189
+
190
+ # Returns true if configuration hash is empty or configuration hash does not have the list of controls that needs to be included
191
+ def controls_list_empty?
192
+ !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_controls_list.empty? || @conf.empty?
193
+ end
194
+
195
+ # Check if the given control exist in the --controls option
196
+ def control_exist_in_controls_list?(id)
197
+ if profile_config_exist?
198
+ id_exist_in_list = @conf["profile"].include_controls_list.any? do |inclusion|
199
+ # Try to see if the inclusion is a regex, and if it matches
200
+ inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
201
+ end
202
+ end
203
+ id_exist_in_list
204
+ end
179
205
  end
180
206
  end
@@ -62,7 +62,6 @@ module Inspec::Fetcher
62
62
  def fetch(destination_path)
63
63
  @repo_directory = destination_path # Might be the cache, or vendoring, or something else
64
64
  FileUtils.mkdir_p(destination_path) unless Dir.exist?(destination_path)
65
-
66
65
  if cloned?
67
66
  checkout
68
67
  else
@@ -126,10 +125,25 @@ module Inspec::Fetcher
126
125
  elsif @tag
127
126
  resolve_ref(@tag)
128
127
  else
129
- resolve_ref("master")
128
+ resolve_ref(default_ref)
130
129
  end
131
130
  end
132
131
 
132
+ def default_ref
133
+ command_string = "git remote show #{@remote_url}"
134
+ cmd = shellout(command_string)
135
+ unless cmd.exitstatus == 0
136
+ raise(Inspec::FetcherFailure, "Profile git dependency failed with default reference - #{@remote_url} - error running '#{command_string}': #{cmd.stderr}")
137
+ else
138
+ ref = cmd.stdout.lines.detect { |l| l.include? "HEAD branch:" }&.split(":")&.last&.strip
139
+ unless ref
140
+ raise(Inspec::FetcherFailure, "Profile git dependency failed with default reference - #{@remote_url} - error running '#{command_string}': NULL reference")
141
+ end
142
+
143
+ ref
144
+ end
145
+ end
146
+
133
147
  def resolve_ref(ref_name)
134
148
  command_string = "git ls-remote \"#{@remote_url}\" \"#{ref_name}*\""
135
149
  cmd = shellout(command_string)
@@ -82,6 +82,7 @@ module Inspec
82
82
  def find_or_register_input(input_name, profile_name, options = {})
83
83
  input_name = input_name.to_s
84
84
  profile_name = profile_name.to_s
85
+ options[:event].value = Thor::CoreExt::HashWithIndifferentAccess.new(options[:event].value) if options[:event]&.value.is_a?(Hash)
85
86
 
86
87
  if profile_alias?(profile_name) && !profile_aliases[profile_name].nil?
87
88
  alias_name = profile_name
@@ -225,14 +225,17 @@ module Inspec
225
225
  end
226
226
  @tests_collected = true
227
227
  end
228
- filter_controls(@runner_context.all_rules, include_list)
228
+ @runner_context.all_rules
229
229
  end
230
230
 
231
- def filter_controls(controls_array, include_list)
232
- return controls_array if include_list.nil? || include_list.empty?
231
+ # This creates the list of controls provided in the --controls options which need to be include
232
+ # for evaluation.
233
+ def include_controls_list
234
+ return [] if @controls.nil? || @controls.empty?
233
235
 
236
+ included_controls = @controls
234
237
  # Check for anything that might be a regex in the list, and make it official
235
- include_list.each_with_index do |inclusion, index|
238
+ included_controls.each_with_index do |inclusion, index|
236
239
  next if inclusion.is_a?(Regexp)
237
240
  # Insist the user wrap the regex in slashes to demarcate it as a regex
238
241
  next unless inclusion.start_with?("/") && inclusion.end_with?("/")
@@ -240,21 +243,14 @@ module Inspec
240
243
  inclusion = inclusion[1..-2] # Trim slashes
241
244
  begin
242
245
  re = Regexp.new(inclusion)
243
- include_list[index] = re
246
+ included_controls[index] = re
244
247
  rescue RegexpError => e
245
248
  warn "Ignoring unparseable regex '/#{inclusion}/' in --control CLI option: #{e.message}"
246
- include_list[index] = nil
247
- end
248
- end
249
- include_list.compact!
250
-
251
- controls_array.select do |c|
252
- id = ::Inspec::Rule.rule_id(c)
253
- include_list.any? do |inclusion|
254
- # Try to see if the inclusion is a regex, and if it matches
255
- inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
249
+ included_controls[index] = nil
256
250
  end
257
251
  end
252
+ included_controls.compact!
253
+ included_controls
258
254
  end
259
255
 
260
256
  def load_libraries
@@ -173,6 +173,9 @@ module Inspec
173
173
 
174
174
  def unregister_rule(id)
175
175
  @rules.delete(full_id(@profile_id, id))
176
+ @control_subcontexts.each do |c|
177
+ c.unregister_rule(id)
178
+ end
176
179
  end
177
180
 
178
181
  attr_reader :current_load
@@ -170,7 +170,7 @@ module Inspec::Reporters
170
170
  end
171
171
 
172
172
  def all_unique_controls
173
- @unique_controls ||= begin
173
+ @unique_controls ||= begin # rubocop:disable Style/RedundantBegin
174
174
  run_data[:profiles].flat_map do |profile|
175
175
  profile[:controls]
176
176
  end.uniq
@@ -8,7 +8,7 @@ module Inspec::Reporters
8
8
  end
9
9
 
10
10
  def report
11
- {
11
+ output = {
12
12
  platform: platform,
13
13
  profiles: profiles,
14
14
  statistics: {
@@ -16,6 +16,11 @@ module Inspec::Reporters
16
16
  },
17
17
  version: run_data[:version],
18
18
  }
19
+
20
+ %w{passthrough}.each do |option|
21
+ output[option.to_sym] = @config[option] unless @config[option].nil?
22
+ end
23
+ output
19
24
  end
20
25
 
21
26
  private
@@ -24,7 +24,7 @@ module Inspec::Reporters
24
24
  version: run_data[:version],
25
25
  }
26
26
 
27
- # optional json-config passthrough options
27
+ # optional jsonconfig passthrough options
28
28
  %w{node_name environment roles job_uuid passthrough}.each do |option|
29
29
  output[option.to_sym] = @config[option] unless @config[option].nil?
30
30
  end
@@ -78,7 +78,7 @@ module Inspec::Resources
78
78
  return @repo_cache if defined?(@repo_cache)
79
79
 
80
80
  # load all lists
81
- cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
81
+ cmd = inspec.command("find /etc/apt/ -name \"*.list\" -exec sh -c 'cat {} || echo -n' \\;")
82
82
 
83
83
  # @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
84
84
  @repo_cache = cmd.stdout.lines.map do |raw_line|
@@ -16,6 +16,8 @@ module Inspec::Resources
16
16
 
17
17
  include FileReader
18
18
 
19
+ attr_reader :conf_path, :content, :params
20
+
19
21
  def initialize(path = nil)
20
22
  @conf_path = path || "/etc/audit/auditd.conf"
21
23
  @content = read_file_content(@conf_path)
@@ -32,6 +32,16 @@ module Inspec::Resources
32
32
 
33
33
  @command = cmd
34
34
 
35
+ cli_timeout = Inspec::Config.cached["command_timeout"].to_i
36
+ # Can access this via Inspec::InspecCLI.commands["exec"].options[:command_timeout].default,
37
+ # but that may not be loaded for kitchen-inspec and other pure gem consumers
38
+ default_cli_timeout = 3600
39
+ if cli_timeout != default_cli_timeout
40
+ @timeout = cli_timeout
41
+ else
42
+ @timeout = options[:timeout]&.to_i || default_cli_timeout
43
+ end
44
+
35
45
  if options[:redact_regex]
36
46
  unless options[:redact_regex].is_a?(Regexp)
37
47
  # Make sure command is replaced so sensitive output isn't shown
@@ -44,7 +54,15 @@ module Inspec::Resources
44
54
  end
45
55
 
46
56
  def result
47
- @result ||= inspec.backend.run_command(@command)
57
+ @result ||= begin
58
+ inspec.backend.run_command(@command, timeout: @timeout)
59
+ rescue Train::CommandTimeoutReached
60
+ # Without a small sleep, the train connection gets broken
61
+ # We've already timed out, so a small sleep is not likely to be painful here.
62
+ sleep 0.1
63
+ raise Inspec::Exceptions::ResourceFailed,
64
+ "Command `#{@command}` timed out after #{@timeout} seconds"
65
+ end
48
66
  end
49
67
 
50
68
  def stdout
@@ -67,8 +67,14 @@ module Inspec::Resources
67
67
  end
68
68
 
69
69
  def crontab_cmd
70
- # TODO: the -u scenario needs to be able to do sudo
71
- @user.nil? ? "crontab -l" : "crontab -l -u #{@user}"
70
+ if @user.nil?
71
+ "crontab -l"
72
+ elsif inspec.os.aix?
73
+ "crontab -l #{@user}"
74
+ else
75
+ # TODO: the -u scenario needs to be able to do sudo
76
+ "crontab -l -u #{@user}"
77
+ end
72
78
  end
73
79
 
74
80
  filter = FilterTable.create
@@ -54,6 +54,21 @@ module Inspec::Resources
54
54
  "nginx_conf #{@conf_path}"
55
55
  end
56
56
 
57
+ def method_missing(name)
58
+ return super if name.to_s.match?(/^to_/)
59
+
60
+ v = params[name.to_s]
61
+ return v.flatten unless v.nil?
62
+
63
+ nil
64
+ end
65
+
66
+ def respond_to_missing?(name, include_all = false)
67
+ return super if name.to_s.match?(/^to_/)
68
+
69
+ true
70
+ end
71
+
57
72
  private
58
73
 
59
74
  def read_content(path)
@@ -175,6 +190,18 @@ module Inspec::Resources
175
190
  end
176
191
  alias inspect to_s
177
192
 
193
+ def method_missing(name)
194
+ return super if name.to_s.match?(/^to_/)
195
+
196
+ (@params[name.to_s] || []).flatten
197
+ end
198
+
199
+ def respond_to_missing?(name, include_all = false)
200
+ return super if name.to_s.match?(/^to_/)
201
+
202
+ true
203
+ end
204
+
178
205
  private
179
206
 
180
207
  def server_table
@@ -207,6 +234,18 @@ module Inspec::Resources
207
234
  end
208
235
  alias inspect to_s
209
236
 
237
+ def method_missing(name)
238
+ return super if name.to_s.match?(/^to_/)
239
+
240
+ (@params[name.to_s] || []).flatten
241
+ end
242
+
243
+ def respond_to_missing?(name, include_all = false)
244
+ return super if name.to_s.match?(/^to_/)
245
+
246
+ true
247
+ end
248
+
210
249
  private
211
250
 
212
251
  def location_table
@@ -48,7 +48,7 @@ module Inspec::Resources
48
48
  format_options = "set sqlformat csv\nSET FEEDBACK OFF"
49
49
  else
50
50
  @bin = "#{@sqlplus_bin} -S"
51
- format_options = "SET MARKUP CSV ON\nSET PAGESIZE 32000\nSET FEEDBACK OFF"
51
+ format_options = "SET PAGESIZE 32000\nSET FEEDBACK OFF\nSET UNDERLINE OFF"
52
52
  end
53
53
 
54
54
  command = command_builder(format_options, sql)
@@ -39,7 +39,7 @@ module Inspec::Resources
39
39
  def convert_hash(hash)
40
40
  new_hash = {}
41
41
  hash.each do |k, v|
42
- new_hash[k.downcase] = v
42
+ new_hash[k.downcase] ||= v
43
43
  end
44
44
  new_hash
45
45
  end
@@ -5,7 +5,7 @@ require "matchers/matchers"
5
5
  require "inspec/rspec_extensions"
6
6
 
7
7
  # There be dragons!! Or borgs, or something...
8
- # This file and all its contents cannot be unit-tested. both test-suits
8
+ # This file and all its contents cannot be unit-tested. both test-suites
9
9
  # collide and disable all unit tests that have been added.
10
10
 
11
11
  module Inspec
@@ -36,14 +36,20 @@ module FilterTable
36
36
  # RSpec will check the object returned to see if it responds to a method
37
37
  # before calling it. We need to fake it out and tell it that it does. This
38
38
  # allows it to skip past that check and fall through to #method_missing
39
- def respond_to?(_method)
39
+ def respond_to?(_method, include_all = false)
40
40
  true
41
41
  end
42
42
 
43
43
  def to_s
44
- @original_resource.to_s
44
+ "#{@original_resource} (#{@original_exception.message})"
45
45
  end
46
46
  alias inspect to_s
47
+
48
+ # Rspec is not able to convert FilterTable::ExceptionCatcher issue https://github.com/inspec/inspec/issues/5369
49
+ # which result into not showing actual exception message this allows to convert it properly.
50
+ def to_ary
51
+ [ to_s ]
52
+ end
47
53
  end
48
54
 
49
55
  class Trace
@@ -13,6 +13,7 @@ module Inspec
13
13
  def apply_run_data_filters_to_hash
14
14
  @config[:runtime_config] = Inspec::Config.cached || {}
15
15
  apply_report_resize_options
16
+ filter_empty_profiles
16
17
  redact_sensitive_inputs
17
18
  suppress_diff_output
18
19
  sort_controls
@@ -36,6 +37,14 @@ module Inspec
36
37
  end
37
38
  end
38
39
 
40
+ # Filters profiles from report which don't have controls in it.
41
+ def filter_empty_profiles
42
+ runtime_config = @config[:runtime_config]
43
+ if runtime_config[:filter_empty_profiles] && @run_data[:profiles].count > 1
44
+ @run_data[:profiles].delete_if { |p| p[:controls].empty? }
45
+ end
46
+ end
47
+
39
48
  # Find any inputs with :sensitive = true and replace their values with "***"
40
49
  def redact_sensitive_inputs
41
50
  @run_data[:profiles]&.each do |p|
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.25.1".freeze
2
+ VERSION = "4.31.0".freeze
3
3
  end
@@ -287,7 +287,7 @@ RSpec::Matchers.define :cmp do |first_expected| # rubocop:disable Metrics/BlockL
287
287
  end
288
288
 
289
289
  def format_actual(actual)
290
- actual = "0%o" % actual if octal?(@expected)
290
+ actual = "0%o" % actual if octal?(@expected) && !actual.nil?
291
291
  "\n%s\n got: %s\n\n(compared using `cmp` matcher)\n" % [format_expectation(false), actual]
292
292
  end
293
293
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  This example shows the implementation of an InSpec profile for AWS.
4
4
 
5
- ## Create a profile
5
+ ## Create a profile
6
6
 
7
7
  ```
8
8
  $ inspec init profile --platform aws my-profile
@@ -15,12 +15,12 @@ Creating new profile at /Users/spaterson/my-profile
15
15
  • Creating directory controls
16
16
  • Creating file controls/example.rb
17
17
  • Creating file inspec.yml
18
- • Creating file attributes.yml
18
+ • Creating file inputs.yml
19
19
  • Creating file libraries/.gitkeep
20
-
20
+
21
21
  ```
22
22
 
23
- ## Optionally update `attributes.yml` to point to your custom VPC
23
+ ## Optionally update `inputs.yml` to point to your custom VPC
24
24
 
25
25
  ```
26
26
  aws_vpc_id: 'custom-vpc-id'
@@ -32,11 +32,11 @@ The related control will simply be skipped if this is not provided. See the [In
32
32
 
33
33
  ### With a VPC Identifier
34
34
 
35
- With a supplied VPC identifier in `attributes.yml` both of the example controls will run. The 'aws-single-vpc-exists-check' control will only check for a VPC identifier in the currently configured AWS SDK region e.g. `eu-west-2` in the below:
35
+ With a supplied VPC identifier in `inputs.yml` both of the example controls will run. The 'aws-single-vpc-exists-check' control will only check for a VPC identifier in the currently configured AWS SDK region e.g. `eu-west-2` in the below:
36
36
 
37
37
  ```
38
38
  $ cd my-profile/
39
- $ inspec exec . -t aws:// --attrs attributes.yml
39
+ $ inspec exec . -t aws:// --input-file=inputs.yml
40
40
 
41
41
  Profile: AWS InSpec Profile (my-profile)
42
42
  Version: 0.1.0
@@ -111,13 +111,13 @@ Test Summary: 53 successful, 0 failures, 0 skipped
111
111
  ```
112
112
 
113
113
 
114
- ### Without Supplying a VPC Identifier
114
+ ### Without Supplying a VPC Identifier
115
115
 
116
- If no VPC identifier is supplied, the 'aws-single-vpc-exists-check' control is skipped and the other control runs. The `attributes.yml` file does not have to be specified to InSpec in this case.
116
+ If no VPC identifier is supplied, the 'aws-single-vpc-exists-check' control is skipped and the other control runs. The `inputs.yml` file does not have to be specified to InSpec in this case.
117
117
 
118
118
  ```
119
119
  $ cd my-profile/
120
- $ inspec exec . -t aws://
120
+ $ inspec exec . -t aws://
121
121
 
122
122
  Profile: AWS InSpec Profile (my-profile)
123
123
  Version: 0.1.0
@@ -189,4 +189,4 @@ Target: aws://eu-west-2
189
189
 
190
190
  Profile Summary: 2 successful controls, 0 control failures, 1 control skipped
191
191
  Test Summary: 52 successful, 0 failures, 1 skipped
192
- ```
192
+ ```
@@ -2,11 +2,11 @@
2
2
 
3
3
  title "Sample Section"
4
4
 
5
- aws_vpc_id = attribute("aws_vpc_id", default: "", description: "Optional AWS VPC identifier.")
5
+ aws_vpc_id = input("aws_vpc_id")
6
6
 
7
7
  # You add controls here
8
- control "aws-single-vpc-exists-check" do # A unique ID for this control.
9
- only_if { aws_vpc_id != "" } # Only run this control if the `aws_vpc_id` attribute is provided.
8
+ control "aws-single-vpc-exists-check" do # A unique ID for this control.
9
+ only_if { aws_vpc_id != "" } # Only run this control if the `aws_vpc_id` input is provided.
10
10
  impact 1.0 # The criticality, if this control fails.
11
11
  title "Check to see if custom VPC exists." # A human-readable title.
12
12
  describe aws_vpc(aws_vpc_id) do # The test itself.
@@ -7,14 +7,13 @@ license: Apache-2.0
7
7
  summary: An InSpec Compliance Profile For AWS
8
8
  version: 0.1.0
9
9
  inspec_version: '~> 4'
10
- attributes:
10
+ inputs:
11
11
  - name: aws_vpc_id
12
12
  required: false
13
13
  # Below is deliberately left as a default empty string to allow the profile to run when this is not provided.
14
14
  # Please see the README for more details.
15
- default: ''
15
+ value: ''
16
16
  description: 'Optional Custom AWS VPC Id'
17
- type: string
18
17
  depends:
19
18
  - name: inspec-aws
20
19
  url: https://github.com/inspec/inspec-aws/archive/master.tar.gz
@@ -2,7 +2,7 @@
2
2
 
3
3
  This example shows the implementation of an InSpec profile for GCP that depends on the [InSpec GCP Resource Pack](https://github.com/inspec/inspec-gcp). See the [README](https://github.com/inspec/inspec-gcp) for instructions on setting up appropriate GCP credentials.
4
4
 
5
- ## Create a profile
5
+ ## Create a profile
6
6
 
7
7
  ```
8
8
  $ inspec init profile --platform gcp my-profile
@@ -12,12 +12,12 @@ Create new profile at /Users/spaterson/my-profile
12
12
  * Create directory controls
13
13
  * Create file controls/example.rb
14
14
  * Create file inspec.yml
15
- * Create file attributes.yml
16
- * Create file libraries/.gitkeep
17
-
15
+ * Create file inputs.yml
16
+ * Create file libraries/.gitkeep
17
+
18
18
  ```
19
19
 
20
- ## Update `attributes.yml` to point to your project
20
+ ## Update `inputs.yml` to point to your project
21
21
 
22
22
  ```
23
23
  gcp_project_id: 'my-gcp-project'
@@ -27,7 +27,7 @@ gcp_project_id: 'my-gcp-project'
27
27
 
28
28
  ```
29
29
  $ cd gcp-profile/
30
- $ inspec exec . -t gcp:// --attrs attributes.yml
30
+ $ inspec exec . -t gcp:// --input-file=inputs.yml
31
31
 
32
32
  Profile: GCP InSpec Profile (my-profile)
33
33
  Version: 0.1.0
@@ -63,4 +63,4 @@ Target: gcp://local-service-account@my-gcp-project.iam.gserviceaccount.com
63
63
 
64
64
  Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped
65
65
  Test Summary: 18 successful, 0 failures, 0 skipped
66
- ```
66
+ ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  title "Sample Section"
4
4
 
5
- gcp_project_id = attribute("gcp_project_id")
5
+ gcp_project_id = input("gcp_project_id")
6
6
 
7
7
  # you add controls here
8
8
  control "gcp-single-region-1.0" do # A unique ID for this control
@@ -6,14 +6,13 @@ copyright_email: you@example.com
6
6
  license: Apache-2.0
7
7
  summary: An InSpec Compliance Profile For GCP
8
8
  version: 0.1.0
9
- inspec_version: '>= 2.3.5'
10
- attributes:
9
+ inspec_version: '>= 4'
10
+ inputs:
11
11
  - name: gcp_project_id
12
12
  required: true
13
13
  description: 'The GCP project identifier.'
14
- type: string
15
14
  depends:
16
15
  - name: inspec-gcp
17
16
  url: https://github.com/inspec/inspec-gcp/archive/master.tar.gz
18
17
  supports:
19
- - platform: gcp
18
+ - platform: gcp
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.25.1
4
+ version: 4.31.0
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-01-20 00:00:00.000000000 Z
11
+ date: 2021-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -234,6 +234,20 @@ dependencies:
234
234
  - - "<"
235
235
  - !ruby/object:Gem::Version
236
236
  version: '1.4'
237
+ - !ruby/object:Gem::Dependency
238
+ name: faraday_middleware
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '1.0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '1.0'
237
251
  - !ruby/object:Gem::Dependency
238
252
  name: tty-table
239
253
  requirement: !ruby/object:Gem::Requirement
@@ -305,7 +319,7 @@ dependencies:
305
319
  version: '1.5'
306
320
  - - "<"
307
321
  - !ruby/object:Gem::Version
308
- version: '3.0'
322
+ version: '2.0'
309
323
  type: :runtime
310
324
  prerelease: false
311
325
  version_requirements: !ruby/object:Gem::Requirement
@@ -315,7 +329,7 @@ dependencies:
315
329
  version: '1.5'
316
330
  - - "<"
317
331
  - !ruby/object:Gem::Version
318
- version: '3.0'
332
+ version: '2.0'
319
333
  - !ruby/object:Gem::Dependency
320
334
  name: semverse
321
335
  requirement: !ruby/object:Gem::Requirement
@@ -697,15 +711,15 @@ files:
697
711
  - lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/reporter.rb
698
712
  - lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/version.rb
699
713
  - lib/plugins/inspec-init/templates/profiles/aws/README.md
700
- - lib/plugins/inspec-init/templates/profiles/aws/attributes.yml
701
714
  - lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb
715
+ - lib/plugins/inspec-init/templates/profiles/aws/inputs.yml
702
716
  - lib/plugins/inspec-init/templates/profiles/aws/inspec.yml
703
717
  - lib/plugins/inspec-init/templates/profiles/azure/README.md
704
718
  - lib/plugins/inspec-init/templates/profiles/azure/controls/example.rb
705
719
  - lib/plugins/inspec-init/templates/profiles/azure/inspec.yml
706
720
  - lib/plugins/inspec-init/templates/profiles/gcp/README.md
707
- - lib/plugins/inspec-init/templates/profiles/gcp/attributes.yml
708
721
  - lib/plugins/inspec-init/templates/profiles/gcp/controls/example.rb
722
+ - lib/plugins/inspec-init/templates/profiles/gcp/inputs.yml
709
723
  - lib/plugins/inspec-init/templates/profiles/gcp/inspec.yml
710
724
  - lib/plugins/inspec-init/templates/profiles/os/README.md
711
725
  - lib/plugins/inspec-init/templates/profiles/os/controls/example.rb