inspec-core 4.56.20 → 4.56.58

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5cd060fe45d6cb0fa653922f1fa8c63e723e8736bfa3c4b821e7a4f1e109fae
4
- data.tar.gz: 5c5ceb1b63e19b6311d7ef9a5ce601b98a782397439b3e97dcc4f590c9ca739b
3
+ metadata.gz: c9817a3eab9cc59b2a73fff43f35ecb954d48b9a16b2e1e1a7eb44bbd1389420
4
+ data.tar.gz: 410c6d2786f8cccc6690593e5db3bb03be0bc77444ea8fab9504213b9594102c
5
5
  SHA512:
6
- metadata.gz: 3a028a6ea4d48e8eba83804548abc255ac2fb2ecfd76d450223cc24eab43f84382dec1de8813fd7b9f7284ffd1ef7f8a9948724850469296d086dd9c9bb55173
7
- data.tar.gz: 534d17549cbf55ffc635a4a9f0689372093debd6f2bbe020f15d606619b451c5441bd2266a8f092024409d0bbe3715d5b7bb7bebf695bba0f23ae2b4112f8553
6
+ metadata.gz: c93dd109c5676294db7ecc9dd944769df71badcf3df9d116583b7429a07da78087fa3f1194d6d2cfe0acc6ecf8483abba72fe3d490b2439f01e736bdf41cce3d
7
+ data.tar.gz: 62058048a64e284a585c4a38f4a906d3aeab03142287726393e71ae8088b8f766d2eed97bd7a4b75446d3b74e2dd469b70906b1c5d3d61b4dd1863eeeee2d68d
data/Gemfile CHANGED
@@ -23,42 +23,27 @@ group :omnibus do
23
23
  end
24
24
 
25
25
  group :test do
26
- gem "chefstyle", "~> 2.0.3"
26
+ gem "chefstyle", "~> 2.2.2"
27
27
  gem "concurrent-ruby", "~> 1.0"
28
- gem "html-proofer", platforms: :ruby # do not attempt to run proofer on windows
29
- gem "json_schemer", ">= 0.2.1", "< 0.2.19"
28
+ gem "json_schemer", ">= 0.2.1", "< 2.0.1"
30
29
  gem "m"
31
30
  gem "minitest-sprint", "~> 1.0"
32
- gem "minitest", "~> 5.5"
33
- gem "mocha", "~> 1.1"
31
+ gem "minitest", "5.15.0"
32
+ gem "mocha", "~> 2.1"
34
33
  gem "nokogiri", "~> 1.9"
35
34
  gem "pry-byebug"
36
35
  gem "pry", "~> 0.10"
37
36
  gem "rake", ">= 10"
38
- gem "ruby-progressbar", "~> 1.8"
39
37
  gem "simplecov", "~> 0.21"
40
38
  gem "simplecov_json_formatter"
41
39
  gem "webmock", "~> 3.0"
42
- end
43
40
 
44
- group :deploy do
45
- gem "inquirer"
46
- end
47
-
48
- # Only include Test Kitchen support if we are on Ruby 2.7 or higher
49
- # as chef-zero support requires Ruby 2.6
50
- # See https://github.com/inspec/inspec/pull/5341
51
- if Gem.ruby_version >= Gem::Version.new("2.7.0")
52
- group :kitchen do
53
- gem "berkshelf"
54
- gem "chef", ">= 16.0" # Required to allow net-ssh > 6
55
- gem "test-kitchen", ">= 2.8"
56
- gem "kitchen-inspec", ">= 2.0"
57
- gem "kitchen-dokken", ">= 2.11"
58
- gem "git"
41
+ if Gem.ruby_version >= Gem::Version.new("3.0.0")
42
+ # html-proofer has a dep on io-event, which is ruby-3 only
43
+ gem "html-proofer", "~> 3.19.4", platforms: :ruby # do not attempt to run proofer on windows. Pinned to 3.19.4 as test is breaking in updated versions.
59
44
  end
60
45
  end
61
46
 
62
- if Gem.ruby_version < Gem::Version.new("2.7.0")
63
- gem "activesupport", "6.1.4.4"
47
+ group :deploy do
48
+ gem "inquirer"
64
49
  end
data/inspec-core.gemspec CHANGED
@@ -25,10 +25,12 @@ Gem::Specification.new do |spec|
25
25
  # Implementation dependencies
26
26
  spec.add_dependency "chef-telemetry", "~> 1.0", ">= 1.0.8" # 1.0.8+ removes the http dep
27
27
  spec.add_dependency "license-acceptance", ">= 0.2.13", "< 3.0"
28
- spec.add_dependency "thor", ">= 0.20", "< 2.0"
28
+ # TODO: We should remove the thor pinning in next upcoming releases currently it's breaking our unit test in cli_args_test for aliases due to
29
+ # recent changes made in thor library REF: https://github.com/rails/thor/releases/tag/v1.3.0 & https://github.com/rails/thor/pull/800
30
+ spec.add_dependency "thor", ">= 0.20", "< 1.3.0"
29
31
  spec.add_dependency "method_source", ">= 0.8", "< 2.0"
