inspec-core 4.56.20 → 4.56.58

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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