inspec 1.45.9 → 1.45.13

Sign up to get free protection for your applications and to get access to all the features.
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