diff --git a/lib/inspec/base_cli.rb b/lib/inspec/base_cli.rb index 864f8df0c..53ab15324 100644 --- a/lib/inspec/base_cli.rb +++ b/lib/inspec/base_cli.rb @@ -62,6 +62,8 @@ module Inspec desc: 'Specifies the bastion port if applicable' option :insecure, type: :boolean, default: false, desc: 'Disable SSL verification on select targets' + option :target_id, type: :string, + desc: 'Provide a ID which will be included on reports' end def self.profile_options @@ -142,6 +144,7 @@ module Inspec 'file' => target, 'stdout' => false, } + reports[reporter_name]['target_id'] = opts['target_id'] if opts['target_id'] end end opts['reporter'] = reports @@ -152,6 +155,7 @@ module Inspec opts['reporter'].each do |reporter_name, config| opts['reporter'][reporter_name] = {} if config.nil? opts['reporter'][reporter_name]['stdout'] = true if opts['reporter'][reporter_name].empty? + opts['reporter'][reporter_name]['target_id'] = opts['target_id'] if opts['target_id'] end end diff --git a/lib/inspec/formatters/base.rb b/lib/inspec/formatters/base.rb index b11cf433a..a9ee6ddfb 100644 --- a/lib/inspec/formatters/base.rb +++ b/lib/inspec/formatters/base.rb @@ -69,7 +69,6 @@ module Inspec::Formatters name: platform(:name), release: platform(:release), target: backend_target, - uuid: platform(:uuid), } end diff --git a/lib/inspec/reporters/automate.rb b/lib/inspec/reporters/automate.rb index d16acb9d6..74b55d037 100644 --- a/lib/inspec/reporters/automate.rb +++ b/lib/inspec/reporters/automate.rb @@ -23,7 +23,7 @@ module Inspec::Reporters final_report[:type] = 'inspec_report' final_report[:end_time] = Time.now.utc.strftime('%FT%TZ') - final_report[:node_uuid] = @config['node_uuid'] || @run_data[:platform][:uuid] + final_report[:node_uuid] = @config['node_uuid'] || @config['target_id'] raise Inspec::ReporterError, 'Cannot find a UUID for your node. Please specify one via json-config.' if final_report[:node_uuid].nil? final_report[:report_uuid] = @config['report_uuid'] || uuid_from_string(final_report[:end_time] + final_report[:node_uuid]) diff --git a/lib/inspec/reporters/cli.rb b/lib/inspec/reporters/cli.rb index ebcac60fc..e7fb5beb9 100644 --- a/lib/inspec/reporters/cli.rb +++ b/lib/inspec/reporters/cli.rb @@ -63,9 +63,17 @@ module Inspec::Reporters private def print_profile_header(profile) - output("Profile: #{format_profile_name(profile)}") - output("Version: #{profile[:version] || '(not specified)'}") - output("Target: #{run_data[:platform][:target]}") unless run_data[:platform][:target].nil? + header = { + 'Profile' => format_profile_name(profile), + 'Version' => profile[:version] || '(not specified)', + } + header['Target'] = run_data[:platform][:target] unless run_data[:platform][:target].nil? + header['Target ID'] = @config['target_id'] unless @config['target_id'].nil? + + pad = header.keys.max_by(&:length).length + 1 + header.each do |title, value| + output(format("%-#{pad}s %s", title + ':', value)) + end output('') end diff --git a/lib/inspec/reporters/json.rb b/lib/inspec/reporters/json.rb index 6d81e96a8..6bb77ea55 100644 --- a/lib/inspec/reporters/json.rb +++ b/lib/inspec/reporters/json.rb @@ -22,10 +22,12 @@ module Inspec::Reporters private def platform - { + platform = { name: run_data[:platform][:name], release: run_data[:platform][:release], } + platform[:target_id] = @config['target_id'] if @config['target_id'] + platform end def profile_results(control) diff --git a/lib/inspec/schema.rb b/lib/inspec/schema.rb index 03226a4aa..7e3feea0d 100644 --- a/lib/inspec/schema.rb +++ b/lib/inspec/schema.rb @@ -42,6 +42,7 @@ module Inspec 'properties' => { 'name' => { 'type' => 'string' }, 'release' => { 'type' => 'string' }, + 'target_id' => { 'type' => 'string', 'optional' => true }, }, }.freeze diff --git a/test/functional/inspec_exec_json_test.rb b/test/functional/inspec_exec_json_test.rb index b76459f9a..a8b52f3f3 100644 --- a/test/functional/inspec_exec_json_test.rb +++ b/test/functional/inspec_exec_json_test.rb @@ -28,6 +28,17 @@ describe 'inspec exec with json formatter' do JSON::Schema.validate(data, schema) end + it 'can execute a profile and validate the json schema with target_id' do + out = inspec('exec ' + example_profile + ' --reporter json --no-create-lockfile --target-id 1d3e399f-4d71-4863-ac54-84d437fbc444') + out.stderr.must_equal '' + out.exit_status.must_equal 101 + data = JSON.parse(out.stdout) + data['platform']['target_id'].must_equal '1d3e399f-4d71-4863-ac54-84d437fbc444' + sout = inspec('schema exec-json') + schema = JSON.parse(sout.stdout) + JSON::Schema.validate(data, schema) + end + describe 'execute a profile with json formatting' do let(:json) { JSON.load(inspec('exec ' + example_profile + ' --reporter json --no-create-lockfile').stdout) } let(:profile) { json['profiles'][0] } diff --git a/test/functional/inspec_exec_test.rb b/test/functional/inspec_exec_test.rb index d9dd28480..3e604e098 100644 --- a/test/functional/inspec_exec_test.rb +++ b/test/functional/inspec_exec_test.rb @@ -46,6 +46,15 @@ Test Summary: 0 successful, 0 failures, 0 skipped File.stat("#{outpath}/foo/bar/test.json").size.must_be :>, 0 end + it 'can execute the profile with a target_id passthrough' do + outpath = Dir.tmpdir + out = inspec("exec #{example_profile} --no-create-lockfile --target-id 1d3e399f-4d71-4863-ac54-84d437fbc444") + out.stderr.must_equal '' + out.exit_status.must_equal 101 + stdout = out.stdout.force_encoding(Encoding::UTF_8) + stdout.must_include "Target ID: 1d3e399f-4d71-4863-ac54-84d437fbc444" + end + it 'executes a metadata-only profile' do out = inspec('exec ' + File.join(profile_path, 'complete-metadata') + ' --no-create-lockfile') out.stderr.must_equal '' diff --git a/test/unit/base_cli_test.rb b/test/unit/base_cli_test.rb index aaf40de60..68a3ff3f3 100644 --- a/test/unit/base_cli_test.rb +++ b/test/unit/base_cli_test.rb @@ -149,15 +149,22 @@ EOF it 'parse cli reporters' do opts = { 'reporter' => ['cli'] } parsed = Inspec::BaseCLI.parse_reporters(opts) - assert = { 'reporter' => { 'cli' => { 'stdout' => true }}} - parsed.must_equal assert + expected_value = { 'reporter' => { 'cli' => { 'stdout' => true }}} + parsed.must_equal expected_value + end + + it 'parses cli report and attaches target_id' do + opts = { 'reporter' => ['cli'], 'target_id' => '1d3e399f-4d71-4863-ac54-84d437fbc444' } + parsed = Inspec::BaseCLI.parse_reporters(opts) + expected_value = {"reporter"=>{"cli"=>{"stdout"=>true, "target_id"=>"1d3e399f-4d71-4863-ac54-84d437fbc444"}}, "target_id"=>"1d3e399f-4d71-4863-ac54-84d437fbc444"} + parsed.must_equal expected_value end it 'parse cli reporters with format' do opts = { 'format' => 'json' } parsed = Inspec::BaseCLI.parse_reporters(opts) - assert = { 'reporter' => { 'json' => { 'stdout' => true }}} - parsed.must_equal assert + expected_value = { 'reporter' => { 'json' => { 'stdout' => true }}} + parsed.must_equal expected_value end it 'parse cli reporters with format and output' do @@ -166,8 +173,8 @@ EOF proc { opts = { 'format' => 'json', 'output' => '/tmp/inspec_out.json' } parsed = Inspec::BaseCLI.parse_reporters(opts) - assert = { 'reporter' => { 'json' => { 'file' => '/tmp/inspec_out.json', 'stdout' => false }}} - parsed.must_equal assert + expected_value = { 'reporter' => { 'json' => { 'file' => '/tmp/inspec_out.json', 'stdout' => false }}} + parsed.must_equal expected_value }.must_output nil, error end end