30
32
  spec.add_dependency "rubyzip", ">= 1.2.2", "< 3.0"
31
- spec.add_dependency "rspec", ">= 3.9", "<= 3.11"
33
+ spec.add_dependency "rspec", ">= 3.9", "<= 3.13"
32
34
  spec.add_dependency "rspec-its", "~> 1.2"
33
35
  spec.add_dependency "pry", "~> 0.13"
34
36
  spec.add_dependency "hashie", ">= 3.4", "< 5.0"
data/lib/inspec/cli.rb CHANGED
@@ -189,6 +189,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI
189
189
  desc: "Fallback to using local archives if fetching fails."
190
190
  option :ignore_errors, type: :boolean, default: false,
191
191
  desc: "Ignore profile warnings."
192
+ option :check, type: :boolean, default: false,
193
+ desc: "Run profile check before archiving."
194
+ option :export, type: :boolean, default: false,
195
+ desc: "Export the profile to inspec.json and include in archive"
192
196
  def archive(path)
193
197
  o = config
194
198
  diagnose(o)
@@ -203,7 +207,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI
203
207
  vendor_deps(path, vendor_options)
204
208
 
205
209
  profile = Inspec::Profile.for_target(path, o)
206
- result = profile.check
210
+ result = profile.check if o[:check]
207
211
 
208
212
  if result && !o[:ignore_errors] == false
209
213
  o[:logger].info "Profile check failed. Please fix the profile before generating an archive."
@@ -25,7 +25,9 @@ module Inspec
25
25
  def self.from_array(dependencies, cwd, cache, backend)
26
26
  dep_list = {}
27
27
  dependencies.each do |d|
28
- dep_list[d.name] = d
28
+ # if depedent profile does not have a source version then only name is used in dependency hash
29
+ key_name = (d.source_version.blank? ? "#{d.name}" : "#{d.name}-#{d.source_version}") rescue "#{d.name}"
30
+ dep_list[key_name] = d
29
31
  end
30
32
  new(cwd, cache, dep_list, backend)
31
33
  end
@@ -39,7 +41,9 @@ module Inspec
39
41
  def self.flatten_dep_tree(dep_tree)
40
42
  dep_list = {}
41
43
  dep_tree.each do |d|
42
- dep_list[d.name] = d
44
+ # if depedent profile does not have a source version then only name is used in dependency hash
45
+ key_name = (d.source_version.blank? ? "#{d.name}" : "#{d.name}-#{d.source_version}") rescue "#{d.name}"
46
+ dep_list[key_name] = d
43
47
  dep_list.merge!(flatten_dep_tree(d.dependencies))
44
48
  end
45
49
  dep_list
data/lib/inspec/dsl.rb CHANGED
@@ -5,13 +5,13 @@ require "inspec/plugin/v2"
5
5
  module Inspec::DSL
6
6
  attr_accessor :backend
7
7
 
8
- def require_controls(id, &block)
9
- opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf, dependencies: @dependencies }
8
+ def require_controls(id, version = nil, &block)
9
+ opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf, dependencies: @dependencies, profile_version: version }
10
10
  ::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
11
11
  end
12
12
 
13
- def include_controls(id, &block)
14
- opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf, dependencies: @dependencies }
13
+ def include_controls(id, version = nil, &block)
14
+ opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf, dependencies: @dependencies, profile_version: version }
15
15
  ::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
16
16
  end
17
17
 
@@ -76,7 +76,23 @@ module Inspec::DSL
76
76
  def self.load_spec_files_for_profile(bind_context, opts, &block)
77
77
  dependencies = opts[:dependencies]
78
78
  profile_id = opts[:profile_id]
79
- dep_entry = dependencies.list[profile_id]
79
+ profile_version = opts[:profile_version]
80
+
81
+ new_profile_id = nil
82
+ if profile_version
83
+ new_profile_id = "#{profile_id}-#{profile_version}"
84
+ else
85
+ dependencies.list.each do |key, value|
86
+ # 1. Fetching VERSION from a profile dependency name which is in a format NAME-VERSION.
87
+ # 2. Matching original profile dependency name with profile name used with include or require control DSL.
88
+ source_version = value.source_version
89
+ unless source_version.blank?
90
+ profile_id_key = key.split("-#{source_version}")[0]
91
+ new_profile_id = key if profile_id_key == profile_id
92
+ end
93
+ end
94
+ end
95
+ dep_entry = new_profile_id ? dependencies.list[new_profile_id] : dependencies.list[profile_id]
80
96
 
81
97
  if dep_entry.nil?
82
98
  raise <<~EOF
@@ -35,7 +35,7 @@ module Inspec
35
35
  private
