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 +4 -4
- data/Gemfile +9 -24
- data/inspec-core.gemspec +4 -2
- data/lib/inspec/cli.rb +5 -1
- data/lib/inspec/dependencies/dependency_set.rb +6 -2
- data/lib/inspec/dsl.rb +21 -5
- data/lib/inspec/env_printer.rb +1 -1
- data/lib/inspec/fetcher/git.rb +43 -28
- data/lib/inspec/fetcher/url.rb +1 -1
- data/lib/inspec/formatters/base.rb +1 -0
- data/lib/inspec/profile.rb +22 -13
- data/lib/inspec/resources/cassandradb_session.rb +4 -3
- data/lib/inspec/resources/file.rb +1 -1
- data/lib/inspec/resources/ibmdb2_session.rb +4 -3
- data/lib/inspec/resources/mongodb_session.rb +7 -1
- data/lib/inspec/resources/oracledb_session.rb +13 -4
- data/lib/inspec/resources/postgres_session.rb +4 -4
- data/lib/inspec/resources/processes.rb +6 -4
- data/lib/inspec/resources/service.rb +4 -2
- data/lib/inspec/rule.rb +1 -1
- data/lib/inspec/secrets/yaml.rb +7 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +7 -1
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +4 -4
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9817a3eab9cc59b2a73fff43f35ecb954d48b9a16b2e1e1a7eb44bbd1389420
|
4
|
+
data.tar.gz: 410c6d2786f8cccc6690593e5db3bb03be0bc77444ea8fab9504213b9594102c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
26
|
+
gem "chefstyle", "~> 2.2.2"
|
27
27
|
gem "concurrent-ruby", "~> 1.0"
|
28
|
-
gem "
|
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", "
|
33
|
-
gem "mocha", "~>
|
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
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
63
|
-
gem "
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/inspec/env_printer.rb
CHANGED
@@ -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),
|
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
|
|
data/lib/inspec/fetcher/git.rb
CHANGED
@@ -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.
|
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
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
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
|
140
|
+
resolve_ref
|
129
141
|
end
|
130
142
|
end
|
131
143
|
|
132
|
-
def
|
133
|
-
command_string =
|
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
|
-
|
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
|
157
|
+
ref = parse_ls_remote(cmd.stdout, ref_name)
|
139
158
|
unless ref
|
140
|
-
raise
|
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
|
-
|
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
|
data/lib/inspec/fetcher/url.rb
CHANGED
@@ -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
|
|
data/lib/inspec/profile.rb
CHANGED
@@ -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
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
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,
|
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,
|
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
|
-
|
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 =
|
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
|
-
|
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
|
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 "
|
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 |
|
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
|
-
|
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.
|
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
|
data/lib/inspec/secrets/yaml.rb
CHANGED
@@ -16,7 +16,13 @@ module Secrets
|
|
16
16
|
|
17
17
|
# array of yaml file paths
|
18
18
|
def initialize(target)
|
19
|
-
|
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")
|
data/lib/inspec/version.rb
CHANGED
data/lib/matchers/matchers.rb
CHANGED
@@ -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
|
-
|
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),
|
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),
|
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"),
|
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"),
|
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"),
|
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"),
|
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.
|
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:
|
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:
|
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:
|
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.
|
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.
|
132
|
+
version: '3.13'
|
133
133
|
- !ruby/object:Gem::Dependency
|
134
134
|
name: rspec-its
|
135
135
|
requirement: !ruby/object:Gem::Requirement
|