inspec-core 6.8.24 → 7.0.95
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 +8 -8
- data/etc/deprecations.json +42 -4
- data/inspec-core.gemspec +14 -7
- data/lib/inspec/archive/tar.rb +1 -0
- data/lib/inspec/backend.rb +2 -0
- data/lib/inspec/base_cli.rb +15 -2
- data/lib/inspec/cached_fetcher.rb +17 -1
- data/lib/inspec/cli.rb +2 -0
- data/lib/inspec/dependencies/cache.rb +47 -7
- data/lib/inspec/dsl.rb +44 -10
- data/lib/inspec/exceptions.rb +1 -0
- data/lib/inspec/fetcher/gem.rb +117 -0
- data/lib/inspec/fetcher/git.rb +21 -1
- data/lib/inspec/fetcher/local.rb +1 -1
- data/lib/inspec/fetcher.rb +1 -0
- data/lib/inspec/file_provider.rb +47 -1
- data/lib/inspec/metadata.rb +2 -0
- data/lib/inspec/plugin/v2/concerns/gem_spec_helper.rb +30 -0
- data/lib/inspec/plugin/v2/gem_source_manager.rb +50 -0
- data/lib/inspec/plugin/v2/installer.rb +65 -18
- data/lib/inspec/plugin/v2/loader.rb +37 -6
- data/lib/inspec/plugin/v2/plugin_types/resource_pack.rb +8 -0
- data/lib/inspec/plugin/v2.rb +1 -0
- data/lib/inspec/profile.rb +22 -3
- data/lib/inspec/profile_context.rb +10 -0
- data/lib/inspec/resources/audit_policy.rb +8 -2
- data/lib/inspec/resources/groups.rb +52 -0
- data/lib/inspec/resources.rb +0 -14
- data/lib/inspec/rule.rb +2 -0
- data/lib/inspec/runner.rb +7 -1
- data/lib/inspec/source_reader.rb +2 -0
- data/lib/inspec/ui.rb +1 -0
- data/lib/inspec/utils/deprecated_core_resources_list.rb +2 -2
- data/lib/inspec/utils/deprecation/config_file.rb +39 -3
- data/lib/inspec/utils/deprecation/deprecator.rb +10 -3
- data/lib/inspec/utils/simpleconfig.rb +2 -0
- data/lib/inspec/utils/telemetry/run_context_probe.rb +5 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +35 -18
- data/lib/inspec.rb +2 -0
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +1 -1
- data/lib/plugins/shared/core_plugin_test_helper.rb +1 -1
- data/lib/source_readers/gem.rb +67 -0
- metadata +82 -43
- data/lib/inspec/resources/docker.rb +0 -274
- data/lib/inspec/resources/docker_container.rb +0 -116
- data/lib/inspec/resources/docker_image.rb +0 -141
- data/lib/inspec/resources/docker_object.rb +0 -52
- data/lib/inspec/resources/docker_plugin.rb +0 -68
- data/lib/inspec/resources/docker_service.rb +0 -95
- data/lib/inspec/resources/elasticsearch.rb +0 -165
- data/lib/inspec/resources/ibmdb2_conf.rb +0 -65
- data/lib/inspec/resources/ibmdb2_session.rb +0 -78
- data/lib/inspec/resources/mongodb.rb +0 -69
- data/lib/inspec/resources/mongodb_conf.rb +0 -44
- data/lib/inspec/resources/mongodb_session.rb +0 -98
- data/lib/inspec/resources/opa.rb +0 -26
- data/lib/inspec/resources/opa_api.rb +0 -49
- data/lib/inspec/resources/opa_cli.rb +0 -57
- data/lib/inspec/resources/podman.rb +0 -353
- data/lib/inspec/resources/podman_container.rb +0 -84
- data/lib/inspec/resources/podman_image.rb +0 -108
- data/lib/inspec/resources/podman_network.rb +0 -81
- data/lib/inspec/resources/podman_pod.rb +0 -101
- data/lib/inspec/resources/podman_volume.rb +0 -87
- data/lib/inspec/resources/rabbitmq_conf.rb +0 -2
- data/lib/inspec/resources/rabbitmq_config.rb +0 -56
- data/lib/inspec/resources/sybase_conf.rb +0 -41
- data/lib/inspec/resources/sybase_session.rb +0 -124
- data/lib/inspec/utils/podman.rb +0 -24
data/lib/inspec/runner.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# copyright: 2015, Dominik Richter
|
|
2
|
+
# Copyright © 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates.
|
|
3
|
+
# All Rights Reserved.
|
|
2
4
|
|
|
3
5
|
require "forwardable" unless defined?(Forwardable)
|
|
4
6
|
require "uri" unless defined?(URI)
|
|
@@ -115,7 +117,8 @@ module Inspec
|
|
|
115
117
|
next unless profile.supports_platform?
|
|
116
118
|
|
|
117
119
|
write_lockfile(profile) if @create_lockfile
|
|
118
|
-
|
|
120
|
+
# TODO: InSpec 8: Replace with Profile OnLoad event handling
|
|
121
|
+
profile.locked_dependencies # Only need to do this once, this recurses down
|
|
119
122
|
profile.load_gem_dependencies
|
|
120
123
|
profile_context = profile.load_libraries
|
|
121
124
|
|
|
@@ -125,6 +128,9 @@ module Inspec
|
|
|
125
128
|
" on unsupported platform: '#{@backend.platform.name}/#{@backend.platform.release}'."
|
|
126
129
|
next
|
|
127
130
|
end
|
|
131
|
+
# TODO: InSpec 8: Replace with Profile OnLoad event handling
|
|
132
|
+
requirement.profile.load_gem_dependencies
|
|
133
|
+
requirement.profile.load_libraries
|
|
128
134
|
@test_collector.add_profile(requirement.profile)
|
|
129
135
|
end
|
|
130
136
|
|
data/lib/inspec/source_reader.rb
CHANGED
data/lib/inspec/ui.rb
CHANGED
|
@@ -10,6 +10,8 @@ module DeprecatedCoreResourcesList
|
|
|
10
10
|
mongodb
|
|
11
11
|
mongodb_conf
|
|
12
12
|
mongodb_session
|
|
13
|
+
opa_api
|
|
14
|
+
opa_cli
|
|
13
15
|
podman
|
|
14
16
|
podman_container
|
|
15
17
|
podman_image
|
|
@@ -17,8 +19,6 @@ module DeprecatedCoreResourcesList
|
|
|
17
19
|
podman_pod
|
|
18
20
|
podman_volume
|
|
19
21
|
rabbitmq_config
|
|
20
|
-
ssh_config
|
|
21
|
-
ssh_key
|
|
22
22
|
sybase_conf
|
|
23
23
|
sybase_session
|
|
24
24
|
}.freeze
|
|
@@ -7,6 +7,7 @@ module Inspec
|
|
|
7
7
|
module Deprecation
|
|
8
8
|
class ConfigFile
|
|
9
9
|
GroupEntry = Struct.new(:name, :action, :prefix, :suffix, :exit_status)
|
|
10
|
+
FallbackEntry = Struct.new(:resource_name_regex, :gem_name, :message)
|
|
10
11
|
|
|
11
12
|
# What actions may you specify to be taken when a deprecation is encountered?
|
|
12
13
|
VALID_ACTIONS = [
|
|
@@ -20,7 +21,7 @@ module Inspec
|
|
|
20
21
|
# and pass validation.
|
|
21
22
|
VALID_GROUP_FIELDS = %w{action suffix prefix exit_status comment}.freeze
|
|
22
23
|
|
|
23
|
-
attr_reader :groups, :unknown_group_action
|
|
24
|
+
attr_reader :fallback_resource_packs, :groups, :unknown_group_action
|
|
24
25
|
|
|
25
26
|
def initialize(io = nil)
|
|
26
27
|
io ||= open_default_config_io
|
|
@@ -31,6 +32,7 @@ module Inspec
|
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
@groups = {}
|
|
35
|
+
@fallback_resource_packs = []
|
|
34
36
|
@unknown_group_action = :warn
|
|
35
37
|
validate!
|
|
36
38
|
silence_deprecations_from_cli
|
|
@@ -83,14 +85,25 @@ module Inspec
|
|
|
83
85
|
@raw_data["groups"].each do |group_name, group_info|
|
|
84
86
|
validate_group_entry(group_name, group_info)
|
|
85
87
|
end
|
|
88
|
+
|
|
89
|
+
unless @raw_data.key?("fallback_resource_packs")
|
|
90
|
+
raise Inspec::Deprecation::InvalidConfigFileError, "Missing fallback_resource_packs field"
|
|
91
|
+
end
|
|
92
|
+
unless @raw_data["fallback_resource_packs"].is_a?(Hash)
|
|
93
|
+
raise Inspec::Deprecation::InvalidConfigFileError, "fallback_resource_packs field must be a Hash"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
@raw_data["fallback_resource_packs"].each do |fallback_pat, fallback_info|
|
|
97
|
+
validate_fallback(fallback_pat, fallback_info)
|
|
98
|
+
end
|
|
86
99
|
end
|
|
87
100
|
|
|
88
101
|
def validate_file_version
|
|
89
102
|
unless @raw_data.key?("file_version")
|
|
90
103
|
raise Inspec::Deprecation::InvalidConfigFileError, "Missing file_version field"
|
|
91
104
|
end
|
|
92
|
-
unless @raw_data["file_version"] == "
|
|
93
|
-
raise Inspec::Deprecation::InvalidConfigFileError, "Unrecognized file_version '#{@raw_data["file_version"]}' - supported versions:
|
|
105
|
+
unless @raw_data["file_version"] == "2.0.0"
|
|
106
|
+
raise Inspec::Deprecation::InvalidConfigFileError, "Unrecognized file_version '#{@raw_data["file_version"]}' - supported versions: 2.0.0"
|
|
94
107
|
end
|
|
95
108
|
end
|
|
96
109
|
|
|
@@ -125,6 +138,29 @@ module Inspec
|
|
|
125
138
|
|
|
126
139
|
groups[name.to_sym] = entry
|
|
127
140
|
end
|
|
141
|
+
|
|
142
|
+
def validate_fallback(pattern, raw_info)
|
|
143
|
+
fallback = FallbackEntry.new
|
|
144
|
+
begin
|
|
145
|
+
fallback.resource_name_regex = Regexp.new(pattern)
|
|
146
|
+
rescue RegexpError
|
|
147
|
+
raise Inspec::Deprecation::InvalidConfigFileError, "Invalid regular expression in resource pack fallback definition '#{pattern}'"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
unless raw_info["gem"]
|
|
151
|
+
raise Inspec::Deprecation::InvalidConfigFileError, "fallback_resource_packs missing gem name for pattern '#{pattern}'"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
fallback.gem_name = raw_info["gem"]
|
|
155
|
+
|
|
156
|
+
unless raw_info["message"]
|
|
157
|
+
raise Inspec::Deprecation::InvalidConfigFileError, "fallback_resource_packs missing message for pattern '#{pattern}'"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
fallback.message = raw_info["message"]
|
|
161
|
+
|
|
162
|
+
fallback_resource_packs.push fallback
|
|
163
|
+
end
|
|
128
164
|
end
|
|
129
165
|
end
|
|
130
166
|
end
|
|
@@ -4,11 +4,12 @@ require "inspec/log"
|
|
|
4
4
|
module Inspec
|
|
5
5
|
module Deprecation
|
|
6
6
|
class Deprecator
|
|
7
|
-
attr_reader :config, :groups
|
|
7
|
+
attr_reader :config, :fallback_resource_packs, :groups
|
|
8
8
|
|
|
9
9
|
def initialize(opts = {})
|
|
10
10
|
@config = Inspec::Deprecation::ConfigFile.new(opts[:config_io])
|
|
11
11
|
@groups = @config.groups
|
|
12
|
+
@fallback_resource_packs = @config.fallback_resource_packs
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
def handle_deprecation(group_name, message, opts = {})
|
|
@@ -21,6 +22,13 @@ module Inspec
|
|
|
21
22
|
send(action_method, group_name.to_sym, assembled_message, group)
|
|
22
23
|
end
|
|
23
24
|
|
|
25
|
+
# Given a resource name, suggest a gem nam to load and or install
|
|
26
|
+
def match_gem_for_fallback_resource_name(resource_name)
|
|
27
|
+
fallback = fallback_resource_packs.find { |fb| fb.resource_name_regex.match(resource_name) }
|
|
28
|
+
# We have a message here but can't pass it back?
|
|
29
|
+
fallback&.gem_name
|
|
30
|
+
end
|
|
31
|
+
|
|
24
32
|
private
|
|
25
33
|
|
|
26
34
|
def create_group_entry_for_unknown_group(group_name)
|
|
@@ -61,8 +69,7 @@ module Inspec
|
|
|
61
69
|
|
|
62
70
|
suffix += (" (used at " + opts[:used_at_stack_frame].path + ":" + opts[:used_at_stack_frame].lineno.to_s + ")") if opts.key?(:used_at_stack_frame)
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
keyword + prefix + message + suffix
|
|
72
|
+
"DEPRECATION: " + prefix + message + suffix
|
|
66
73
|
end
|
|
67
74
|
|
|
68
75
|
def called_from_control?
|
|
@@ -26,8 +26,11 @@ module Inspec
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def self.run_by_thor?(stack)
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
# Handled in both ways to fix label differences for Ruby 3.4 and other versions of Ruby
|
|
30
|
+
(stack_match(stack: stack, path: "thor/command", label: "Thor::Command#run") &&
|
|
31
|
+
stack_match(stack: stack, path: "thor/invocation", label: "Thor::Invocation#invoke_command")) ||
|
|
32
|
+
(stack_match(stack: stack, path: "thor/command", label: "run") &&
|
|
33
|
+
stack_match(stack: stack, path: "thor/invocation", label: "invoke_command"))
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def self.kitchen?(stack)
|
data/lib/inspec/version.rb
CHANGED
|
@@ -5,6 +5,8 @@ require "inspec/utils/waivers/json_file_reader"
|
|
|
5
5
|
module Inspec
|
|
6
6
|
class WaiverFileReader
|
|
7
7
|
|
|
8
|
+
SUPPORTED_FILE_EXTENSION = %w{.yaml .yml .csv .json}.freeze
|
|
9
|
+
|
|
8
10
|
def self.fetch_waivers_by_profile(profile_id, files)
|
|
9
11
|
read_waivers_from_file(profile_id, files) if @waivers_data.nil? || @waivers_data[profile_id].nil?
|
|
10
12
|
@waivers_data[profile_id]
|
|
@@ -15,14 +17,10 @@ module Inspec
|
|
|
15
17
|
output = {}
|
|
16
18
|
|
|
17
19
|
files.each do |file_path|
|
|
18
|
-
|
|
19
|
-
output.merge!(data) if !data.nil? && data.is_a?(Hash)
|
|
20
|
+
next unless valid_waiver_file?(file_path)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"Cannot find parser for waivers file." \
|
|
24
|
-
"Check to make sure file has the appropriate extension."
|
|
25
|
-
end
|
|
22
|
+
data = parse_waiver_file(file_path)
|
|
23
|
+
output.merge!(data) if data.is_a?(Hash)
|
|
26
24
|
rescue Inspec::Exceptions::WaiversFileNotReadable, Inspec::Exceptions::WaiversFileInvalidFormatting => e
|
|
27
25
|
Inspec::Log.error "Error reading waivers file #{file_path}. #{e.message}"
|
|
28
26
|
Inspec::UI.new.exit(:usage_error)
|
|
@@ -31,21 +29,38 @@ module Inspec
|
|
|
31
29
|
@waivers_data[profile_id] = output
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
def self.
|
|
35
|
-
|
|
36
|
-
file_extension = File.extname(file_path)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
def self.valid_waiver_file?(file_path)
|
|
33
|
+
# Check if the file is readable
|
|
34
|
+
file_extension = File.extname(file_path).downcase
|
|
35
|
+
unless SUPPORTED_FILE_EXTENSION.include?(file_extension)
|
|
36
|
+
raise Inspec::Exceptions::WaiversFileNotReadable,
|
|
37
|
+
"Unsupported file extension for '#{file_path}'. Allowed waiver file extensions: #{SUPPORTED_FILE_EXTENSION.join(", ")}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Check if the file is empty
|
|
41
|
+
if File.zero?(file_path)
|
|
42
|
+
Inspec::Log.warn "Waivers file '#{file_path}' is empty. Skipping waivers."
|
|
43
|
+
return false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.parse_waiver_file(file_path)
|
|
50
|
+
file_extension = File.extname(file_path).downcase
|
|
51
|
+
|
|
52
|
+
case file_extension
|
|
53
|
+
when ".yaml", ".yml"
|
|
54
|
+
data = Secrets::YAML.resolve(file_path)&.inputs
|
|
40
55
|
validate_json_yaml(data)
|
|
41
|
-
|
|
56
|
+
when ".csv"
|
|
42
57
|
data = Waivers::CSVFileReader.resolve(file_path)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
elsif file_extension == ".json"
|
|
58
|
+
validate_csv_headers(Waivers::CSVFileReader.headers)
|
|
59
|
+
when ".json"
|
|
46
60
|
data = Waivers::JSONFileReader.resolve(file_path)
|
|
47
|
-
validate_json_yaml(data)
|
|
61
|
+
validate_json_yaml(data)
|
|
48
62
|
end
|
|
63
|
+
|
|
49
64
|
data
|
|
50
65
|
end
|
|
51
66
|
|
|
@@ -81,6 +96,8 @@ module Inspec
|
|
|
81
96
|
end
|
|
82
97
|
|
|
83
98
|
def self.validate_json_yaml(data)
|
|
99
|
+
return if data.nil?
|
|
100
|
+
|
|
84
101
|
missing_required_field = false
|
|
85
102
|
data.each do |key, value|
|
|
86
103
|
# In case of yaml or json we need to validate headers/parametes for each value
|
data/lib/inspec.rb
CHANGED
|
@@ -426,7 +426,7 @@ module InspecPlugins
|
|
|
426
426
|
"at https://github.com/inspec/inspec/issues/new")
|
|
427
427
|
ui.exit Inspec::UI::EXIT_PLUGIN_ERROR
|
|
428
428
|
rescue Inspec::Plugin::V2::InstallError => e
|
|
429
|
-
# This change is
|
|
429
|
+
# This change is required for Ruby 3.3 upgrade
|
|
430
430
|
# Using Inspec::Log::level breaks with error `undefined method nil` in Ruby log library
|
|
431
431
|
Inspec::Log.debug e.backtrace
|
|
432
432
|
|
|
@@ -12,7 +12,7 @@ require "tmpdir" unless defined?(Dir.mktmpdir)
|
|
|
12
12
|
require "pathname" unless defined?(Pathname)
|
|
13
13
|
require "forwardable" unless defined?(Forwardable)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
require_relative "../../../test/functional/helper"
|
|
16
16
|
require "inspec/plugin/v2"
|
|
17
17
|
|
|
18
18
|
# Configure Minitest to expose things like `let`
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require "inspec/fetcher"
|
|
2
|
+
require "inspec/metadata"
|
|
3
|
+
|
|
4
|
+
module SourceReaders
|
|
5
|
+
class GemReader < Inspec.source_reader(1)
|
|
6
|
+
name "gem"
|
|
7
|
+
priority 20
|
|
8
|
+
|
|
9
|
+
def self.resolve(target)
|
|
10
|
+
return new(target) unless target.files.grep(/gemspec/).empty?
|
|
11
|
+
|
|
12
|
+
nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_reader :metadata, :metadata_src, :tests, :libraries, :data_files, :target, :readme
|
|
16
|
+
|
|
17
|
+
# This creates a new instance of an InSpec Gem-packaged profile source reader
|
|
18
|
+
# As of July 2024 only resource packs, not controls, may be packaged as gems
|
|
19
|
+
#
|
|
20
|
+
# @param [FileProvider] target An instance of a FileProvider object that can list files and read them
|
|
21
|
+
def initialize(target)
|
|
22
|
+
@target = target
|
|
23
|
+
@metadata = load_metadata(target.files.grep("inspec.yml").first)
|
|
24
|
+
@tests = {} # TODO - one day support controls?
|
|
25
|
+
@libraries = load_libs
|
|
26
|
+
@data_files = {}
|
|
27
|
+
@readme = load_readme
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def load_metadata(metadata_source)
|
|
33
|
+
@metadata_src = @target.read(metadata_source)
|
|
34
|
+
Inspec::Metadata.from_ref(
|
|
35
|
+
metadata_source,
|
|
36
|
+
@metadata_src,
|
|
37
|
+
nil
|
|
38
|
+
)
|
|
39
|
+
rescue Psych::SyntaxError => e
|
|
40
|
+
raise "Unable to parse inspec.yml: line #{e.line}, #{e.problem} #{e.context}"
|
|
41
|
+
rescue => e
|
|
42
|
+
raise "Unable to parse #{metadata_source}: #{e.class} -- #{e.message}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def find_all(regexp)
|
|
46
|
+
@target.files.grep(regexp)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def load_all(regexp)
|
|
50
|
+
find_all(regexp)
|
|
51
|
+
.map { |path| file = @target.read(path); [path, file] if file }
|
|
52
|
+
.compact
|
|
53
|
+
.to_h
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def load_libs
|
|
57
|
+
# Legacy resource packs (inspec-gcp, inspec-aws, etc) have resources in old locations
|
|
58
|
+
load_all(%r{^libraries/.*\.rb$})
|
|
59
|
+
# New resource packs have them here
|
|
60
|
+
load_all(%r{^lib/.*/resources/.*\.rb$})
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def load_readme
|
|
64
|
+
load_all(/README.md/)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|