inspec 1.45.9 → 1.45.13

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +54 -32
  3. data/CHANGELOG.md +29 -21
  4. data/Gemfile +1 -1
  5. data/docs/resources/ini.md.erb +14 -1
  6. data/docs/shell.md +1 -1
  7. data/inspec.gemspec +2 -2
  8. data/lib/bundles/inspec-artifact/cli.rb +3 -8
  9. data/lib/bundles/inspec-compliance/configuration.rb +5 -5
  10. data/lib/bundles/inspec-compliance/http.rb +2 -5
  11. data/lib/bundles/inspec-compliance/target.rb +6 -6
  12. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +1 -1
  13. data/lib/bundles/inspec-habitat/profile.rb +68 -74
  14. data/lib/bundles/inspec-supermarket/api.rb +7 -7
  15. data/lib/bundles/inspec-supermarket/cli.rb +1 -1
  16. data/lib/fetchers/git.rb +3 -8
  17. data/lib/fetchers/local.rb +7 -13
  18. data/lib/fetchers/url.rb +1 -1
  19. data/lib/inspec/backend.rb +0 -1
  20. data/lib/inspec/base_cli.rb +1 -1
  21. data/lib/inspec/cached_fetcher.rb +11 -12
  22. data/lib/inspec/cli.rb +0 -1
  23. data/lib/inspec/control_eval_context.rb +2 -2
  24. data/lib/inspec/dependencies/lockfile.rb +13 -15
  25. data/lib/inspec/dependencies/requirement.rb +1 -1
  26. data/lib/inspec/dependencies/resolver.rb +3 -5
  27. data/lib/inspec/dsl.rb +5 -5
  28. data/lib/inspec/dsl_shared.rb +1 -1
  29. data/lib/inspec/env_printer.rb +26 -26
  30. data/lib/inspec/metadata.rb +11 -10
  31. data/lib/inspec/objects/or_test.rb +4 -2
  32. data/lib/inspec/objects/test.rb +1 -1
  33. data/lib/inspec/profile.rb +2 -2
  34. data/lib/inspec/resource.rb +1 -3
  35. data/lib/inspec/rspec_json_formatter.rb +6 -8
  36. data/lib/inspec/shell.rb +51 -52
  37. data/lib/inspec/version.rb +1 -1
  38. data/lib/matchers/matchers.rb +1 -2
  39. data/lib/resources/audit_policy.rb +2 -2
  40. data/lib/resources/auditd.rb +6 -3
  41. data/lib/resources/dh_params.rb +1 -2
  42. data/lib/resources/docker.rb +2 -2
  43. data/lib/resources/docker_container.rb +4 -4
  44. data/lib/resources/elasticsearch.rb +2 -6
  45. data/lib/resources/etc_group.rb +2 -4
  46. data/lib/resources/groups.rb +14 -14
  47. data/lib/resources/host.rb +2 -3
  48. data/lib/resources/packages.rb +1 -1
  49. data/lib/resources/port.rb +1 -1
  50. data/lib/resources/postgres.rb +6 -6
  51. data/lib/resources/powershell.rb +1 -1
  52. data/lib/resources/service.rb +4 -5
  53. data/lib/resources/users.rb +58 -58
  54. data/lib/resources/vbscript.rb +10 -10
  55. data/lib/resources/virtualization.rb +3 -4
  56. data/lib/resources/x509_certificate.rb +1 -1
  57. data/lib/resources/yum.rb +1 -1
  58. data/lib/source_readers/inspec.rb +2 -1
  59. data/lib/utils/command_wrapper.rb +3 -8
  60. data/lib/utils/filter.rb +1 -1
  61. data/lib/utils/json_log.rb +2 -1
  62. data/lib/utils/latest_version.rb +5 -4
  63. data/lib/utils/object_traversal.rb +1 -1
  64. data/lib/utils/parser.rb +2 -2
  65. metadata +4 -4
@@ -54,11 +54,11 @@ module Supermarket
54
54
 
55
55
  def self.find(profile, supermarket_url = SUPERMARKET_URL)
56
56
  profiles = Supermarket::API.profiles(supermarket_url)
57
- if !profiles.empty?
58
- index = profiles.index { |t| same?(profile, t, supermarket_url) }
59
- # return profile or nil
60
- profiles[index] if !index.nil? && index >= 0
61
- end
57
+ return if profiles.empty?
58
+
59
+ index = profiles.index { |t| same?(profile, t, supermarket_url) }
60
+ # return profile or nil
61
+ profiles[index] if !index.nil? && index >= 0
62
62
  end
