Merge branch 'cw/attrs-rename-cli-option' into 3-stable

This commit is contained in:
Clinton Wolfe 2019-04-09 12:10:53 -04:00
commit 2b30646642
7 changed files with 65 additions and 22 deletions

View file

@ -107,8 +107,10 @@ module Inspec
option :reporter, type: :array, option :reporter, type: :array,
banner: 'one two:/output/file/path', banner: 'one two:/output/file/path',
desc: 'Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml' desc: 'Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml'
option :attrs, type: :array, option :input_file, type: :array,
desc: 'Load one or more input files, a YAML file with values for the profile to use' desc: 'Load one or more input files, a YAML file with values for the profile to use'
option :attrs, type: :array,
desc: 'Legacy name for --input-file - deprecated.'
option :create_lockfile, type: :boolean, option :create_lockfile, type: :boolean,
desc: 'Write out a lockfile based on this execution (unless one already exists)' desc: 'Write out a lockfile based on this execution (unless one already exists)'
option :backend_cache, type: :boolean, option :backend_cache, type: :boolean,

View file

@ -23,8 +23,8 @@ module Inspec
# output warn message if we are in a exec call # output warn message if we are in a exec call
Inspec::Log.warn( Inspec::Log.warn(
"Attribute '#{@name}' does not have a value. "\ "Input '#{@name}' does not have a value. "\
"Use --attrs to provide a value for '#{@name}' or specify a "\ "Use --input-file to provide a value for '#{@name}' or specify a "\
"value with `attribute('#{@name}', value: 'somevalue', ...)`.", "value with `attribute('#{@name}', value: 'somevalue', ...)`.",
) if Inspec::BaseCLI.inspec_cli_command == :exec ) if Inspec::BaseCLI.inspec_cli_command == :exec
end end

View file

@ -151,10 +151,14 @@ module Inspec
# determine all inputs before the execution, fetch data from secrets backend # determine all inputs before the execution, fetch data from secrets backend
def load_inputs(options) def load_inputs(options)
# TODO: - rename :attributes and :attrs - these are both user-visible # TODO: - rename :attributes - it is user-visible
options[:attributes] ||= {} options[:attributes] ||= {}
secrets_targets = options[:attrs] if options.key?(:attrs)
Inspec.deprecate(:rename_attributes_to_inputs, 'Use --input-file on the command line instead of --attrs.')
options[:input_file] = options.delete(:attrs)
end
secrets_targets = options[:input_file]
return options[:attributes] if secrets_targets.nil? return options[:attributes] if secrets_targets.nil?
secrets_targets.each do |target| secrets_targets.each do |target|

View file

@ -68,7 +68,7 @@ describe 'example inheritance profile' do
end end
it 'can execute a profile inheritance' do it 'can execute a profile inheritance' do
out = inspec('exec ' + path + ' --reporter json --no-create-lockfile --attrs ' + input_file) out = inspec('exec ' + path + ' --reporter json --no-create-lockfile --input-file ' + input_file)
out.stderr.must_equal '' out.stderr.must_equal ''
out.exit_status.must_equal 101 out.exit_status.must_equal 101
JSON.load(out.stdout).must_be_kind_of Hash JSON.load(out.stdout).must_be_kind_of Hash

View file

@ -13,7 +13,7 @@ describe 'inputs' do
cmd = 'exec ' cmd = 'exec '
cmd += File.join(inputs_profiles_path, 'basic') cmd += File.join(inputs_profiles_path, 'basic')
cmd += ' --no-create-lockfile' cmd += ' --no-create-lockfile'
cmd += ' --attrs ' + 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) out = inspec(cmd)
out.stderr.must_equal '' out.stderr.must_equal ''
@ -21,12 +21,49 @@ describe 'inputs' do
end end
end end
describe 'when asking for usage help' do
it 'includes the new --input-file option' do
result = run_inspec_process('exec help', lock: true) # --no-create-lockfile option breaks usage help
lines = result.stdout.split("\n")
line = lines.detect { |l| l.include? '--input-file' }
line.wont_be_nil
end
it 'includes the legacy --attrs option' do
result = run_inspec_process('exec help', lock: true)
lines = result.stdout.split("\n")
line = lines.detect { |l| l.include? '--attrs' }
line.wont_be_nil
end
end
describe 'when using a cli-specified file' do
let(:result) do
cmd = 'exec '
cmd += File.join(inputs_profiles_path, 'basic') + ' '
cmd += flag + ' ' + File.join(inputs_profiles_path, 'basic', 'files', 'flat.yaml')
cmd += ' --controls flat'
run_inspec_process(cmd)
end
describe 'when the --input-file flag is used' do
let(:flag) { '--input-file' }
it 'works' do
result.exit_status.must_equal 0
end
end
describe 'when the --attrs flag is used' do
let(:flag) { '--attrs' }
it 'works' do
result.exit_status.must_equal 0
end
end
end
describe 'run profile with yaml inputs' do describe 'run profile with yaml inputs' do
it "runs using yml inputs" do it "runs using yml inputs" do
cmd = 'exec ' cmd = 'exec '
cmd += File.join(inputs_profiles_path, 'global') cmd += File.join(inputs_profiles_path, 'global')
cmd += ' --no-create-lockfile' cmd += ' --no-create-lockfile'
cmd += ' --attrs ' + File.join(inputs_profiles_path, 'global', 'files', "inputs.yml") cmd += ' --input-file ' + File.join(inputs_profiles_path, 'global', 'files', "inputs.yml")
out = inspec(cmd) out = inspec(cmd)
out.stderr.must_equal '' out.stderr.must_equal ''
# TODO: fix attribute inheritance override test # TODO: fix attribute inheritance override test

View file

@ -98,7 +98,7 @@ Test Summary: 0 successful, 0 failures, 0 skipped
end end
it "executes a profile and reads inputs" do it "executes a profile and reads inputs" do
out = inspec("exec #{File.join(examples_path, 'profile-attribute')} --no-create-lockfile --attrs #{File.join(examples_path, "profile-attribute.yml")}") out = inspec("exec #{File.join(examples_path, 'profile-attribute')} --no-create-lockfile --input-file #{File.join(examples_path, "profile-attribute.yml")}")
out.stderr.must_equal '' out.stderr.must_equal ''
out.exit_status.must_equal 0 out.exit_status.must_equal 0
out.stdout.force_encoding(Encoding::UTF_8).must_include "Test Summary: \e[38;5;41m2 successful\e[0m, 0 failures, 0 skipped" out.stdout.force_encoding(Encoding::UTF_8).must_include "Test Summary: \e[38;5;41m2 successful\e[0m, 0 failures, 0 skipped"

View file

@ -65,34 +65,34 @@ describe Inspec::Runner do
end end
end end
describe 'when no attrs are specified' do describe 'when no input files are specified' do
it 'returns an empty hash' do it 'returns an empty hash' do
options = {} options = {}
runner.load_inputs(options).must_equal({}) runner.load_inputs(options).must_equal({})
end end
end end
describe 'when an attr is provided and does not resolve' do describe 'when an input file is provided and does not resolve' do
it 'raises an exception' do it 'raises an exception' do
options = { attrs: ['nope.jpg'] } options = { input_file: ['nope.jpg'] }
Inspec::SecretsBackend.expects(:resolve).with('nope.jpg').returns(nil) Inspec::SecretsBackend.expects(:resolve).with('nope.jpg').returns(nil)
proc { runner.load_inputs(options) }.must_raise Inspec::Exceptions::SecretsBackendNotFound proc { runner.load_inputs(options) }.must_raise Inspec::Exceptions::SecretsBackendNotFound
end end
end end
describe 'when an attr is provided and has no inputs' do describe 'when an input file is provided and has no inputs' do
it 'returns an empty hash' do it 'returns an empty hash' do
secrets = mock secrets = mock
secrets.stubs(:inputs).returns(nil) secrets.stubs(:inputs).returns(nil)
options = { attrs: ['empty.yaml'] } options = { input_file: ['empty.yaml'] }
Inspec::SecretsBackend.expects(:resolve).with('empty.yaml').returns(secrets) Inspec::SecretsBackend.expects(:resolve).with('empty.yaml').returns(secrets)
runner.load_inputs(options).must_equal({}) runner.load_inputs(options).must_equal({})
end end
end end
describe 'when an attr is provided and has inputs' do describe 'when an input file is provided and has inputs' do
it 'returns a hash containing the inputs' do it 'returns a hash containing the inputs' do
options = { attrs: ['file1.yaml'] } options = { input_file: ['file1.yaml'] }
inputs = { foo: 'bar' } inputs = { foo: 'bar' }
secrets = mock secrets = mock
secrets.stubs(:inputs).returns(inputs) secrets.stubs(:inputs).returns(inputs)
@ -101,9 +101,9 @@ describe Inspec::Runner do
end end
end end
describe 'when multiple attrs are provided and one fails' do describe 'when multiple input files are provided and one fails' do
it 'raises an exception' do it 'raises an exception' do
options = { attrs: ['file1.yaml', 'file2.yaml'] } options = { input_file: ['file1.yaml', 'file2.yaml'] }
secrets = mock secrets = mock
secrets.stubs(:inputs).returns(nil) secrets.stubs(:inputs).returns(nil)
Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets) Inspec::SecretsBackend.expects(:resolve).with('file1.yaml').returns(secrets)
@ -112,9 +112,9 @@ describe Inspec::Runner do
end end
end end
describe 'when multiple attrs are provided and one has no inputs' do 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 it 'returns a hash containing the inputs from the valid files' do
options = { attrs: ['file1.yaml', 'file2.yaml'] } options = { input_file: ['file1.yaml', 'file2.yaml'] }
inputs = { foo: 'bar' } inputs = { foo: 'bar' }
secrets1 = mock secrets1 = mock
secrets1.stubs(:inputs).returns(nil) secrets1.stubs(:inputs).returns(nil)
@ -126,9 +126,9 @@ describe Inspec::Runner do
end end
end end
describe 'when multiple attrs are provided and all have inputs' do describe 'when multiple input files are provided and all have inputs' do
it 'returns a hash containing all the inputs' do it 'returns a hash containing all the inputs' do
options = { attrs: ['file1.yaml', 'file2.yaml'] } options = { input_file: ['file1.yaml', 'file2.yaml'] }
secrets1 = mock secrets1 = mock
secrets1.stubs(:inputs).returns({ key1: 'value1' }) secrets1.stubs(:inputs).returns({ key1: 'value1' })
secrets2 = mock secrets2 = mock