diff --git a/etc/deprecations.json b/etc/deprecations.json index 429824a77..5e2b3b831 100644 --- a/etc/deprecations.json +++ b/etc/deprecations.json @@ -11,6 +11,11 @@ "comment": "See #3853", "prefix": "The 'attribute' DSL keyword is being replaced by 'input' - please use it instead." }, + "attrs_rename_in_metadata": { + "action": "ignore", + "comment": "See 3854", + "prefix": "Inputs should be specified by using the 'inputs' key in profile metadata, not 'attributes'." + }, "aws_resources_in_resource_pack": { "comment": "See #3822", "action": "warn", diff --git a/lib/inspec/input_registry.rb b/lib/inspec/input_registry.rb index 96f39b188..fb9e1e8fa 100644 --- a/lib/inspec/input_registry.rb +++ b/lib/inspec/input_registry.rb @@ -205,31 +205,46 @@ module Inspec def bind_inputs_from_metadata(profile_name, profile_metadata_obj) # TODO: move this into a core plugin - # TODO: add deprecation stuff return if profile_metadata_obj.nil? # Metadata files are technically optional - if profile_metadata_obj.params.key?(:attributes) && profile_metadata_obj.params[:attributes].is_a?(Array) - profile_metadata_obj.params[:attributes].each do |input_orig| - input_options = input_orig.dup - input_name = input_options.delete(:name) - input_options.merge!({ priority: 30, provider: :profile_metadata, file: File.join(profile_name, "inspec.yml") }) - evt = Inspec::Input.infer_event(input_options) - - # Profile metadata may set inputs in other profiles by naming them. - if input_options[:profile] - profile_name = input_options[:profile] || profile_name - # Override priority to force this to win. Allow user to set their own priority. - evt.priority = input_orig[:priority] || 35 - end - find_or_register_input(input_name, - profile_name, - type: input_options[:type], - required: input_options[:required], - event: evt) - end + if profile_metadata_obj.params.key?(:inputs) + raw_inputs = profile_metadata_obj.params[:inputs] elsif profile_metadata_obj.params.key?(:attributes) - Inspec::Log.warn "Inputs must be defined as an Array. Skipping current definition." + Inspec.deprecate(:attrs_rename_in_metadata, "Profile: '#{profile_name}'.") + raw_inputs = profile_metadata_obj.params[:attributes] + else + return end + + unless raw_inputs.is_a?(Array) + Inspec::Log.warn "Inputs must be defined as an Array in metadata files. Skipping definition from #{profile_name}." + return + end + + raw_inputs.each { |i| handle_raw_input_from_metadata(i, profile_name) } + end + + def handle_raw_input_from_metadata(input_orig, profile_name) + input_options = input_orig.dup + input_name = input_options.delete(:name) + input_options[:provider] = :profile_metadata + input_options[:file] = File.join(profile_name, "inspec.yml") + input_options[:priority] ||= 30 + evt = Inspec::Input.infer_event(input_options) + + # Profile metadata may set inputs in other profiles by naming them. + if input_options[:profile] + profile_name = input_options[:profile] || profile_name + # Override priority to force this to win. Allow user to set their own priority. + evt.priority = input_orig[:priority] || 35 + end + find_or_register_input( + input_name, + profile_name, + type: input_options[:type], + required: input_options[:required], + event: evt + ) end #-------------------------------------------------------------# diff --git a/test/functional/inputs_test.rb b/test/functional/inputs_test.rb index 954bc5838..f92868e21 100644 --- a/test/functional/inputs_test.rb +++ b/test/functional/inputs_test.rb @@ -80,11 +80,26 @@ describe "inputs" do end describe "run profile with metadata inputs" do + + it "works when using the new 'inputs' key" do + cmd = "exec #{inputs_profiles_path}/metadata-basic" + result = run_inspec_process(cmd, json: true) + result.must_have_all_controls_passing + result.stderr.must_be_empty + end + + it "works when using the legacy 'attributes' key" do + cmd = "exec #{inputs_profiles_path}/metadata-legacy" + result = run_inspec_process(cmd, json: true) + result.must_have_all_controls_passing + # Will eventually issue deprecation warning + end + it "does not error when inputs are empty" do cmd = "exec " cmd += File.join(inputs_profiles_path, "metadata-empty") result = run_inspec_process(cmd, json: true) - result.stderr.must_include "WARN: Inputs must be defined as an Array. Skipping current definition." + result.stderr.must_include "WARN: Inputs must be defined as an Array in metadata files. Skipping definition from profile-with-empty-attributes." assert_exit_code 0, result end diff --git a/test/unit/mock/profiles/inputs/metadata-basic/controls/metadata_controls.rb b/test/unit/mock/profiles/inputs/metadata-basic/controls/metadata_controls.rb new file mode 100644 index 000000000..d2bdcc5b4 --- /dev/null +++ b/test/unit/mock/profiles/inputs/metadata-basic/controls/metadata_controls.rb @@ -0,0 +1,5 @@ +control 'test_control_01' do + describe attribute('test_01') do + it { should cmp 'test_value_01' } + end +end \ No newline at end of file diff --git a/test/unit/mock/profiles/inputs/metadata-basic/inspec.yml b/test/unit/mock/profiles/inputs/metadata-basic/inspec.yml new file mode 100644 index 000000000..358cceb65 --- /dev/null +++ b/test/unit/mock/profiles/inputs/metadata-basic/inspec.yml @@ -0,0 +1,11 @@ +name: metadata_basic +title: InSpec Profile +maintainer: The Authors +copyright: The Authors +copyright_email: you@example.com +license: Apache-2.0 +summary: A profile with a single simple input defined in metadata +version: 0.1.0 +inputs: +- name: test_01 + value: test_value_01 \ No newline at end of file diff --git a/test/unit/mock/profiles/inputs/metadata-legacy/controls/metadata_controls.rb b/test/unit/mock/profiles/inputs/metadata-legacy/controls/metadata_controls.rb new file mode 100644 index 000000000..d2bdcc5b4 --- /dev/null +++ b/test/unit/mock/profiles/inputs/metadata-legacy/controls/metadata_controls.rb @@ -0,0 +1,5 @@ +control 'test_control_01' do + describe attribute('test_01') do + it { should cmp 'test_value_01' } + end +end \ No newline at end of file diff --git a/test/unit/mock/profiles/inputs/metadata-legacy/inspec.yml b/test/unit/mock/profiles/inputs/metadata-legacy/inspec.yml new file mode 100644 index 000000000..ab8678007 --- /dev/null +++ b/test/unit/mock/profiles/inputs/metadata-legacy/inspec.yml @@ -0,0 +1,12 @@ +name: metadata_legacy +title: InSpec Profile +maintainer: The Authors +copyright: The Authors +copyright_email: you@example.com +license: Apache-2.0 +summary: A profile with a single simple input defined in metadata, using the attributes key +version: 0.1.0 + +attributes: # Use legacy "attributes" key +- name: test_01 + value: test_value_01 \ No newline at end of file