63
63
 
64
64
  # verifies that a profile exists
@@ -75,9 +75,9 @@ module Supermarket
75
75
 
76
76
  def self.send_request(uri, req)
77
77
  # send request
78
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') {|http|
78
+ res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
79
79
  http.request(req)
80
- }
80
+ end
81
81
  [res.is_a?(Net::HTTPSuccess), res.body]
82
82
  end
83
83
  end
@@ -42,7 +42,7 @@ module Supermarket
42
42
  # check that the profile is available
43
43
  supermarket_profiles = Supermarket::API.profiles
44
44
  found = supermarket_profiles.select { |p|
45
- "#{p['tool_owner']}/#{p['slug']}" == profile
45
+ profile == "#{p['tool_owner']}/#{p['slug']}"
46
46
  }
47
47
 
48
48
  if found.empty?
data/lib/fetchers/git.rb CHANGED
@@ -24,14 +24,12 @@ module Fetchers
24
24
  # you got to this file during debugging, you may want to look at the
25
25
  # omnibus source for hints.
26
26
  #
27
- class Git < Inspec.fetcher(1) # rubocop:disable ClassLength
27
+ class Git < Inspec.fetcher(1)
28
28
  name 'git'
29
29
  priority 200
30
30
 
31
31
  def self.resolve(target, opts = {})
32
- if target.respond_to?(:has_key?) &&target.key?(:git)
33
- new(target[:git], opts.merge(target))
34
- end
32
+ new(target[:git], opts.merge(target)) if target.respond_to?(:has_key?) && target.key?(:git)
35
33
  end
36
34
 
37
35
  def initialize(remote_url, opts = {})
@@ -121,10 +119,7 @@ module Fetchers
121
119
  if tagged_commit
122
120
  tagged_commit.first
123
121
  else
124
- found = pairs.find { |m| m[1].end_with?(ref_name.to_s) }
125
- if found
126
- found.first
127
- end
122
+ pairs.find { |m| m[1].end_with?(ref_name.to_s) }&.first
128
123
  end
129
124
  end
130
125
 
@@ -16,19 +16,15 @@ module Fetchers
16
16
  resolve_from_hash(target)
17
17
  end
18
18
 
19
- if local_path
20
- new(local_path)
21
- end
19
+ new(local_path) if local_path
22
20
  end
23
21
 
24
22
  def self.resolve_from_hash(target)
25
- if target.key?(:path)
26
- local_path = target[:path]
27
- if target.key?(:cwd)
28
- local_path = File.expand_path(local_path, target[:cwd])
29
- end
30
- local_path
31
- end
23
+ return unless target.key?(:path)
24
+
25
+ local_path = target[:path]
26
+ local_path = File.expand_path(local_path, target[:cwd]) if target.key?(:cwd)
27
+ local_path
32
28
  end
33
29
 
34
30
  def self.resolve_from_string(target)
@@ -40,9 +36,7 @@ module Fetchers
40
36
  target = target.tr('\\', '/')
41
37
  end
42
38
 
43
- if File.exist?(target)
44
- target
45
- end
39
+ target if File.exist?(target)
46
40
  end
47
41
 
48
42
  def initialize(target)
data/lib/fetchers/url.rb CHANGED
@@ -141,7 +141,7 @@ module Fetchers
141
141
 
142
142
  # Downloads archive to temporary file with side effect :( of setting @archive_type
143
143
  def download_archive_to_temp
144
- return @temp_archive_path if ! @temp_archive_path.nil?
144
+ return @temp_archive_path if !@temp_archive_path.nil?
145
145
  Inspec::Log.debug("Fetching URL: #{@target}")
146
146
  remote = open(@target, http_opts)
147
147
  @archive_type = file_type_from_remote(remote) # side effect :(
@@ -68,7 +68,6 @@ module Inspec
68
68
  end
69
69
 
70
70
  cls.new
71
-
72
71
  rescue Train::ClientError => e
73
72
  raise "Client error, can't connect to '#{name}' backend: #{e.message}"
74
73
  rescue Train::TransportError => e
@@ -134,7 +134,7 @@ module Inspec
134
134
  config = File.read(file)
135
135
  end
136
136
 
137
- JSON.load(config)
137
+ JSON.parse(config)
138
138
  rescue JSON::ParserError => e
139
139
  puts "Failed to load JSON configuration: #{e}\nConfig was: #{config.inspect}"
140
140
  exit 1
@@ -48,20 +48,19 @@ module Inspec
48
48
  end
49
49
 
50
50
  def assert_cache_sanity!
51
- if target.respond_to?(:key?) && target.key?(:sha256)
52
- if fetcher.resolved_source[:sha256] != target[:sha256]
53
- raise <<EOF
54
- The remote source #{fetcher} no longer has the requested content:
51
+ return unless target.respond_to?(:key?) && target.key?(:sha256)
55
52
 
56
- Request Content Hash: #{target[:sha256]}
57
- Actual Content Hash: #{fetcher.resolved_source[:sha256]}
53
+ exception_message = <<~EOF
54
+ The remote source #{fetcher} no longer has the requested content:
58
55
 
59
- For URL, supermarket, compliance, and other sources that do not
60
- provide versioned artifacts, this likely means that the remote source
61
- has changed since your lockfile was generated.
62
- EOF
63
- end
64
- end
56
+ Request Content Hash: #{target[:sha256]}
57
+ Actual Content Hash: #{fetcher.resolved_source[:sha256]}
58
+
59
+ For URL, supermarket, compliance, and other sources that do not
60
+ provide versioned artifacts, this likely means that the remote source
61
+ has changed since your lockfile was generated.
62
+ EOF
63
+ raise exception_message if fetcher.resolved_source[:sha256] != target[:sha256]
65
64
  end
66
65
  end
67
66
  end
data/lib/inspec/cli.rb CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: utf-8
3
2
  # Copyright 2015 Dominik Richter
4
3
  # author: Dominik Richter
@@ -40,7 +40,7 @@ module Inspec
40
40
  profile_context_owner = profile_context
41
41
  profile_id = profile_context.profile_id
42
42
 
43
- Class.new do
43
+ Class.new do # rubocop:disable Metrics/BlockLength
44
44
  include Inspec::DSL
45
45
  include Inspec::DSL::RequireOverride
46
46
  include resources_dsl
@@ -80,7 +80,7 @@ module Inspec
80
80
  # the describe block in the context of that control.
81
81
  #
82
82
  define_method :describe do |*args, &block|
83
- loc = block_location(block, caller[0])
83
+ loc = block_location(block, caller(1..1).first)
84
84
  id = "(generated from #{loc} #{SecureRandom.hex})"
85
85
 
86
86
  res = nil
@@ -31,22 +31,22 @@ module Inspec
31
31
  # rubocop:disable Style/GuardClause
32
32
  def self.validate_lockfile_version!(version)
33
33
  if version < MINIMUM_SUPPORTED_VERSION
34
- raise <<EOF
35
- This lockfile specifies a lockfile_version of #{version} which is
36
- lower than the minimum supported version #{MINIMUM_SUPPORTED_VERSION}.
34
+ raise <<~EOF
35
+ This lockfile specifies a lockfile_version of #{version} which is
36
+ lower than the minimum supported version #{MINIMUM_SUPPORTED_VERSION}.
37
37
 
38
- Please create a new lockfile for this project by running:
38
+ Please create a new lockfile for this project by running:
39
39
 
40
- inspec vendor
41
- EOF
40
+ inspec vendor
41
+ EOF
42
42
  elsif version > CURRENT_LOCKFILE_VERSION
