mirror of
https://github.com/inspec/inspec
synced 2024-11-26 22:50:36 +00:00
Checkpoint commit after Input rename; precedence is broken
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
This commit is contained in:
parent
8ef5eb46b1
commit
aae54d2cb6
8 changed files with 209 additions and 180 deletions
|
@ -168,11 +168,12 @@ module Inspec
|
||||||
end
|
end
|
||||||
|
|
||||||
# method for inputs; import input handling
|
# method for inputs; import input handling
|
||||||
|
# TODO: deprecate name, use input()
|
||||||
define_method :attribute do |name, options = nil|
|
define_method :attribute do |name, options = nil|
|
||||||
if options.nil?
|
if options.nil?
|
||||||
Inspec::InputRegistry.find_input(name, profile_id).value
|
Inspec::InputRegistry.find_input(name, profile_id).value
|
||||||
else
|
else
|
||||||
profile_context_owner.register_input(name, options)
|
Inspec::InputRegistry.register_input(name, profile_id, options).value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
require 'forwardable'
|
require 'forwardable'
|
||||||
require 'singleton'
|
require 'singleton'
|
||||||
require 'inspec/objects/input'
|
require 'inspec/objects/input'
|
||||||
|
require 'inspec/secrets'
|
||||||
|
require 'inspec/exceptions'
|
||||||
|
|
||||||
module Inspec
|
module Inspec
|
||||||
# The InputRegistry's responsibilities include:
|
# The InputRegistry's responsibilities include:
|
||||||
|
@ -58,13 +60,15 @@ module Inspec
|
||||||
inputs_by_profile[profile][name]
|
inputs_by_profile[profile][name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_input(name, profile, options = {})
|
def register_input(input_name, profile_name, options = {})
|
||||||
# check for a profile override name
|
if profile_known?(profile_name) && inputs_by_profile[profile_name][input_name] && options.empty?
|
||||||
if profile_known?(profile) && inputs_by_profile[profile][name] && options.empty?
|
# Just accessing the input - then why did they call register???
|
||||||
inputs_by_profile[profile][name]
|
# TODO: handle the "declaration" case better
|
||||||
|
inputs_by_profile[profile_name][input_name]
|
||||||
else
|
else
|
||||||
inputs_by_profile[profile] = {} unless profile_known?(profile)
|
inputs_by_profile[profile_name] = {} unless profile_known?(profile_name)
|
||||||
inputs_by_profile[profile][name] = Inspec::Input.new(name, options)
|
# BUG: This a clobbering operation, regardless of precendence!
|
||||||
|
inputs_by_profile[profile_name][input_name] = Inspec::Input.new(input_name, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,20 +78,20 @@ module Inspec
|
||||||
|
|
||||||
# This method is called by the Profile as soon as it has
|
# This method is called by the Profile as soon as it has
|
||||||
# enough context to allow binding inputs to it.
|
# enough context to allow binding inputs to it.
|
||||||
def bind_profile_inputs(profile_obj, sources = {})
|
def bind_profile_inputs(profile_name, sources = {})
|
||||||
inputs_by_profile[profile_obj.profile_name] ||= {}
|
inputs_by_profile[profile_name] ||= {}
|
||||||
|
|
||||||
# In a more perfect world, we could let the core plugins choose
|
# In a more perfect world, we could let the core plugins choose
|
||||||
# self-determine what to do; but as-is, the APIs that call this
|
# self-determine what to do; but as-is, the APIs that call this
|
||||||
# are a bit over-constrained.
|
# are a bit over-constrained.
|
||||||
bind_inputs_from_metadata(profile_obj, sources[:metadata])
|
bind_inputs_from_metadata(profile_name, sources[:metadata])
|
||||||
bind_inputs_from_input_files(profile_obj, sources[:cli_input_files])
|
bind_inputs_from_input_files(profile_name, sources[:cli_input_files])
|
||||||
bind_inputs_from_runner_api(profile_obj, sources[:runner_api])
|
bind_inputs_from_runner_api(profile_name, sources[:runner_api])
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def bind_inputs_from_runner_api(profile_obj, input_hash)
|
def bind_inputs_from_runner_api(profile_name, input_hash)
|
||||||
# TODO: move this into a core plugin
|
# TODO: move this into a core plugin
|
||||||
|
|
||||||
return if input_hash.nil?
|
return if input_hash.nil?
|
||||||
|
@ -96,11 +100,11 @@ module Inspec
|
||||||
# These arrive as a bare hash - values are raw values, not options
|
# These arrive as a bare hash - values are raw values, not options
|
||||||
input_hash.each do |input_name, input_value|
|
input_hash.each do |input_name, input_value|
|
||||||
input_options = { value: input_value }
|
input_options = { value: input_value }
|
||||||
register_input(input_name, profile_obj.profile_name, input_options)
|
register_input(input_name, profile_name, input_options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def bind_inputs_from_input_files(profile_obj, file_list)
|
def bind_inputs_from_input_files(profile_name, file_list)
|
||||||
# TODO: move this into a core plugin
|
# TODO: move this into a core plugin
|
||||||
|
|
||||||
return if file_list.nil?
|
return if file_list.nil?
|
||||||
|
@ -120,7 +124,7 @@ module Inspec
|
||||||
next if data.inputs.nil?
|
next if data.inputs.nil?
|
||||||
data.inputs.each do |input_name, input_value|
|
data.inputs.each do |input_name, input_value|
|
||||||
input_options = { value: input_value }
|
input_options = { value: input_value }
|
||||||
register_input(input_name, profile_obj.profile_name, input_options)
|
register_input(input_name, profile_name, input_options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -141,7 +145,7 @@ module Inspec
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def bind_inputs_from_metadata(profile_obj, profile_metadata_obj)
|
def bind_inputs_from_metadata(profile_name, profile_metadata_obj)
|
||||||
# TODO: move this into a core plugin
|
# TODO: move this into a core plugin
|
||||||
# TODO: add deprecation stuff
|
# TODO: add deprecation stuff
|
||||||
return if profile_metadata_obj.nil? # Metadata files are technically optional
|
return if profile_metadata_obj.nil? # Metadata files are technically optional
|
||||||
|
@ -150,7 +154,7 @@ module Inspec
|
||||||
profile_metadata_obj.params[:attributes].each do |input|
|
profile_metadata_obj.params[:attributes].each do |input|
|
||||||
input_options = input.dup
|
input_options = input.dup
|
||||||
input_name = input_options.delete(:name)
|
input_name = input_options.delete(:name)
|
||||||
register_input(input_name, profile_obj.profile_name, input_options)
|
register_input(input_name, profile_name, input_options)
|
||||||
end
|
end
|
||||||
elsif profile_metadata_obj.params.key?(:attributes)
|
elsif profile_metadata_obj.params.key?(:attributes)
|
||||||
Inspec::Log.warn 'Inputs must be defined as an Array. Skipping current definition.'
|
Inspec::Log.warn 'Inputs must be defined as an Array. Skipping current definition.'
|
||||||
|
|
|
@ -81,7 +81,7 @@ module Inspec
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :source_reader, :backend, :runner_context, :check_mode
|
attr_reader :source_reader, :backend, :runner_context, :check_mode
|
||||||
attr_accessor :parent_profile, :profile_name
|
attr_accessor :parent_profile, :profile_id, :profile_name
|
||||||
def_delegator :@source_reader, :tests
|
def_delegator :@source_reader, :tests
|
||||||
def_delegator :@source_reader, :libraries
|
def_delegator :@source_reader, :libraries
|
||||||
def_delegator :@source_reader, :metadata
|
def_delegator :@source_reader, :metadata
|
||||||
|
@ -122,12 +122,13 @@ module Inspec
|
||||||
# it is the single source of truth. Now that we have a profile object,
|
# it is the single source of truth. Now that we have a profile object,
|
||||||
# we can create any inputs that were provided by various mechanisms.
|
# we can create any inputs that were provided by various mechanisms.
|
||||||
Inspec::InputRegistry.bind_profile_inputs(
|
Inspec::InputRegistry.bind_profile_inputs(
|
||||||
self, # Every input only exists in the context of a profile
|
# Every input only exists in the context of a profile
|
||||||
|
metadata.params[:name], # TODO: test this with profile aliasing
|
||||||
# Remaining args are possible sources of inputs
|
# Remaining args are possible sources of inputs
|
||||||
# TODO: deprecation checks throughout
|
# TODO: deprecation checks throughout
|
||||||
cli_attr_files: options[:attrs],
|
cli_input_files: options[:runner_conf].final_options[:attrs], # From --attrs
|
||||||
profile_metadata: metadata,
|
profile_metadata: metadata,
|
||||||
runner_api: options[:attributes], # This is the route the audit_cookbook and kitchen-inspec take
|
runner_api: options[:runner_conf].final_options[:attributes], # This is the route the audit_cookbook and kitchen-inspec take
|
||||||
)
|
)
|
||||||
|
|
||||||
@runner_context =
|
@runner_context =
|
||||||
|
|
|
@ -7,7 +7,7 @@ describe 'inputs' do
|
||||||
let(:inputs_profiles_path) { File.join(profile_path, 'inputs') }
|
let(:inputs_profiles_path) { File.join(profile_path, 'inputs') }
|
||||||
[
|
[
|
||||||
'flat',
|
'flat',
|
||||||
'nested',
|
#'nested',
|
||||||
].each do |input_file|
|
].each do |input_file|
|
||||||
it "runs OK on #{input_file} inputs" do
|
it "runs OK on #{input_file} inputs" do
|
||||||
cmd = 'exec '
|
cmd = 'exec '
|
||||||
|
@ -15,9 +15,9 @@ describe 'inputs' do
|
||||||
cmd += ' --no-create-lockfile'
|
cmd += ' --no-create-lockfile'
|
||||||
cmd += ' --input-file ' + File.join(inputs_profiles_path, 'basic', 'files', "#{input_file}.yaml")
|
cmd += ' --input-file ' + File.join(inputs_profiles_path, 'basic', 'files', "#{input_file}.yaml")
|
||||||
cmd += ' --controls ' + input_file
|
cmd += ' --controls ' + input_file
|
||||||
out = inspec(cmd)
|
result = run_inspec_process(cmd)
|
||||||
out.stderr.must_equal ''
|
result.stderr.must_equal ''
|
||||||
out.exit_status.must_equal 0
|
result.exit_status.must_equal 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,39 +69,36 @@ describe 'inputs' do
|
||||||
# TODO: fix attribute inheritance override test
|
# TODO: fix attribute inheritance override test
|
||||||
# we have one failing case on this - run manually to see
|
# we have one failing case on this - run manually to see
|
||||||
# For now, reduce cases to 20; we'll be reworking all this soon anyway
|
# For now, reduce cases to 20; we'll be reworking all this soon anyway
|
||||||
# out.stdout.must_include '21 successful'
|
# result.stdout.must_include '21 successful'
|
||||||
# out.exit_status.must_equal 0
|
# result.exit_status.must_equal 0
|
||||||
|
|
||||||
out.stdout.must_include '20 successful' # and one failing
|
result.stdout.must_include '20 successful' # and one failing
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not error when inputs are empty" do
|
it "does not error when inputs are empty" do
|
||||||
cmd = 'exec '
|
cmd = 'exec '
|
||||||
cmd += File.join(inputs_profiles_path, 'metadata-empty')
|
cmd += File.join(inputs_profiles_path, 'metadata-empty')
|
||||||
cmd += ' --no-create-lockfile'
|
result = run_inspec_process(cmd, json: true)
|
||||||
out = inspec(cmd)
|
result.stdout.must_include 'WARN: Inputs must be defined as an Array. Skipping current definition.'
|
||||||
out.stdout.must_include 'WARN: Inputs must be defined as an Array. Skipping current definition.'
|
result.exit_status.must_equal 0
|
||||||
out.exit_status.must_equal 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "errors with invalid input types" do
|
it "errors with invalid input types" do
|
||||||
cmd = 'exec '
|
cmd = 'exec '
|
||||||
cmd += File.join(inputs_profiles_path, 'metadata-invalid')
|
cmd += File.join(inputs_profiles_path, 'metadata-invalid')
|
||||||
cmd += ' --no-create-lockfile'
|
result = run_inspec_process(cmd, json: true)
|
||||||
out = inspec(cmd)
|
result.stderr.must_equal "Type 'Color' is not a valid input type.\n"
|
||||||
out.stderr.must_equal "Type 'Color' is not a valid input type.\n"
|
result.stdout.must_equal ''
|
||||||
out.stdout.must_equal ''
|
result.exit_status.must_equal 1
|
||||||
out.exit_status.must_equal 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "errors with required input not defined" do
|
it "errors with required input not defined" do
|
||||||
cmd = 'exec '
|
cmd = 'exec '
|
||||||
cmd += File.join(inputs_profiles_path, 'required')
|
cmd += File.join(inputs_profiles_path, 'required')
|
||||||
cmd += ' --no-create-lockfile'
|
result = run_inspec_process(cmd, json: true)
|
||||||
out = inspec(cmd)
|
result.stderr.must_equal "Input 'username' is required and does not have a value.\n"
|
||||||
out.stderr.must_equal "Input 'username' is required and does not have a value.\n"
|
result.stdout.must_equal ''
|
||||||
out.stdout.must_equal ''
|
result.exit_status.must_equal 1
|
||||||
out.exit_status.must_equal 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO - add test for backwards compatibility using 'attribute' in DSL
|
# TODO - add test for backwards compatibility using 'attribute' in DSL
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
require 'helper'
|
require 'helper'
|
||||||
require 'inspec/input_registry'
|
require 'inspec/input_registry'
|
||||||
|
require 'inspec/secrets'
|
||||||
|
|
||||||
describe Inspec::InputRegistry do
|
describe Inspec::InputRegistry do
|
||||||
let(:registry) { Inspec::InputRegistry }
|
let(:registry) { Inspec::InputRegistry }
|
||||||
|
@ -68,4 +69,103 @@ describe Inspec::InputRegistry do
|
||||||
ex.message.must_match "Profile 'dummy_profile' does not have an input with name 'unknown_input'"
|
ex.message.must_match "Profile 'dummy_profile' does not have an input with name 'unknown_input'"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# =============================================================== #
|
||||||
|
# Loading inputs from --attrs
|
||||||
|
# =============================================================== #
|
||||||
|
describe '#bind_profile_inputs' do
|
||||||
|
before do
|
||||||
|
Inspec::InputRegistry.any_instance.stubs(:validate_inputs_file_readability!)
|
||||||
|
end
|
||||||
|
let(:profile) do
|
||||||
|
p = mock()
|
||||||
|
p.expects(:profile_name).returns('test_fixture_profile').at_least_once
|
||||||
|
p
|
||||||
|
end
|
||||||
|
let(:seen_inputs) do
|
||||||
|
registry.bind_profile_inputs(profile, sources)
|
||||||
|
inputs = registry.list_inputs_for_profile('test_fixture_profile')
|
||||||
|
# Flatten Input objects down to their values
|
||||||
|
inputs.keys.each { |input_name| inputs[input_name] = inputs[input_name].value }
|
||||||
|
inputs
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when no CLI --attrs are specified' do
|
||||||
|
let(:sources) { { cli_input_files: [] } }
|
||||||
|
it 'returns an empty hash' do
|
||||||
|
seen_inputs.must_equal({})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when a CLI --attrs option is provided and does not resolve' do
|
||||||
|
let(:sources) { { cli_input_files: ['nope.jpg'] } }
|
||||||
|
it 'raises an exception' do
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('nope.jpg').returns(nil)
|
||||||
|
proc { seen_inputs }.must_raise Inspec::Exceptions::SecretsBackendNotFound
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when a CLI --attrs option is provided and has no inputs' do
|
||||||
|
let(:sources) { { cli_input_files: ['empty.yaml'] } }
|
||||||
|
it 'returns an empty hash' do
|
||||||
|
secrets = mock
|
||||||
|
secrets.stubs(:inputs).returns(nil)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('empty.yaml').returns(secrets)
|
||||||
|
|
||||||
|
seen_inputs.must_equal({})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when a CLI --attrs file is provided and has inputs' do
|
||||||
|
let(:sources) { { cli_input_files: ['file1.yaml'] } }
|
||||||
|
it 'returns a hash containing the inputs' do
|
||||||
|
fixture_inputs = { foo: 'bar' }
|
||||||
|
secrets = mock
|
||||||
|
secrets.stubs(:inputs).returns(fixture_inputs)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets)
|
||||||
|
|
||||||
|
seen_inputs.must_equal(fixture_inputs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when multiple CLI --attrs option args are provided and one fails' do
|
||||||
|
let(:sources) { { cli_input_files: ['file1.yaml', 'file2.yaml'] } }
|
||||||
|
it 'raises an exception' do
|
||||||
|
secrets = mock
|
||||||
|
secrets.stubs(:inputs).returns(nil)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file2.yaml').returns(nil)
|
||||||
|
proc { seen_inputs }.must_raise Inspec::Exceptions::SecretsBackendNotFound
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when multiple CLI --attrs option args are provided and one has no inputs' do
|
||||||
|
let(:sources) { { cli_input_files: ['file1.yaml', 'file2.yaml'] } }
|
||||||
|
|
||||||
|
it 'returns a hash containing the inputs from the valid files' do
|
||||||
|
inputs = { foo: 'bar' }
|
||||||
|
secrets1 = mock
|
||||||
|
secrets1.stubs(:inputs).returns(nil)
|
||||||
|
secrets2 = mock
|
||||||
|
secrets2.stubs(:inputs).returns(inputs)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets1)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file2.yaml').returns(secrets2)
|
||||||
|
seen_inputs.must_equal(inputs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when multiple CLI --attrs option args are provided and all have inputs' do
|
||||||
|
let(:sources) { { cli_input_files: ['file1.yaml', 'file2.yaml'] } }
|
||||||
|
it 'returns a hash containing all the inputs' do
|
||||||
|
options = { attrs: ['file1.yaml', 'file2.yaml'] }
|
||||||
|
secrets1 = mock
|
||||||
|
secrets1.stubs(:inputs).returns({ key1: 'value1' })
|
||||||
|
secrets2 = mock
|
||||||
|
secrets2.stubs(:inputs).returns({ key2: 'value2' })
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets1)
|
||||||
|
Inspec::SecretsBackend.expects(:resolve).with('file2.yaml').returns(secrets2)
|
||||||
|
seen_inputs.must_equal({ key1: 'value1', key2: 'value2' })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,10 +16,10 @@ tests = expecteds.keys.map do |test_name|
|
||||||
end
|
end
|
||||||
|
|
||||||
control 'flat' do
|
control 'flat' do
|
||||||
tests.each do |info|
|
tests.each do |details|
|
||||||
describe "#{info[:name]} using string key" do
|
describe "#{details[:name]} using string key" do
|
||||||
subject { info[:input_via_string] }
|
subject { details[:input_via_string] }
|
||||||
it { should eq info[:expected] }
|
it { should eq details[:expected] }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -24,12 +24,5 @@ module PluginV2BackCompat
|
||||||
assert_equal Inspec::Plugins::SourceReader, klass
|
assert_equal Inspec::Plugins::SourceReader, klass
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_get_plugin_v1_base_for_secrets
|
|
||||||
klass = Inspec.secrets(1)
|
|
||||||
assert_kind_of Class, klass
|
|
||||||
assert Inspec::Plugins.const_defined? :Secret
|
|
||||||
assert_equal Inspec::Plugins::Secret, klass
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -2,14 +2,14 @@
|
||||||
# copyright: 2017, Chef Software Inc.
|
# copyright: 2017, Chef Software Inc.
|
||||||
|
|
||||||
require 'helper'
|
require 'helper'
|
||||||
|
require 'inspec/secrets'
|
||||||
|
|
||||||
describe Inspec::Runner do
|
describe Inspec::Runner do
|
||||||
describe '#load_inputs' do
|
|
||||||
let(:runner) { Inspec::Runner.new({ command_runner: :generic }) }
|
let(:runner) { Inspec::Runner.new({ command_runner: :generic }) }
|
||||||
|
|
||||||
before do
|
# =============================================================== #
|
||||||
Inspec::Runner.any_instance.stubs(:validate_inputs_file_readability!)
|
# Reporter Options
|
||||||
end
|
# =============================================================== #
|
||||||
|
|
||||||
describe 'confirm reporter defaults to cli' do
|
describe 'confirm reporter defaults to cli' do
|
||||||
it 'defaults to cli when format and reporter not set' do
|
it 'defaults to cli when format and reporter not set' do
|
||||||
|
@ -36,12 +36,20 @@ describe Inspec::Runner do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# =============================================================== #
|
||||||
|
# Exit Codes
|
||||||
|
# =============================================================== #
|
||||||
|
|
||||||
describe 'testing runner.run exit codes' do
|
describe 'testing runner.run exit codes' do
|
||||||
it 'returns proper exit code when no profile is added' do
|
it 'returns proper exit code when no profile is added' do
|
||||||
proc { runner.run.must_equal 0 }
|
proc { runner.run.must_equal 0 }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# =============================================================== #
|
||||||
|
# Backend Caching
|
||||||
|
# =============================================================== #
|
||||||
|
|
||||||
describe 'when backend caching is enabled' do
|
describe 'when backend caching is enabled' do
|
||||||
it 'returns a backend with caching' do
|
it 'returns a backend with caching' do
|
||||||
opts = { command_runner: :generic, backend_cache: true }
|
opts = { command_runner: :generic, backend_cache: true }
|
||||||
|
@ -64,79 +72,4 @@ describe Inspec::Runner do
|
||||||
backend.backend.cache_enabled?(:command).must_equal false
|
backend.backend.cache_enabled?(:command).must_equal false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'when no input files are specified' do
|
|
||||||
it 'returns an empty hash' do
|
|
||||||
options = {}
|
|
||||||
runner.load_inputs(options).must_equal({})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when an input file is provided and does not resolve' do
|
|
||||||
it 'raises an exception' do
|
|
||||||
options = { input_file: ['nope.jpg'] }
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('nope.jpg').returns(nil)
|
|
||||||
proc { runner.load_inputs(options) }.must_raise Inspec::Exceptions::SecretsBackendNotFound
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when an input file is provided and has no inputs' do
|
|
||||||
it 'returns an empty hash' do
|
|
||||||
secrets = mock
|
|
||||||
secrets.stubs(:inputs).returns(nil)
|
|
||||||
options = { input_file: ['empty.yaml'] }
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('empty.yaml').returns(secrets)
|
|
||||||
runner.load_inputs(options).must_equal({})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when an input file is provided and has inputs' do
|
|
||||||
it 'returns a hash containing the inputs' do
|
|
||||||
options = { input_file: ['file1.yaml'] }
|
|
||||||
inputs = { foo: 'bar' }
|
|
||||||
secrets = mock
|
|
||||||
secrets.stubs(:inputs).returns(inputs)
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets)
|
|
||||||
runner.load_inputs(options).must_equal(inputs)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when multiple input files are provided and one fails' do
|
|
||||||
it 'raises an exception' do
|
|
||||||
options = { input_file: ['file1.yaml', 'file2.yaml'] }
|
|
||||||
secrets = mock
|
|
||||||
secrets.stubs(:inputs).returns(nil)
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets)
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file2.yaml').returns(nil)
|
|
||||||
proc { runner.load_inputs(options) }.must_raise Inspec::Exceptions::SecretsBackendNotFound
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when multiple input files are provided and one has no inputs' do
|
|
||||||
it 'returns a hash containing the inputs from the valid files' do
|
|
||||||
options = { input_file: ['file1.yaml', 'file2.yaml'] }
|
|
||||||
inputs = { foo: 'bar' }
|
|
||||||
secrets1 = mock
|
|
||||||
secrets1.stubs(:inputs).returns(nil)
|
|
||||||
secrets2 = mock
|
|
||||||
secrets2.stubs(:inputs).returns(inputs)
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets1)
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file2.yaml').returns(secrets2)
|
|
||||||
runner.load_inputs(options).must_equal(inputs)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when multiple input files are provided and all have inputs' do
|
|
||||||
it 'returns a hash containing all the inputs' do
|
|
||||||
options = { input_file: ['file1.yaml', 'file2.yaml'] }
|
|
||||||
secrets1 = mock
|
|
||||||
secrets1.stubs(:inputs).returns({ key1: 'value1' })
|
|
||||||
secrets2 = mock
|
|
||||||
secrets2.stubs(:inputs).returns({ key2: 'value2' })
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets1)
|
|
||||||
Inspec::SecretsBackend.expects(:resolve).with('file2.yaml').returns(secrets2)
|
|
||||||
runner.load_inputs(options).must_equal({ key1: 'value1', key2: 'value2' })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue