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 +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
|