43
- raise <<EOF
44
- This lockfile claims to be version #{version} which is greater than
45
- the most recent lockfile version(#{CURRENT_LOCKFILE_VERSION}).
43
+ raise <<~EOF
44
+ This lockfile claims to be version #{version} which is greater than
45
+ the most recent lockfile version(#{CURRENT_LOCKFILE_VERSION}).
46
46
 
47
- This may happen if you are using an older version of inspec than was
48
- used to create the lockfile.
49
- EOF
47
+ This may happen if you are using an older version of inspec than was
48
+ used to create the lockfile.
49
+ EOF
50
50
  end
51
51
  end
52
52
  # rubocop:enable Style/GuardClause
@@ -87,9 +87,7 @@ EOF
87
87
  end
88
88
 
89
89
  def parse_content_hash_1(lockfile_content_hash)
90
- @deps = if lockfile_content_hash['depends']
91
- lockfile_content_hash['depends'].map { |i| symbolize_keys(i) }
92
- end
90
+ @deps = lockfile_content_hash['depends']&.map { |i| symbolize_keys(i) }
93
91
  end
94
92
 
95
93
  def mutate_hash_keys_with(hash, fun)
@@ -111,7 +111,7 @@ module Inspec
111
111
 
112
112
  # load the profile for the requirement
113
113
  def profile
114
- return @profile if ! @profile.nil?
114
+ return @profile unless @profile.nil?
115
115
  opts = @opts.dup
116
116
  opts[:backend] = @backend
117
117
  if !@dependencies.nil?
@@ -64,11 +64,9 @@ module Inspec
64
64
  path_string + " -> #{dep.name}"
65
65
  end
66
66
 
67
- if new_seen_items.key?(dep.resolved_source)
68
- raise Inspec::CyclicDependencyError, "Dependency #{dep} would cause a dependency cycle (#{new_path_string})"
69
- else
70
- new_seen_items[dep.resolved_source] = true
71
- end
67
+ raise Inspec::CyclicDependencyError, "Dependency #{dep} would cause a dependency cycle (#{new_path_string})" if new_seen_items.key?(dep.resolved_source)
68
+
69
+ new_seen_items[dep.resolved_source] = true
72
70
 
73
71
  if !dep.source_satisfies_spec?
74
72
  raise Inspec::UnsatisfiedVersionSpecification, "The profile #{dep.name} from #{dep.resolved_source} has a version #{dep.source_version} which doesn't match #{dep.version_constraints}"
data/lib/inspec/dsl.rb CHANGED
@@ -33,12 +33,12 @@ module Inspec::DSL
33
33
 
34
34
  dep_entry = dependencies.list[profile_id]
35
35
  if dep_entry.nil?
36
- raise <<EOF
37
- Cannot load #{profile_id} since it is not listed as a dependency of #{bind_context.profile_name}.
36
+ raise <<~EOF
37
+ Cannot load #{profile_id} since it is not listed as a dependency of #{bind_context.profile_name}.
38
38
 
39
- Dependencies available from this context are:
40
- #{dependencies.list.keys.join("\n ")}
41
- EOF
39
+ Dependencies available from this context are:
40
+ #{dependencies.list.keys.join("\n ")}
41
+ EOF
42
42
  end
43
43
 
44
44
  context = dep_entry.profile.runner_context
@@ -18,7 +18,7 @@ module Inspec
18
18
  # We cannot rely on libraries residing on disk however.
19
19
  # TODO: Sandboxing.
20
20
  content, path, line = @require_loader.load(rbpath)
21
- eval(content, TOPLEVEL_BINDING, path, line) # rubocop:disable Lint/Eval
21
+ eval(content, TOPLEVEL_BINDING, path, line) # rubocop:disable Security/Eval
22
22
  end
23
23
  end
24
24
  end
@@ -41,7 +41,7 @@ module Inspec
41
41
  end
42
42
 
43
43
  def have_shell?
44
- ! (@shell.nil? || @shell.empty?)
44
+ !(@shell.nil? || @shell.empty?)
45
45
  end
46
46
 
47
47
  def have_shell_completion?
@@ -61,26 +61,26 @@ module Inspec
61
61
  end
62
62
 
63
63
  def print_usage_guidance
64
- puts <<EOF
65
- # To use this, eval it in your shell
66
- #
67
- # #{EVAL_COMMANDS[shell]}
68
- #
69
- #
70
- EOF
64
+ puts <<~EOF
65
+ # To use this, eval it in your shell
66
+ #
67
+ # #{EVAL_COMMANDS[shell]}
68
+ #
69
+ #
70
+ EOF
71
71
  end
72
72
 
73
73
  def print_detection_warning(device)
74
- device.puts <<EOF
75
- #
76
- # The shell #{@shell} was auto-detected. If this is incorrect, please
77
- # specify a shell explicitly by running:
78
- #
79
- # inspec env SHELLNAME
80
- #
81
- # Currently supported shells are: #{shells_with_completions.join(', ')}
82
- #
83
- EOF
74
+ device.puts <<~EOF
75
+ #
76
+ # The shell #{@shell} was auto-detected. If this is incorrect, please
77
+ # specify a shell explicitly by running:
78
+ #
79
+ # inspec env SHELLNAME
80
+ #
81
+ # Currently supported shells are: #{shells_with_completions.join(', ')}
82
+ #
83
+ EOF
84
84
  end
85
85
 
86
86
  def exit_no_completion
@@ -93,14 +93,14 @@ EOF
93
93
  if @detected
94
94
  $stderr.puts '# Unable to automatically detect shell and no shell was provided.'
95
95
  end
96
- $stderr.puts <<EOF
97
- #
98
- # Please provide the name of your shell via the command line:
99
- #
100
- # inspec env SHELLNAME
101
- #
102
- # Currently supported shells are: #{shells_with_completions.join(', ')}
103
- EOF
96
+ $stderr.puts <<~EOF
97
+ #
98
+ # Please provide the name of your shell via the command line:
99
+ #
100
+ # inspec env SHELLNAME
101
+ #
102
+ # Currently supported shells are: #{shells_with_completions.join(', ')}
103
+ EOF
104
104
  exit 1
105
105
  end
106
106
 
@@ -110,7 +110,7 @@ module Inspec
110
110
  errors = []
111
111
  warnings = []
112
112
 
113
- %w{ name version }.each do |field|
113
+ %w{name version}.each do |field|
114
114
  next unless params[field.to_sym].nil?
115
115
  errors.push("Missing profile #{field} in #{ref}")
116
116
  end
@@ -126,7 +126,7 @@ module Inspec
126
126
  errors.push('Version needs to be in SemVer format')
127
127
  end
128
128
 
129
- %w{ title summary maintainer copyright license }.each do |field|
129
+ %w{title summary maintainer copyright license}.each do |field|
130
130
  next unless params[field.to_sym].nil?
131
131
  warnings.push("Missing profile #{field} in #{ref}")
132
132
  end
@@ -165,11 +165,11 @@ module Inspec
165
165
  return obj.map { |i| symbolize_keys(i) } if obj.is_a?(Array)
166
166
  return obj unless obj.is_a?(Hash)
167
167
 
168
- obj.each_with_object({}) {|(k, v), h|
168
+ obj.each_with_object({}) do |(k, v), h|
169
169
  v = symbolize_keys(v) if v.is_a?(Hash)
170
170
  v = symbolize_keys(v) if v.is_a?(Array)
171
171
  h[k.to_sym] = v
172
- }
172
+ end
173
173
  end
174
174
 
175
175
  def self.finalize_supports_elem(elem, logger)
@@ -188,7 +188,8 @@ module Inspec
188
188
  logger ||= Logger.new(nil)
189
189
  logger.warn(
190
190
  "Do not use deprecated `supports: #{x}` syntax. Instead use:\n"\
191
- "supports:\n - os-family: #{x}\n\n")
191
+ "supports:\n - os-family: #{x}\n\n",
192
+ )
192
193
  { :'os-family' => x } # rubocop:disable Style/HashSyntax
193
194
  end
194
195
  end
@@ -202,7 +203,8 @@ module Inspec
202
203
  logger ||= Logger.new(nil)
203
204
  logger.warn(
204
205
  "Do not use deprecated `supports: #{x}` syntax. Instead use:\n"\
205
- "supports:\n - os-family: #{x}\n\n")
206
+ "supports:\n - os-family: #{x}\n\n",
207
+ )
206
208
  [{ :'os-family' => x }] # rubocop:disable Style/HashSyntax