36
36
 
37
37
  def print_completion_for_shell
38
- erb = ERB.new(File.read(completion_template_path), nil, "-")
38
+ erb = ERB.new(File.read(completion_template_path), trim_mode: "-")
39
39
  puts erb.result(TemplateContext.new(@command_class).get_bindings)
40
40
  end
41
41
 
@@ -41,6 +41,7 @@ module Inspec::Fetcher
41
41
  @ref = opts[:ref]
42
42
  @remote_url = expand_local_path(remote_url)
43
43
  @repo_directory = nil
44
+ @resolved_ref = nil
44
45
  @relative_path = opts[:relative_path] if opts[:relative_path] && !opts[:relative_path].empty?
45
46
  end
46
47
 
@@ -70,7 +71,7 @@ module Inspec::Fetcher
70
71
  if @relative_path
71
72
  perform_relative_path_fetch(destination_path, working_dir)
72
73
  else
73
- Inspec::Log.debug("Checkout of #{resolved_ref} successful. " \
74
+ Inspec::Log.debug("Checkout of #{resolved_ref.nil? ? @remote_url : resolved_ref} successful. " \
74
75
  "Moving checkout to #{destination_path}")
75
76
  FileUtils.cp_r(working_dir + "/.", destination_path)
76
77
  end
@@ -80,14 +81,14 @@ module Inspec::Fetcher
80
81
  end
81
82
 
82
83
  def perform_relative_path_fetch(destination_path, working_dir)
83
- Inspec::Log.debug("Checkout of #{resolved_ref} successful. " \
84
+ Inspec::Log.debug("Checkout of #{resolved_ref.nil? ? @remote_url : resolved_ref} successful. " \
84
85
  "Moving #{@relative_path} to #{destination_path}")
85
86
  unless File.exist?("#{working_dir}/#{@relative_path}")
86
87
  # Cleanup the destination path - otherwise we'll have an empty dir
87
88
  # in the cache, which is enough to confuse the cache reader
88
89
  # This is a courtesy, assuming we're writing to the cache; if we're
89
90
  # vendoring to something more complex, don't bother.
90
- FileUtils.rmdir(destination_path) if Dir.empty?(destination_path)
91
+ FileUtils.rm_r(destination_path) if Dir.exist?(destination_path)
91
92
 
92
93
  raise Inspec::FetcherFailure, "Cannot find relative path '#{@relative_path}' " \
93
94
  "within profile in git repo specified by '#{@remote_url}'"
@@ -96,9 +97,16 @@ module Inspec::Fetcher
96
97
  end
97
98
 
98
99
  def cache_key
99
- return resolved_ref unless @relative_path
100
-
101
- OpenSSL::Digest.hexdigest("SHA256", resolved_ref + @relative_path)
100
+ cache_key = if @relative_path && !resolved_ref.nil?
101
+ OpenSSL::Digest.hexdigest("SHA256", resolved_ref + @relative_path)
102
+ elsif @relative_path && resolved_ref.nil?
103
+ OpenSSL::Digest.hexdigest("SHA256", @remote_url + @relative_path)
104
+ elsif resolved_ref.nil?
105
+ OpenSSL::Digest.hexdigest("SHA256", @remote_url)
106
+ else
107
+ resolved_ref
108
+ end
109
+ cache_key
102
110
  end
103
111
 
104
112
  def archive_path
@@ -106,7 +114,11 @@ module Inspec::Fetcher
106
114
  end
107
115
 
108
116
  def resolved_source
109
- source = { git: @remote_url, ref: resolved_ref }
117
+ if resolved_ref.nil?
118
+ source = { git: @remote_url }
119
+ else
120
+ source = { git: @remote_url, ref: resolved_ref }
121
+ end
110
122
  source[:relative_path] = @relative_path if @relative_path
111
123
  source
112
124
  end
@@ -125,33 +137,27 @@ module Inspec::Fetcher
125
137
  elsif @tag
126
138
  resolve_ref(@tag)
127
139
  else
128
- resolve_ref(default_ref)
140
+ resolve_ref
129
141
  end
130
142
  end
131
143
 
132
- def default_ref
133
- command_string = "git remote show #{@remote_url}"
144
+ def resolve_ref(ref_name = nil)
145
+ command_string = if ref_name.nil?
146
+ # Running git ls-remote command helps to raise error if git URL is invalid and avoids cache_key creation
147
+ "git ls-remote \"#{@remote_url}\""
148
+ else
149
+ "git ls-remote \"#{@remote_url}\" \"#{ref_name}*\""
150
+ end
134
151
  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}")
152
+ raise(Inspec::FetcherFailure, "Profile git dependency failed for #{@remote_url} - error running '#{command_string}': #{cmd.stderr}") unless cmd.exitstatus == 0
153
+
154
+ if ref_name.nil?
155
+ ref = nil
137
156
  else
138
- ref = cmd.stdout.lines.detect { |l| l.include? "HEAD branch:" }&.split(":")&.last&.strip
157
+ ref = parse_ls_remote(cmd.stdout, ref_name)
139
158
  unless ref
140
- raise(Inspec::FetcherFailure, "Profile git dependency failed with default reference - #{@remote_url} - error running '#{command_string}': NULL reference")
159
+ raise Inspec::FetcherFailure, "Profile git dependency failed - unable to resolve #{ref_name} to a specific git commit for #{@remote_url}"
141
160
  end
142
-
143
- ref
144
- end
145
- end
146
-
147
- def resolve_ref(ref_name)
148
- command_string = "git ls-remote \"#{@remote_url}\" \"#{ref_name}*\""
149
- cmd = shellout(command_string)
150
- raise(Inspec::FetcherFailure, "Profile git dependency failed for #{@remote_url} - error running '#{command_string}': #{cmd.stderr}") unless cmd.exitstatus == 0
151
-
152
- ref = parse_ls_remote(cmd.stdout, ref_name)
153
- unless ref
154
- raise Inspec::FetcherFailure, "Profile git dependency failed - unable to resolve #{ref_name} to a specific git commit for #{@remote_url}"
155
161
  end
156
162
 
157
163
  ref
@@ -200,7 +206,14 @@ module Inspec::Fetcher
200
206
 
201
207
  def checkout(dir = @repo_directory)
202
208
  clone(dir)
203
- git_cmd("checkout #{resolved_ref}", dir)
209
+ # In case of branch, tag or git reference is not provided by User the resolved_ref will always be nil
210
+ # and will always checkout the default HEAD branch, else it will checkout specific branch, tag or git reference.
211
+ if resolved_ref.nil?
212
+ git_cmd("checkout", dir)
213
+ else
214
+ git_cmd("checkout #{resolved_ref}", dir)
215
+ end
216
+
204
217
  @repo_directory
205
218
  end
206
219
 
@@ -208,6 +221,8 @@ module Inspec::Fetcher
208
221
  cmd = shellout("git #{cmd}", cwd: dir)
209
222
  cmd.error!
210
223
  cmd.status
224
+ rescue Mixlib::ShellOut::ShellCommandFailed => e
225
+ raise Inspec::FetcherFailure, "Error while running git command. #{e.message} "
211
226
  rescue Errno::ENOENT
212
227
  raise Inspec::FetcherFailure, "Profile git dependency failed for #{@remote_url} - to use git sources, you must have git installed."
213
228
  end
@@ -262,7 +262,7 @@ module Inspec::Fetcher
262
262
 
263
263
  open(target, opts)
264
264
 
265
- rescue SocketError, Errno::ECONNREFUSED, OpenURI::HTTPError => e
265
+ rescue SocketError, Net::OpenTimeout, Errno::ECONNREFUSED, OpenURI::HTTPError => e
266
266
  raise Inspec::FetcherFailure, "Profile URL dependency #{target} could not be fetched: #{e.message}"
267
267
  end
268
268
 
@@ -1,5 +1,6 @@
1
1
  require "rspec/core"
2
2
  require "rspec/core/formatters/base_formatter"
3
+ require "set" unless defined?(Set)
3
4
 
4
5
  module Inspec::Formatters
5
6
  class Base < RSpec::Core::Formatters::BaseFormatter
@@ -617,7 +617,6 @@ module Inspec
617
617
  end
618
618
 
619
619
  # generates a archive of a folder profile
620
- # assumes that the profile was checked before
621
620
  def archive(opts)
622
621
  # check if file exists otherwise overwrite the archive
623
622
  dst = archive_name(opts)
@@ -634,31 +633,34 @@ module Inspec
634
633
  # TODO ignore all .files, but add the files to debug output
635
634
 
636
635
  # Generate temporary inspec.json for archive
637
- Inspec::Utils::JsonProfileSummary.produce_json(
638
- info: info,
639
- write_path: "#{root_path}inspec.json",
640
- suppress_output: true
641
- )
636
+ if opts[:export]
637
+ Inspec::Utils::JsonProfileSummary.produce_json(
638
+ info: info, # TODO: conditionalize and call info_from_parse
639
+ write_path: "#{root_path}inspec.json",
640
+ suppress_output: true
641
+ )
642
+ end
642
643
 
643
644
  # display all files that will be part of the archive
644
645
  @logger.debug "Add the following files to archive:"
645
646
  files.each { |f| @logger.debug " " + f }
646
- @logger.debug " inspec.json"
647
+ @logger.debug " inspec.json" if opts[:export]
647
648
 
649
+ archive_files = opts[:export] ? files.push("inspec.json") : files
648
650
  if opts[:zip]
649
651
  # generate zip archive
650
652
  require "inspec/archive/zip"
651
653
  zag = Inspec::Archive::ZipArchiveGenerator.new
652
- zag.archive(root_path, files.push("inspec.json"), dst)
654
+ zag.archive(root_path, archive_files, dst)
653
655
  else
654
656
  # generate tar archive
655
657
  require "inspec/archive/tar"
656
658
  tag = Inspec::Archive::TarArchiveGenerator.new
657
- tag.archive(root_path, files.push("inspec.json"), dst)
659
+ tag.archive(root_path, archive_files, dst)
658
660
  end
659
661
 
660
662
  # Cleanup
661
- FileUtils.rm_f("#{root_path}inspec.json")
663
+ FileUtils.rm_f("#{root_path}inspec.json") if opts[:export]
662
664
 
663
665
  @logger.info "Finished archive generation."
664
666
  true
@@ -756,10 +758,12 @@ module Inspec
756
758
  return Pathname.new(name)
757
759
  end
758
760
 
759
- name = params[:name] ||
761
+ # Using metadata to fetch basic info of name and version
762
+ metadata = @source_reader.metadata.params
763
+ name = metadata[:name] ||
760
764
  raise("Cannot create an archive without a profile name! Please "\
761
765
  "specify the name in metadata or use --output to create the archive.")
762
- version = params[:version] ||
766
+ version = metadata[:version] ||
763
767
  raise("Cannot create an archive without a profile version! Please "\
764
768
  "specify the version in metadata or use --output to create the archive.")
765
769
  ext = opts[:zip] ? "zip" : "tar.gz"
@@ -787,7 +791,12 @@ module Inspec
787
791
  f = load_rule_filepath(prefix, rule)
788
792
  load_rule(rule, f, controls, groups)
789
793
  end
790
- params[:inputs] = Inspec::InputRegistry.list_inputs_for_profile(@profile_id)
794
+ if @profile_id.nil?
795
+ # identifying inputs using profile name
796
+ params[:inputs] = Inspec::InputRegistry.list_inputs_for_profile(params[:name])
797
+ else
798
+ params[:inputs] = Inspec::InputRegistry.list_inputs_for_profile(@profile_id)
799
+ end
791
800
  params
792
801
  end
793
802
 
@@ -1,10 +1,11 @@
1
1
  module Inspec::Resources
2
2
  class Lines
3
- attr_reader :output
3
+ attr_reader :output, :exit_status
4
4
 
5
- def initialize(raw, desc)
5
+ def initialize(raw, desc, exit_status)
6
6
  @output = raw
7
7
  @desc = desc
8
+ @exit_status = exit_status
8
9
  end
9
10
 
10
11
  def to_s
@@ -40,7 +41,7 @@ module Inspec::Resources
40
41
  if cmd.exit_status != 0 || out =~ /Unable to connect to any servers/ || out.downcase =~ /^error:.*/
41
42
  raise Inspec::Exceptions::ResourceFailed, "Cassandra query with errors: #{out}"
42
43
  else
43
- Lines.new(cmd.stdout.strip, "Cassandra query: #{q}")
44
+ Lines.new(cmd.stdout.strip, "Cassandra query: #{q}", cmd.exit_status)
44
45
  end
45
46
  end
46
47
 
@@ -65,7 +65,7 @@ module Inspec::Resources
65
65
  def user_permissions
66
66
  return {} unless exist?
67
67
 
68
- return skip_reource"`user_permissions` is not supported on your OS yet." unless inspec.os.windows?
68
+ return skip_resource "`user_permissions` is not supported on your OS yet." unless inspec.os.windows?
69
69
 
70
70
  @perms_provider.user_permissions(file)
71
71
  end
@@ -1,10 +1,11 @@
1
1
  module Inspec::Resources
2
2
  class Lines
3
- attr_reader :output
3
+ attr_reader :output, :exit_status
4
4
 
5
- def initialize(raw, desc)
5
+ def initialize(raw, desc, exit_status)
6
6
  @output = raw
7
7
  @desc = desc
8
+ @exit_status = exit_status
8
9
  end
9
10
 
10
11
  def to_s
@@ -58,7 +59,7 @@ module Inspec::Resources
58
59
  if cmd.exit_status != 0 || out =~ /Can't connect to IBM Db2 / || out.downcase =~ /^error:.*/
59
60
  raise Inspec::Exceptions::ResourceFailed, "IBM Db2 connection error: #{out}"
60
61
  else
61
- Lines.new(cmd.stdout.strip, "IBM Db2 Query: #{q}")
62
+ Lines.new(cmd.stdout.strip, "IBM Db2 Query: #{q}", cmd.exit_status)
62
63
  end
63
64
  end
64
65
 
@@ -4,9 +4,10 @@ module Inspec::Resources
4
4
  class Lines
5
5
  attr_reader :params
6
6
 
7
- def initialize(raw, desc)
7
+ def initialize(raw, desc, exit_status = nil)
8
8
  @params = raw
9
9
  @desc = desc
10
+ @exit_status = exit_status
10
11
  end
11
12
 
12
13
  def to_s
@@ -79,6 +80,11 @@ module Inspec::Resources
79
80
  options[:ssl_cert] = @ssl_cert unless @ssl_cert.nil?
80
81
  options[:ssl_ca_cert] = @ssl_ca_cert unless @ssl_ca_cert.nil?
81
82
 
83
+ # Setting the logger level to INFO as mongo gem version 2.13.2 is using DEBUG as the log level Ref: https://github.com/mongodb/mongo-ruby-driver/blob/v2.13.2/lib/mongo/logger.rb#L79
84
+ # Latest version of the mongo gem don't have this issue as it set to INFO level Ref: https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/logger.rb#L82
85
+ # We pinned the version to 2.13.2 as the latest version of the mongo gem has broken symlink https://jira.mongodb.org/browse/RUBY-2546 which causes omnibus build failure.
86
+ # Once we get the latest version working we can remove logger level set here.
87
+ Mongo::Logger.logger.level = Logger::INFO
82
88
  @client = Mongo::Client.new([ "#{host}:#{port}" ], options)
83
89
 
84
90
  rescue => e
@@ -91,22 +91,31 @@ module Inspec::Resources
91
91
  verified_query = verify_query(escaped_query)
92
92
  end
93
93
 
94
- sql_prefix, sql_postfix = "", ""
94
+ sql_prefix, sql_postfix, oracle_echo_str = "", "", ""
95
95
  if inspec.os.windows?
96
96
  sql_prefix = %{@'\n#{format_options}\n#{verified_query}\nEXIT\n'@ | }
97
97
  else
98
98
  sql_postfix = %{ <<'EOC'\n#{format_options}\n#{verified_query}\nEXIT\nEOC}
99
+ # oracle_query_string is echoed to be able to extract the query output clearly
100
+ oracle_echo_str = %{echo 'oracle_query_string';}
101
+ end
102
+
103
+ # Resetting sql_postfix if system is using AIX OS and C shell installation for oracle
104
+ if inspec.os.aix?
105
+ command_to_fetch_shell = @su_user ? %{su - #{@su_user} -c "env | grep SHELL"} : %{env | grep SHELL}
106
+ shell_is_csh = inspec.command(command_to_fetch_shell).stdout&.include? "/csh"
107
+ sql_postfix = %{ <<'EOC'\n#{format_options}\n#{verified_query}\nEXIT\n'EOC'} if shell_is_csh
99
108
  end
100
109
 
101
110
  if @db_role.nil?
102
- %{#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}}
111
+ %{#{oracle_echo_str}#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service}#{sql_postfix}}
103
112
  elsif @su_user.nil?
104
- %{#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}}
113
+ %{#{oracle_echo_str}#{sql_prefix}#{bin} #{user}/#{password}@#{host}:#{port}/#{@service} as #{@db_role}#{sql_postfix}}
105
114
  else
106
115
  # oracle_query_string is echoed to be able to extract the query output clearly
107
116
  # su - su_user in certain versions of oracle returns a message
108
117
  # Example of msg with query output: The Oracle base remains unchanged with value /oracle\n\nVALUE\n3\n
109
- %{su - #{@su_user} -c "echo 'oracle_query_string'; env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"}
118
+ %{su - #{@su_user} -c "#{oracle_echo_str} env ORACLE_SID=#{@service} #{@bin} / as #{@db_role}#{sql_postfix}"}
110
119
  end
111
120
  end
112
121
 
@@ -4,9 +4,9 @@ require "shellwords" unless defined?(Shellwords)
4
4
 
5
5
  module Inspec::Resources
6
6
  class Lines
7
- attr_reader :output
7
+ attr_reader :output, :exit_status
8
8
 
9
- def initialize(raw, desc)
9
+ def initialize(raw, desc, exit_status)
10
10
  @output = raw
11
11
  @desc = desc
12
12
  end
@@ -58,9 +58,9 @@ module Inspec::Resources
58
58
  if cmd.exit_status != 0 && ( out =~ /could not connect to/ || out =~ /password authentication failed/ ) && out.downcase =~ /error:/
59
59
  raise Inspec::Exceptions::ResourceFailed, "PostgreSQL connection error: #{out}"
60
60
  elsif cmd.exit_status != 0 && out.downcase =~ /error:/
61
- Lines.new(out, "PostgreSQL query with error: #{query}")
61
+ Lines.new(out, "PostgreSQL query with error: #{query}", cmd.exit_status)
62
62
  else
63
- Lines.new(cmd.stdout.strip, "PostgreSQL query: #{query}")
63
+ Lines.new(cmd.stdout.strip, "PostgreSQL query: #{query}", cmd.exit_status)
64
64
  end
65
65
  end
66
66
 
@@ -43,7 +43,7 @@ module Inspec::Resources
43
43
 
44
44
  all_cmds = ps_axo
45
45
  @list = all_cmds.find_all do |hm|
46
- hm[:command] =~ grep
46
+ hm[:command] =~ grep || hm[:process_name] =~ grep
47
47
  end
48
48
  end
49
49
 
@@ -73,6 +73,7 @@ module Inspec::Resources
73
73
  .register_column(:time, field: "time")
74
74
  .register_column(:users, field: "user")
75
75
  .register_column(:commands, field: "command")
76
+ .register_column(:process_name, field: "process_name")
76
77
  .install_filter_methods_on_resource(self, :filtered_processes)
77
78
 
78
79
  private
@@ -87,9 +88,9 @@ module Inspec::Resources
87
88
  if os.linux?
88
89
  command, regex, field_map = ps_configuration_for_linux
89
90
  elsif os.windows?
90
- command = '$Proc = Get-Process -IncludeUserName | Where-Object {$_.Path -ne $null } | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")'
91
+ command = '$Proc = Get-Process -IncludeUserName | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path,ProcessName | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")'
91
92
  # Wanted to use /(?:^|,)([^,]*)/; works on rubular.com not sure why here?
92
- regex = /^(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+)$/
93
+ regex = /^(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)$/
93
94
  field_map = {
94
95
  pid: 2,
95
96
  cpu: 3,
@@ -102,6 +103,7 @@ module Inspec::Resources
102
103
  time: 10,
103
104
  user: 11,
104
105
  command: 12,
106
+ process_name: 13,
105
107
  }
106
108
  else
107
109
  command = "ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command"
@@ -193,7 +195,7 @@ module Inspec::Resources
193
195
 
194
196
  # build a hash of process data that we'll turn into a struct for FilterTable
195
197
  process_data = {}
196
- %i{label pid cpu mem vsz rss tty stat start time user command}.each do |param|
198
+ %i{label pid cpu mem vsz rss tty stat start time user command process_name}.each do |param|
197
199
  # not all operating systems support all fields, so skip the field if we don't have it
198
200
  process_data[param] = line[field_map[param]] if field_map.key?(param)
199
201
  end
@@ -182,7 +182,9 @@ module Inspec::Resources
182
182
  when "aix"
183
183
  SrcMstr.new(inspec)
184
184
  when "amazon"
185
- if os[:release] =~ /^20\d\d/
185
+ # If `initctl` exists on the system, use `Upstart`. Else use `Systemd` since all-new Amazon Linux supports `systemctl`.
186
+ # This way, it is not dependent on the version of Amazon Linux.
187
+ if inspec.command("initctl").exist? || inspec.command("/sbin/initctl").exist?
186
188
  Upstart.new(inspec, service_ctl)
187
189
  else
188
190
  Systemd.new(inspec, service_ctl)
@@ -603,7 +605,7 @@ module Inspec::Resources
603
605
  return nil if srv.nil? || srv[0].nil?
604
606
 
605
607
  # extract values from service
606
- parsed_srv = /^(?<pid>[0-9-]+)\t(?<exit>[0-9]+)\t(?<name>\S*)$/.match(srv[0])
608
+ parsed_srv = /^(?<pid>[0-9-]+)\t(?<exit>[\-0-9]+)\t(?<name>\S*)$/.match(srv[0])
607
609
  enabled = !parsed_srv["name"].nil? # it's in the list
608
610
 
609
611
  # check if the service is running
data/lib/inspec/rule.rb CHANGED
@@ -358,7 +358,7 @@ module Inspec
358
358
  # YAML will automagically give us a Date or a Time.
359
359
  # If transcoding YAML between languages (e.g. Go) the date might have also ended up as a String.
360
360
  # A string that does not represent a valid time results in the date 0000-01-01.
361
- if [Date, Time].include?(expiry.class) || (expiry.is_a?(String) && Time.new(expiry).year != 0)
361
+ if [Date, Time].include?(expiry.class) || (expiry.is_a?(String) && Time.parse(expiry).year != 0)
362
362
  expiry = expiry.to_time if expiry.is_a? Date
363
363
  expiry = Time.parse(expiry) if expiry.is_a? String
364
364
  if expiry < Time.now # If the waiver expired, return - no skip applied
@@ -16,7 +16,13 @@ module Secrets
16
16
 
17
17
  # array of yaml file paths
18
18
  def initialize(target)
19
- @inputs = ::YAML.load_file(target)
19
+ # Ruby 3.1 treats YAML load as a dangerous operation by default, requiring us to declare date and time classes as permitted
20
+ # It's not a valid option in 3.0.x
21
+ if Gem.ruby_version >= Gem::Version.new("3.1.0")
22
+ @inputs = ::YAML.load_file(target, permitted_classes: [Date, Time])
23
+ else
24
+ @inputs = ::YAML.load_file(target)
25
+ end
20
26
 
21
27
  if @inputs == false || !@inputs.is_a?(Hash)
22
28
  Inspec::Log.warn("#{self.class} unable to parse #{target}: invalid YAML or contents is not a Hash")
@@ -1,3 +1,3 @@
1
1
  module Inspec
2
- VERSION = "4.56.20".freeze
2
+ VERSION = "4.56.58".freeze
3
3
  end
@@ -225,7 +225,11 @@ RSpec::Matchers.define :cmp do |first_expected| # rubocop:disable Metrics/BlockL
225
225
  end
226
226
 
227
227
  def boolean?(value)
228
- %w{true false}.include?(value.downcase)
228
+ if value.respond_to?("downcase")
229
+ %w{true false}.include?(value.downcase)
230
+ else
231
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
232
+ end
229
233
  end
230
234
 
231
235
  def version?(value)
@@ -252,6 +256,8 @@ RSpec::Matchers.define :cmp do |first_expected| # rubocop:disable Metrics/BlockL
252
256
  return actual.send(op, expected.to_i)
253
257
  elsif expected.is_a?(String) && boolean?(expected) && [true, false].include?(actual)
254
258
  return actual.send(op, to_boolean(expected))
259
+ elsif boolean?(expected) && %w{true false}.include?(actual)
260
+ return actual.send(op, expected.to_s)
255
261
  elsif expected.is_a?(Integer) && actual.is_a?(String) && integer?(actual)
256
262
  return actual.to_i.send(op, expected)
257
263
  elsif expected.is_a?(Float) && float?(actual)
@@ -7,21 +7,21 @@
7
7
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
8
  <style type="text/css">
9
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) %>
10
+ <%= ERB.new(File.read(css_path), eoutvar: "_css").result(binding) %>
11
11
  </style>
12
12
  <script type="text/javascript">
13
13
  // <![CDATA[
14
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) %>
15
+ <%= ERB.new(File.read(js_path), eoutvar: "_js").result(binding) %>
16
16
  // ]]>
17
17
  </script>
18
18
  </head>
19
19
  <body onload="pageLoaded()">
20
- <%= ERB.new(File.read(template_path + "/selector.html.erb"), nil, nil, "_select").result(binding) %>
20
+ <%= ERB.new(File.read(template_path + "/selector.html.erb"), eoutvar: "_select").result(binding) %>
21
21
  <div class="inspec-report">
22
22
  <h1><%= Inspec::Dist::PRODUCT_NAME %> Report</h1>
23
23
  <% run_data.profiles.each do |profile| %>
24
- <%= ERB.new(File.read(template_path + "/profile.html.erb"), nil, nil, "_prof").result(binding) %>
24
+ <%= ERB.new(File.read(template_path + "/profile.html.erb"), eoutvar: "_prof").result(binding) %>
25
25
  <% end %>
26
26
 
27
27
  <div class="inspec-summary">
@@ -71,7 +71,7 @@
71
71
  </table>
72
72
 
73
73
  <% control.results.each do |result| %>
74
- <%= ERB.new(File.read(template_path + "/result.html.erb"), nil, nil, "_rslt").result(binding) %>
74
+ <%= ERB.new(File.read(template_path + "/result.html.erb"), eoutvar: "_rslt").result(binding) %>
75
75
  <% end %>
76
76
 
77
77
  </div>
@@ -17,7 +17,7 @@
17
17
 
18
18
  <% if profile.status == "loaded" %>
19
19
  <% profile.controls.each do |control| %>
20
- <%= ERB.new(File.read(template_path + "/control.html.erb"), nil, nil, "_ctl").result(binding) %>
20
+ <%= ERB.new(File.read(template_path + "/control.html.erb"), eoutvar: "_ctl").result(binding) %>
21
21
  <% end %>
22
22
  <% end %>
23
23
  </div>
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.56.20
4
+ version: 4.56.58
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: 2022-04-19 00:00:00.000000000 Z
11
+ date: 2023-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-telemetry
@@ -59,7 +59,7 @@ dependencies:
59
59
  version: '0.20'
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
- version: '2.0'
62
+ version: 1.3.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -69,7 +69,7 @@ dependencies:
69
69
  version: '0.20'
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '2.0'
72
+ version: 1.3.0
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: method_source
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -119,7 +119,7 @@ dependencies:
119
119
  version: '3.9'
120
120
  - - "<="
121
121
  - !ruby/object:Gem::Version
122
- version: '3.11'
122
+ version: '3.13'
123
123
  type: :runtime
124
124
  prerelease: false
125
125
  version_requirements: !ruby/object:Gem::Requirement
@@ -129,7 +129,7 @@ dependencies:
129
129
  version: '3.9'
130
130
  - - "<="
131
131
  - !ruby/object:Gem::Version
132
- version: '3.11'
132
+ version: '3.13'
133
133
  - !ruby/object:Gem::Dependency
134
134
  name: rspec-its
135
135
  requirement: !ruby/object:Gem::Requirement