diff --git a/docs-chef-io/content/inspec/cli.md b/docs-chef-io/content/inspec/cli.md index 605232e96..4fb073c5d 100644 --- a/docs-chef-io/content/inspec/cli.md +++ b/docs-chef-io/content/inspec/cli.md @@ -31,6 +31,10 @@ This subcommand has the following additional options: * ``--airgap``, ``--no-airgap`` Fallback to using local archives if fetching fails. +* ``--check``, ``--no-check`` + Before running archive, run `inspec check`. Default: do not check. +* ``--export``, ``--no-check`` + Include an inspec.json file in the archive, the results of running `inspec export`. * ``--ignore-errors``, ``--no-ignore-errors`` Ignore profile warnings. * ``-o``, ``--output=OUTPUT`` diff --git a/lib/inspec/cli.rb b/lib/inspec/cli.rb index c7be4fd68..5e40e8f48 100644 --- a/lib/inspec/cli.rb +++ b/lib/inspec/cli.rb @@ -189,6 +189,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI desc: "Fallback to using local archives if fetching fails." option :ignore_errors, type: :boolean, default: false, desc: "Ignore profile warnings." + option :check, type: :boolean, default: false, + desc: "Run profile check before archiving." + option :export, type: :boolean, default: false, + desc: "Export the profile to inspec.json and include in archive" def archive(path) o = config diagnose(o) @@ -203,7 +207,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI vendor_deps(path, vendor_options) profile = Inspec::Profile.for_target(path, o) - result = profile.check + result = profile.check if o[:check] if result && !o[:ignore_errors] == false o[:logger].info "Profile check failed. Please fix the profile before generating an archive." diff --git a/lib/inspec/profile.rb b/lib/inspec/profile.rb index 1a2fafde1..18c533b73 100644 --- a/lib/inspec/profile.rb +++ b/lib/inspec/profile.rb @@ -617,7 +617,6 @@ module Inspec end # generates a archive of a folder profile - # assumes that the profile was checked before def archive(opts) # check if file exists otherwise overwrite the archive dst = archive_name(opts) @@ -634,31 +633,34 @@ module Inspec # TODO ignore all .files, but add the files to debug output # Generate temporary inspec.json for archive - Inspec::Utils::JsonProfileSummary.produce_json( - info: info, - write_path: "#{root_path}inspec.json", - suppress_output: true - ) + if opts[:export] + Inspec::Utils::JsonProfileSummary.produce_json( + info: info, # TODO: conditionalize and call info_from_parse + write_path: "#{root_path}inspec.json", + suppress_output: true + ) + end # display all files that will be part of the archive @logger.debug "Add the following files to archive:" files.each { |f| @logger.debug " " + f } - @logger.debug " inspec.json" + @logger.debug " inspec.json" if opts[:export] + archive_files = opts[:export] ? files.push("inspec.json") : files if opts[:zip] # generate zip archive require "inspec/archive/zip" zag = Inspec::Archive::ZipArchiveGenerator.new - zag.archive(root_path, files.push("inspec.json"), dst) + zag.archive(root_path, archive_files, dst) else # generate tar archive require "inspec/archive/tar" tag = Inspec::Archive::TarArchiveGenerator.new - tag.archive(root_path, files.push("inspec.json"), dst) + tag.archive(root_path, archive_files, dst) end # Cleanup - FileUtils.rm_f("#{root_path}inspec.json") + FileUtils.rm_f("#{root_path}inspec.json") if opts[:export] @logger.info "Finished archive generation." true diff --git a/test/fixtures/profiles/eval-markers/controls/markers.rb b/test/fixtures/profiles/eval-markers/controls/markers.rb new file mode 100644 index 000000000..43a5344a7 --- /dev/null +++ b/test/fixtures/profiles/eval-markers/controls/markers.rb @@ -0,0 +1,15 @@ +# This profile emits markers to STDERR at various points to indicate that it was evaluated + +$stderr.puts "TOP_LEVEL_MARKER" +$stderr.puts "EVALUATION_MARKER" +control "my-dummy-control" do + $stderr.puts "CONTROL_BODY_MARKER" + title "#{$stderr.puts "METADATA_MARKER"}" + describe true do + $stderr.puts "DESCRIBE_BODY_MARKER" + it do + $stderr.puts "IT_BODY_MARKER" + should be_truthy + end + end +end \ No newline at end of file diff --git a/test/fixtures/profiles/eval-markers/inspec.yml b/test/fixtures/profiles/eval-markers/inspec.yml new file mode 100644 index 000000000..0b5b5619c --- /dev/null +++ b/test/fixtures/profiles/eval-markers/inspec.yml @@ -0,0 +1,10 @@ +name: eval-markers +title: InSpec Profile +maintainer: The Authors +copyright: The Authors +copyright_email: you@example.com +license: Apache-2.0 +summary: A profile that emits to STDERR at various points +version: 0.1.0 +supports: + platform: os \ No newline at end of file diff --git a/test/functional/inspec_archive_test.rb b/test/functional/inspec_archive_test.rb index fe2b48dbf..464897adf 100644 --- a/test/functional/inspec_archive_test.rb +++ b/test/functional/inspec_archive_test.rb @@ -31,13 +31,24 @@ describe "inspec archive" do end end - it "archives an inspec.json file" do + it "archives an inspec.json file if export if provided --export option" do + prepare_examples("profile") do |dir| + out = inspec("archive " + dir + " --overwrite --export") + + _(out.stderr).must_equal "" + t = Zlib::GzipReader.open(auto_dst) + _(Gem::Package::TarReader.new(t).entries.map(&:header).map(&:name)).must_include "inspec.json" + assert_exit_code 0, out + end + end + + it "does not archive an inspec.json file by default" do prepare_examples("profile") do |dir| out = inspec("archive " + dir + " --overwrite") _(out.stderr).must_equal "" t = Zlib::GzipReader.open(auto_dst) - _(Gem::Package::TarReader.new(t).entries.map(&:header).map(&:name)).must_include "inspec.json" + _(Gem::Package::TarReader.new(t).entries.map(&:header).map(&:name)).wont_include "inspec.json" assert_exit_code 0, out end end @@ -127,4 +138,18 @@ describe "inspec archive" do assert_exit_code 0, out end end + + it "does not evaluate a profile by default" do + eval_marker_path = File.join(profile_path, "eval-markers") + + Dir.mktmpdir do |tmpdir| + FileUtils.cp_r(eval_marker_path + "/.", tmpdir) + + out = inspec("archive " + tmpdir + " --output " + dst.path) + + _(out.stderr).wont_include "EVALUATION_MARKER" + _(out.stderr).must_equal "" + assert_exit_code 0, out + end + end end