207
209
  end
208
210
  end
@@ -223,10 +225,9 @@ module Inspec
223
225
  # create a new name based on the original target if it exists
224
226
  # Crudely slug the target to not contain slashes, to avoid breaking
225
227
  # unit tests that look for warning sequences
226
- unless original_target.to_s.empty?
227
- metadata.params[:title] = "tests from #{original_target}"
228
- metadata.params[:name] = metadata.params[:title].gsub(%r{[\\\/]}, '.')
229
- end
228
+ return if original_target.to_s.empty?
229
+ metadata.params[:title] = "tests from #{original_target}"
230
+ metadata.params[:name] = metadata.params[:title].gsub(%r{[\\\/]}, '.')
230
231
  end
231
232
 
232
233
  def self.finalize(metadata, profile_id, options, logger = nil)
@@ -24,10 +24,12 @@ module Inspec
24
24
  test.negate!
25
25
  test
26
26
  }.map(&:to_ruby).join("\n")
27
- return all_tests
27
+
28
+ all_tests
28
29
  else
29
30
  all_tests = @tests.map(&:to_ruby).join("\n").gsub("\n", "\n ")
30
- return format("describe.one do\n %s\nend", all_tests)
31
+
32
+ format("describe.one do\n %s\nend", all_tests)
31
33
  end
32
34
  end
33
35