inspec-core 5.24.24 → 6.6.0
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/Chef-EULA +9 -0
- data/Gemfile +25 -36
- data/etc/deprecations.json +0 -3
- data/etc/features.sig +6 -0
- data/etc/features.yaml +94 -0
- data/inspec-core.gemspec +21 -19
- data/lib/inspec/archive/tar.rb +0 -1
- data/lib/inspec/backend.rb +2 -0
- data/lib/inspec/base_cli.rb +80 -14
- data/lib/inspec/cached_fetcher.rb +24 -3
- data/lib/inspec/cli.rb +292 -235
- data/lib/inspec/config.rb +24 -11
- data/lib/inspec/dependencies/cache.rb +33 -0
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dsl.rb +1 -1
- data/lib/inspec/enhanced_outcomes.rb +1 -0
- data/lib/inspec/errors.rb +5 -0
- data/lib/inspec/exceptions.rb +1 -0
- data/lib/inspec/feature/config.rb +75 -0
- data/lib/inspec/feature/runner.rb +26 -0
- data/lib/inspec/feature.rb +34 -0
- data/lib/inspec/fetcher/git.rb +6 -21
- data/lib/inspec/fetcher/url.rb +7 -29
- data/lib/inspec/file_provider.rb +0 -1
- data/lib/inspec/globals.rb +6 -0
- data/lib/inspec/input_registry.rb +1 -5
- data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +7 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +30 -2
- data/lib/inspec/profile.rb +49 -13
- data/lib/inspec/reporters/cli.rb +1 -1
- data/lib/inspec/reporters/json.rb +2 -12
- data/lib/inspec/reporters.rb +67 -54
- data/lib/inspec/resources/audit_policy.rb +2 -8
- data/lib/inspec/resources/groups.rb +0 -52
- data/lib/inspec/resources/mssql_session.rb +1 -13
- data/lib/inspec/resources/nftables.rb +1 -14
- data/lib/inspec/resources/oracledb_session.rb +11 -72
- data/lib/inspec/resources/package.rb +2 -9
- data/lib/inspec/resources/postgres_session.rb +5 -9
- data/lib/inspec/resources/sybase_session.rb +2 -11
- data/lib/inspec/resources/virtualization.rb +1 -1
- data/lib/inspec/rule.rb +13 -29
- data/lib/inspec/run_data.rb +7 -5
- data/lib/inspec/runner.rb +35 -6
- data/lib/inspec/runner_rspec.rb +12 -9
- data/lib/inspec/secrets/yaml.rb +5 -1
- data/lib/inspec/shell.rb +10 -0
- data/lib/inspec/ui.rb +4 -0
- data/lib/inspec/utils/licensing_config.rb +9 -0
- data/lib/inspec/utils/profile_ast_helpers.rb +12 -39
- data/lib/inspec/utils/waivers/csv_file_reader.rb +1 -1
- data/lib/inspec/utils/waivers/excel_file_reader.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +18 -35
- data/lib/inspec.rb +2 -1
- data/lib/matchers/matchers.rb +3 -3
- data/lib/plugins/inspec-compliance/README.md +1 -11
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +188 -173
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +10 -3
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +23 -21
- data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +15 -13
- data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +15 -13
- data/lib/plugins/inspec-license/README.md +16 -0
- data/lib/plugins/inspec-license/inspec-license.gemspec +6 -0
- data/lib/plugins/inspec-license/lib/inspec-license/cli.rb +26 -0
- data/lib/plugins/inspec-license/lib/inspec-license.rb +14 -0
- data/lib/plugins/inspec-parallel/README.md +27 -0
- data/lib/plugins/inspec-parallel/inspec-parallel.gemspec +6 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/child_status_reporter.rb +61 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/cli.rb +39 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/command.rb +219 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/runner.rb +265 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/base.rb +24 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/silent.rb +7 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/status.rb +124 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/text.rb +23 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel/validator.rb +170 -0
- data/lib/plugins/inspec-parallel/lib/inspec-parallel.rb +18 -0
- data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +10 -11
- data/lib/plugins/inspec-sign/lib/inspec-sign/cli.rb +11 -4
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +6 -13
- data/lib/source_readers/inspec.rb +1 -1
- metadata +53 -65
data/lib/inspec/runner.rb
CHANGED
|
@@ -11,6 +11,7 @@ require "inspec/dependencies/cache"
|
|
|
11
11
|
require "inspec/dist"
|
|
12
12
|
require "inspec/reporters"
|
|
13
13
|
require "inspec/runner_rspec"
|
|
14
|
+
require "chef-licensing"
|
|
14
15
|
# spec requirements
|
|
15
16
|
|
|
16
17
|
module Inspec
|
|
@@ -60,11 +61,13 @@ module Inspec
|
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
if @conf[:waiver_file]
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
Inspec.with_feature("inspec-waivers") {
|
|
65
|
+
@conf[:waiver_file].each do |file|
|
|
66
|
+
unless File.file?(file)
|
|
67
|
+
raise Inspec::Exceptions::WaiversFileDoesNotExist, "Waiver file #{file} does not exist."
|
|
68
|
+
end
|
|
66
69
|
end
|
|
67
|
-
|
|
70
|
+
}
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
# About reading inputs:
|
|
@@ -142,7 +145,7 @@ module Inspec
|
|
|
142
145
|
get_check_example(m, a, b)
|
|
143
146
|
end.compact
|
|
144
147
|
|
|
145
|
-
examples.map { |example| total_checks += example.
|
|
148
|
+
examples.map { |example| total_checks += example.examples.count }
|
|
146
149
|
|
|
147
150
|
unless control_describe_checks.empty?
|
|
148
151
|
# controls with empty tests are avoided
|
|
@@ -159,16 +162,42 @@ module Inspec
|
|
|
159
162
|
end
|
|
160
163
|
|
|
161
164
|
def run(with = nil)
|
|
165
|
+
ChefLicensing.check_software_entitlement! if Inspec::Dist::EXEC_NAME == "inspec"
|
|
166
|
+
|
|
167
|
+
# Validate if profiles are signed and verified
|
|
168
|
+
# Additional check is required to provide error message in case of inspec exec command (exec command can use multiple profiles as well)
|
|
169
|
+
# Only runs this block when preview flag CHEF_PREVIEW_MANDATORY_PROFILE_SIGNING is set
|
|
170
|
+
Inspec.with_feature("inspec-mandatory-profile-signing") {
|
|
171
|
+
unless @conf.allow_unsigned_profiles?
|
|
172
|
+
verify_target_profiles_if_signed(@target_profiles)
|
|
173
|
+
end
|
|
174
|
+
}
|
|
175
|
+
|
|
162
176
|
Inspec::Log.debug "Starting run with targets: #{@target_profiles.map(&:to_s)}"
|
|
163
177
|
load
|
|
164
178
|
run_tests(with)
|
|
179
|
+
rescue ChefLicensing::SoftwareNotEntitled
|
|
180
|
+
Inspec::Log.error "License is not entitled to use InSpec."
|
|
181
|
+
Inspec::UI.new.exit(:license_not_entitled)
|
|
182
|
+
rescue ChefLicensing::Error => e
|
|
183
|
+
Inspec::Log.error e.message
|
|
184
|
+
Inspec::UI.new.exit(:usage_error)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def verify_target_profiles_if_signed(target_profiles)
|
|
188
|
+
unsigned_profiles = []
|
|
189
|
+
target_profiles.each do |profile|
|
|
190
|
+
unsigned_profiles << profile.name unless profile.verify_if_signed
|
|
191
|
+
end
|
|
192
|
+
raise Inspec::ProfileSignatureRequired, "Signature required for profile/s: #{unsigned_profiles.join(", ")}. Please provide a signed profile. Or set CHEF_ALLOW_UNSIGNED_PROFILES in the environment. Or use `--allow-unsigned-profiles` flag with InSpec CLI. " unless unsigned_profiles.empty?
|
|
165
193
|
end
|
|
166
194
|
|
|
167
195
|
def render_output(run_data)
|
|
168
196
|
return if @conf["reporter"].nil?
|
|
169
197
|
|
|
170
198
|
@conf["reporter"].each do |reporter|
|
|
171
|
-
|
|
199
|
+
enhanced_outcome_flag = @conf["enhanced_outcomes"]
|
|
200
|
+
result = Inspec::Reporters.render(reporter, run_data, enhanced_outcome_flag)
|
|
172
201
|
raise Inspec::ReporterError, "Error generating reporter '#{reporter[0]}'" if result == false
|
|
173
202
|
end
|
|
174
203
|
end
|
data/lib/inspec/runner_rspec.rb
CHANGED
|
@@ -177,16 +177,18 @@ module Inspec
|
|
|
177
177
|
next unless streaming_reporters.include? streaming_reporter_name
|
|
178
178
|
|
|
179
179
|
# Activate the plugin so the formatter ID gets registered with RSpec, presumably
|
|
180
|
-
activator = reg.find_activator(plugin_type: :streaming_reporter, activator_name: streaming_reporter_name.to_sym)
|
|
181
|
-
activator.activate!
|
|
182
180
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
181
|
+
Inspec.with_feature("inspec-reporter-#{streaming_reporter_name}") {
|
|
182
|
+
activator = reg.find_activator(plugin_type: :streaming_reporter, activator_name: streaming_reporter_name.to_sym)
|
|
183
|
+
activator.activate!
|
|
184
|
+
# We cannot pass in a nil output path. Rspec only accepts a valid string or a IO object.
|
|
185
|
+
if file_target&.[]("file").nil?
|
|
186
|
+
RSpec.configuration.add_formatter(activator.implementation_class)
|
|
187
|
+
else
|
|
188
|
+
RSpec.configuration.add_formatter(activator.implementation_class, file_target["file"])
|
|
189
|
+
end
|
|
190
|
+
@conf["reporter"].delete(streaming_reporter_name)
|
|
191
|
+
}
|
|
190
192
|
end
|
|
191
193
|
end
|
|
192
194
|
|
|
@@ -196,6 +198,7 @@ module Inspec
|
|
|
196
198
|
def configure_output
|
|
197
199
|
RSpec.configuration.output_stream = $stdout
|
|
198
200
|
@formatter = RSpec.configuration.add_formatter(Inspec::Formatters::Base)
|
|
201
|
+
|
|
199
202
|
@formatter.enhanced_outcomes = @conf.final_options["enhanced_outcomes"]
|
|
200
203
|
RSpec.configuration.add_formatter(Inspec::Formatters::ShowProgress, $stderr) if @conf[:show_progress]
|
|
201
204
|
set_optional_formatters
|
data/lib/inspec/secrets/yaml.rb
CHANGED
|
@@ -18,7 +18,11 @@ module Secrets
|
|
|
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
20
|
# It's not a valid option in 3.0.x
|
|
21
|
-
|
|
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
|
|
22
26
|
|
|
23
27
|
# In case of empty yaml file raise the warning else raise the parsing error.
|
|
24
28
|
if !@inputs || @inputs.empty?
|
data/lib/inspec/shell.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require "chef-licensing"
|
|
2
|
+
require "inspec/dist"
|
|
3
|
+
|
|
1
4
|
autoload :Pry, "pry"
|
|
2
5
|
|
|
3
6
|
module Inspec
|
|
@@ -10,6 +13,7 @@ module Inspec
|
|
|
10
13
|
end
|
|
11
14
|
|
|
12
15
|
def start
|
|
16
|
+
ChefLicensing.check_software_entitlement! if Inspec::Dist::EXEC_NAME == "inspec"
|
|
13
17
|
# This will hold a single evaluation binding context as opened within
|
|
14
18
|
# the instance_eval context of the anonymous class that the profile
|
|
15
19
|
# context creates to evaluate each individual test file. We want to
|
|
@@ -18,6 +22,12 @@ module Inspec
|
|
|
18
22
|
@ctx_binding = @runner.eval_with_virtual_profile("binding")
|
|
19
23
|
configure_pry
|
|
20
24
|
@ctx_binding.pry
|
|
25
|
+
rescue ChefLicensing::SoftwareNotEntitled
|
|
26
|
+
Inspec::Log.error "License is not entitled to use InSpec."
|
|
27
|
+
Inspec::UI.new.exit(:license_not_entitled)
|
|
28
|
+
rescue ChefLicensing::Error => e
|
|
29
|
+
Inspec::Log.error e.message
|
|
30
|
+
Inspec::UI.new.exit(:usage_error)
|
|
21
31
|
end
|
|
22
32
|
|
|
23
33
|
def configure_pry # rubocop:disable Metrics/AbcSize
|
data/lib/inspec/ui.rb
CHANGED
|
@@ -32,9 +32,13 @@ module Inspec
|
|
|
32
32
|
EXIT_FATAL_DEPRECATION = 3
|
|
33
33
|
EXIT_GEM_DEPENDENCY_LOAD_ERROR = 4
|
|
34
34
|
EXIT_BAD_SIGNATURE = 5
|
|
35
|
+
EXIT_SIGNATURE_REQUIRED = 6
|
|
35
36
|
EXIT_LICENSE_NOT_ACCEPTED = 172
|
|
37
|
+
EXIT_LICENSE_NOT_ENTITLED = 173
|
|
38
|
+
EXIT_LICENSE_NOT_SET = 174
|
|
36
39
|
EXIT_FAILED_TESTS = 100
|
|
37
40
|
EXIT_SKIPPED_TESTS = 101
|
|
41
|
+
EXIT_TERMINATED_BY_CTL_C = 130
|
|
38
42
|
|
|
39
43
|
attr_reader :io
|
|
40
44
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require_relative "../log"
|
|
2
|
+
require "chef-licensing"
|
|
3
|
+
ChefLicensing.configure do |config|
|
|
4
|
+
config.chef_product_name = "InSpec"
|
|
5
|
+
config.chef_entitlement_id = "3ff52c37-e41f-4f6c-ad4d-365192205968"
|
|
6
|
+
config.chef_executable_name = "inspec"
|
|
7
|
+
config.license_server_url = "https://services.chef.io/licensing"
|
|
8
|
+
config.logger = Inspec::Log
|
|
9
|
+
end
|
|
@@ -3,7 +3,8 @@ require "rubocop-ast"
|
|
|
3
3
|
module Inspec
|
|
4
4
|
class Profile
|
|
5
5
|
class AstHelper
|
|
6
|
-
class CollectorBase
|
|
6
|
+
class CollectorBase
|
|
7
|
+
include Parser::AST::Processor::Mixin
|
|
7
8
|
include RuboCop::AST::Traversal
|
|
8
9
|
|
|
9
10
|
attr_reader :memo
|
|
@@ -24,37 +25,6 @@ module Inspec
|
|
|
24
25
|
@memo = memo
|
|
25
26
|
end
|
|
26
27
|
|
|
27
|
-
def extract_node_value(node)
|
|
28
|
-
case node.class.to_s
|
|
29
|
-
when "RuboCop::AST::HashNode"
|
|
30
|
-
# Handle hash nodes
|
|
31
|
-
values = {}
|
|
32
|
-
node.children.each do |pair_node|
|
|
33
|
-
values.merge!(pair_node.key.value => extract_node_value(pair_node.value))
|
|
34
|
-
end
|
|
35
|
-
values
|
|
36
|
-
when "RuboCop::AST::ArrayNode"
|
|
37
|
-
# Handle array nodes
|
|
38
|
-
node.children.map { |element| extract_node_value(element) }
|
|
39
|
-
else
|
|
40
|
-
# Handle simple nodes (strings, numbers, symbols, booleans, nil, etc.)
|
|
41
|
-
if node.respond_to?(:type)
|
|
42
|
-
case node.type
|
|
43
|
-
when :true
|
|
44
|
-
true
|
|
45
|
-
when :false
|
|
46
|
-
false
|
|
47
|
-
when :nil
|
|
48
|
-
nil
|
|
49
|
-
else
|
|
50
|
-
node.respond_to?(:value) ? node.value : node
|
|
51
|
-
end
|
|
52
|
-
else
|
|
53
|
-
node.respond_to?(:value) ? node.value : node
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
28
|
def collect_input(input_children)
|
|
59
29
|
input_name = input_children.children[2].value
|
|
60
30
|
|
|
@@ -70,9 +40,15 @@ module Inspec
|
|
|
70
40
|
if VALID_INPUT_OPTIONS.include?(child_node.key.value)
|
|
71
41
|
if child_node.value.class == RuboCop::AST::Node && REQUIRED_VALUES_MAP.key?(child_node.value.type)
|
|
72
42
|
opts.merge!(child_node.key.value => REQUIRED_VALUES_MAP[child_node.value.type])
|
|
43
|
+
elsif child_node.value.class == RuboCop::AST::HashNode
|
|
44
|
+
# Here value will be a hash
|
|
45
|
+
values = {}
|
|
46
|
+
child_node.value.children.each do |grand_child_node|
|
|
47
|
+
values.merge!(grand_child_node.key.value => grand_child_node.value.value)
|
|
48
|
+
end
|
|
49
|
+
opts.merge!(child_node.key.value => values)
|
|
73
50
|
else
|
|
74
|
-
|
|
75
|
-
opts.merge!(child_node.key.value => extract_node_value(child_node.value))
|
|
51
|
+
opts.merge!(child_node.key.value => child_node.value.value)
|
|
76
52
|
end
|
|
77
53
|
end
|
|
78
54
|
end
|
|
@@ -338,11 +314,8 @@ module Inspec
|
|
|
338
314
|
collectors.push InputCollectorWithinControlBlock.new(@memo)
|
|
339
315
|
collectors.push TestsCollector.new(control_data) if include_tests
|
|
340
316
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
begin_block.each_node do |node_within_control|
|
|
344
|
-
collectors.each { |collector| collector.process(node_within_control) }
|
|
345
|
-
end
|
|
317
|
+
begin_block.each_node do |node_within_control|
|
|
318
|
+
collectors.each { |collector| collector.process(node_within_control) }
|
|
346
319
|
end
|
|
347
320
|
|
|
348
321
|
memo[:controls].push control_data
|
|
@@ -19,7 +19,7 @@ module Waivers
|
|
|
19
19
|
row_hash.delete("control_id")
|
|
20
20
|
row_hash.delete_if { |k, v| k.nil? || v.nil? }
|
|
21
21
|
|
|
22
|
-
waiver_data_hash[control_id] = row_hash if control_id && !
|
|
22
|
+
waiver_data_hash[control_id] = row_hash if control_id && !row_hash.blank?
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
waiver_data_hash
|
|
@@ -25,7 +25,7 @@ module Waivers
|
|
|
25
25
|
row_hash.delete_if { |k, v| k.nil? || v.nil? }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
waiver_data_hash[control_id] = row_hash if control_id && !
|
|
28
|
+
waiver_data_hash[control_id] = row_hash if control_id && !row_hash.blank?
|
|
29
29
|
end
|
|
30
30
|
waiver_data_hash
|
|
31
31
|
rescue Exception => e
|
data/lib/inspec/version.rb
CHANGED
|
@@ -5,8 +5,6 @@ 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
|
-
|
|
10
8
|
def self.fetch_waivers_by_profile(profile_id, files)
|
|
11
9
|
read_waivers_from_file(profile_id, files) if @waivers_data.nil? || @waivers_data[profile_id].nil?
|
|
12
10
|
@waivers_data[profile_id]
|
|
@@ -17,10 +15,14 @@ module Inspec
|
|
|
17
15
|
output = {}
|
|
18
16
|
|
|
19
17
|
files.each do |file_path|
|
|
20
|
-
|
|
18
|
+
data = read_from_file(file_path)
|
|
19
|
+
output.merge!(data) if !data.nil? && data.is_a?(Hash)
|
|
21
20
|
|
|
22
|
-
data
|
|
23
|
-
|
|
21
|
+
if data.nil?
|
|
22
|
+
raise Inspec::Exceptions::WaiversFileNotReadable,
|
|
23
|
+
"Cannot find parser for waivers file." \
|
|
24
|
+
"Check to make sure file has the appropriate extension."
|
|
25
|
+
end
|
|
24
26
|
rescue Inspec::Exceptions::WaiversFileNotReadable, Inspec::Exceptions::WaiversFileInvalidFormatting => e
|
|
25
27
|
Inspec::Log.error "Error reading waivers file #{file_path}. #{e.message}"
|
|
26
28
|
Inspec::UI.new.exit(:usage_error)
|
|
@@ -29,38 +31,21 @@ module Inspec
|
|
|
29
31
|
@waivers_data[profile_id] = output
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
def self.
|
|
33
|
-
|
|
34
|
-
file_extension = File.extname(file_path)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
34
|
+
def self.read_from_file(file_path)
|
|
35
|
+
data = nil
|
|
36
|
+
file_extension = File.extname(file_path)
|
|
37
|
+
if [".yaml", ".yml"].include? file_extension
|
|
38
|
+
data = Secrets::YAML.resolve(file_path)
|
|
39
|
+
data = data.inputs unless data.nil?
|
|
55
40
|
validate_json_yaml(data)
|
|
56
|
-
|
|
41
|
+
elsif file_extension == ".csv"
|
|
57
42
|
data = Waivers::CSVFileReader.resolve(file_path)
|
|
58
|
-
|
|
59
|
-
|
|
43
|
+
headers = Waivers::CSVFileReader.headers
|
|
44
|
+
validate_csv_headers(headers)
|
|
45
|
+
elsif file_extension == ".json"
|
|
60
46
|
data = Waivers::JSONFileReader.resolve(file_path)
|
|
61
|
-
validate_json_yaml(data)
|
|
47
|
+
validate_json_yaml(data) unless data.nil?
|
|
62
48
|
end
|
|
63
|
-
|
|
64
49
|
data
|
|
65
50
|
end
|
|
66
51
|
|
|
@@ -96,8 +81,6 @@ module Inspec
|
|
|
96
81
|
end
|
|
97
82
|
|
|
98
83
|
def self.validate_json_yaml(data)
|
|
99
|
-
return if data.nil?
|
|
100
|
-
|
|
101
84
|
missing_required_field = false
|
|
102
85
|
data.each do |key, value|
|
|
103
86
|
# In case of yaml or json we need to validate headers/parametes for each value
|
data/lib/inspec.rb
CHANGED
|
@@ -4,6 +4,7 @@ libdir = File.dirname(__FILE__)
|
|
|
4
4
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
|
5
5
|
|
|
6
6
|
require "inspec/version"
|
|
7
|
+
require "inspec/utils/licensing_config"
|
|
7
8
|
require "inspec/exceptions"
|
|
8
9
|
require "inspec/utils/deprecation"
|
|
9
10
|
require "inspec/profile"
|
|
@@ -30,4 +31,4 @@ require "inspec/source_reader"
|
|
|
30
31
|
require "inspec/resource"
|
|
31
32
|
|
|
32
33
|
require "inspec/dependency_loader"
|
|
33
|
-
require "inspec/dependency_installer"
|
|
34
|
+
require "inspec/dependency_installer"
|
data/lib/matchers/matchers.rb
CHANGED
|
@@ -299,9 +299,9 @@ RSpec::Matchers.define :cmp do |first_expected| # rubocop:disable Metrics/BlockL
|
|
|
299
299
|
end
|
|
300
300
|
end
|
|
301
301
|
|
|
302
|
-
def format_actual(actual
|
|
302
|
+
def format_actual(actual)
|
|
303
303
|
actual = "0%o" % actual if octal?(@expected) && !actual.nil?
|
|
304
|
-
"\n%s\n got: %s\n\n(compared using `cmp` matcher)\n" % [format_expectation(
|
|
304
|
+
"\n%s\n got: %s\n\n(compared using `cmp` matcher)\n" % [format_expectation(false), actual]
|
|
305
305
|
end
|
|
306
306
|
|
|
307
307
|
def format_expectation(negate)
|
|
@@ -316,7 +316,7 @@ RSpec::Matchers.define :cmp do |first_expected| # rubocop:disable Metrics/BlockL
|
|
|
316
316
|
end
|
|
317
317
|
|
|
318
318
|
failure_message_when_negated do |actual|
|
|
319
|
-
format_actual actual
|
|
319
|
+
format_actual actual
|
|
320
320
|
end
|
|
321
321
|
|
|
322
322
|
description do
|
|
@@ -14,18 +14,8 @@ To use the CLI, this InSpec add-on adds the following commands:
|
|
|
14
14
|
* `$ inspec automate profiles` - list all available Compliance profiles
|
|
15
15
|
* `$ inspec exec compliance://profile` - runs a Compliance profile
|
|
16
16
|
* `$ inspec automate upload path/to/local/profile` - uploads a local profile to Chef Automate/Chef Compliance
|
|
17
|
-
* `$ inspec automate upload path/to/local/profile --legacy` - uploads a local profile to Chef Automate/Chef Compliance using legacy functionalities of inspec check and inspec export
|
|
18
|
-
|
|
19
|
-
*Options*:
|
|
20
|
-
```
|
|
21
|
-
[--overwrite], [--no-overwrite] # Overwrite existing profile on Server.
|
|
22
|
-
[--owner=OWNER] # Owner that should own the profile
|
|
23
|
-
[--legacy], [--no-legacy] # Enable legacy functionality, activating both legacy export and legacy check.
|
|
24
|
-
|
|
25
|
-
uploads a local profile to Chef Automate
|
|
26
|
-
```
|
|
27
17
|
* `$ inspec automate logout` - logout of Chef Automate/Chef Compliance
|
|
28
|
-
|
|
18
|
+
|
|
29
19
|
Similar to these CLI commands are:
|
|
30
20
|
|
|
31
21
|
* `$ inspec compliance login` - authentication of the API token against Chef Automate/Chef Compliance
|