feature: --output on archive

This commit is contained in:
Dominik Richter 2016-03-16 19:18:17 +01:00
parent a5e289b591
commit 0218f1f3ca
3 changed files with 93 additions and 21 deletions

View file

@ -75,6 +75,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
desc 'archive PATH', 'archive a profile to tar.gz (default) or zip' desc 'archive PATH', 'archive a profile to tar.gz (default) or zip'
profile_options profile_options
option :output, aliases: :o, type: :string,
desc: 'Save the archive to a path'
option :zip, type: :boolean, default: false, option :zip, type: :boolean, default: false,
desc: 'Generates a zip archive.' desc: 'Generates a zip archive.'
option :tar, type: :boolean, default: false, option :tar, type: :boolean, default: false,

View file

@ -173,26 +173,17 @@ module Inspec
# generates a archive of a folder profile # generates a archive of a folder profile
# assumes that the profile was checked before # assumes that the profile was checked before
def archive(opts) # rubocop:disable Metrics/AbcSize def archive(opts)
profile_name = params[:name]
ext = opts[:zip] ? 'zip' : 'tar.gz'
if opts[:archive]
archive = Pathname.new(opts[:archive])
else
slug = profile_name.downcase.strip.tr(' ', '-').gsub(/[^\w-]/, '_')
archive = Pathname.new(Dir.pwd).join("#{slug}.#{ext}")
end
# check if file exists otherwise overwrite the archive # check if file exists otherwise overwrite the archive
if archive.exist? && !opts[:overwrite] dst = archive_name(opts)
@logger.info "Archive #{archive} exists already. Use --overwrite." if dst.exist? && !opts[:overwrite]
@logger.info "Archive #{dst} exists already. Use --overwrite."
return false return false
end end
# remove existing archive # remove existing archive
File.delete(archive) if archive.exist? File.delete(dst) if dst.exist?
@logger.info "Generate archive #{archive}." @logger.info "Generate archive #{dst}."
# filter files that should not be part of the profile # filter files that should not be part of the profile
# TODO ignore all .files, but add the files to debug output # TODO ignore all .files, but add the files to debug output
@ -207,12 +198,12 @@ module Inspec
# generate zip archive # generate zip archive
require 'inspec/archive/zip' require 'inspec/archive/zip'
zag = Inspec::Archive::ZipArchiveGenerator.new zag = Inspec::Archive::ZipArchiveGenerator.new
zag.archive(root_path, files, archive) zag.archive(root_path, files, dst)
else else
# generate tar archive # generate tar archive
require 'inspec/archive/tar' require 'inspec/archive/tar'
tag = Inspec::Archive::TarArchiveGenerator.new tag = Inspec::Archive::TarArchiveGenerator.new
tag.archive(root_path, files, archive) tag.archive(root_path, files, dst)
end end
@logger.info 'Finished archive generation.' @logger.info 'Finished archive generation.'
@ -221,6 +212,24 @@ module Inspec
private private
# Create an archive name for this profile and an additional options
# configuration. Either use :output or generate the name from metadata.
#
# @param [Hash] configuration options
# @return [Pathname] path for the archive
def archive_name(opts)
if (name = opts[:output])
return Pathname.new(name)
end
name = params[:name] ||
fail('Cannot create an archive without a profile name! Please '\
'specify the name in metadata or use --output to create the archive.')
ext = opts[:zip] ? 'zip' : 'tar.gz'
slug = name.downcase.strip.tr(' ', '-').gsub(/[^\w-]/, '_')
Pathname.new(Dir.pwd).join("#{slug}.#{ext}")
end
def load_params def load_params
params = @source_reader.metadata.params params = @source_reader.metadata.params
params[:name] = @profile_id unless @profile_id.nil? params[:name] = @profile_id unless @profile_id.nil?

View file

@ -18,6 +18,13 @@ describe 'Inspec::InspecCLI' do
let(:exec_inspec) { File.join(repo_path, 'bin', 'inspec') } let(:exec_inspec) { File.join(repo_path, 'bin', 'inspec') }
let(:profile_path) { File.join(repo_path, 'test', 'unit', 'mock', 'profiles') } let(:profile_path) { File.join(repo_path, 'test', 'unit', 'mock', 'profiles') }
let(:examples_path) { File.join(repo_path, 'examples') } let(:examples_path) { File.join(repo_path, 'examples') }
let(:dst) {
# create a temporary path, but we only want an auto-clean helper
# so remove the file and give back the path
res = Tempfile.new('inspec-shred')
FileUtils.rm(res.path)
res
}
def inspec(commandline) def inspec(commandline)
CMD.run_command("#{exec_inspec} #{commandline}") CMD.run_command("#{exec_inspec} #{commandline}")
@ -38,6 +45,54 @@ describe 'Inspec::InspecCLI' do
out.stdout.must_match /Generate archive [^ ]*profile.tar.gz/ out.stdout.must_match /Generate archive [^ ]*profile.tar.gz/
out.stdout.must_include 'Finished archive generation.' out.stdout.must_include 'Finished archive generation.'
end end
it 'archives to output file' do
out = inspec('archive ' + path + ' --output ' + dst.path)
out.stderr.must_equal ''
out.stdout.must_include 'Generate archive '+dst.path
out.stdout.must_include 'Finished archive generation.'
out.exit_status.must_equal 0
File.exist?(dst.path).must_equal true
end
it 'auto-archives when no --output is given' do
auto_dst = File.join(repo_path, 'profile.tar.gz')
out = inspec('archive ' + path + ' --overwrite')
out.stderr.must_equal ''
out.stdout.must_include 'Generate archive '+auto_dst
out.stdout.must_include 'Finished archive generation.'
out.exit_status.must_equal 0
File.exist?(auto_dst).must_equal true
end
it 'archive on invalid archive' do
out = inspec('archive /proc --output ' + dst.path)
# out.stdout.must_equal '' => we have partial stdout output right now
out.stderr.must_include "Don't understand inspec profile in \"/proc\""
out.exit_status.must_equal 1
File.exist?(dst.path).must_equal false
end
it 'archive wont overwrite existing files' do
x = rand.to_s
File.write(dst.path, x)
out = inspec('archive ' + path + ' --output ' + dst.path)
out.stderr.must_equal '' # uh...
out.stdout.must_include "Archive #{dst.path} exists already. Use --overwrite."
out.exit_status.must_equal 1
File.read(dst.path).must_equal x
end
it 'archive will overwrite files if necessary' do
x = rand.to_s
File.write(dst.path, x)
out = inspec('archive ' + path + ' --output ' + dst.path + ' --overwrite')
out.stderr.must_equal '' # uh...
out.stdout.must_include 'Generate archive '+dst.path
out.exit_status.must_equal 0
File.read(dst.path).wont_equal x
end
end end
describe 'example inheritance profile' do describe 'example inheritance profile' do
@ -46,26 +101,32 @@ describe 'Inspec::InspecCLI' do
it 'check fails without --profiles-path' do it 'check fails without --profiles-path' do
out = inspec('check ' + path) out = inspec('check ' + path)
out.stderr.must_include 'You must supply a --profiles-path to inherit' out.stderr.must_include 'You must supply a --profiles-path to inherit'
out.stdout.must_equal ''
out.exit_status.must_equal 1 out.exit_status.must_equal 1
end end
it 'check succeeds with --profiles-path' do it 'check succeeds with --profiles-path' do
out = inspec('check ' + path + ' --profiles-path ' + examples_path) out = inspec('check ' + path + ' --profiles-path ' + examples_path)
out.stderr.must_equal ''
out.stdout.must_match /Valid.*true/ out.stdout.must_match /Valid.*true/
out.exit_status.must_equal 0 out.exit_status.must_equal 0
end end
it 'archive fails without --profiles-path' do it 'archive fails without --profiles-path' do
out = inspec('archive ' + path + ' --overwrite') out = inspec('archive ' + path + ' --output ' + dst.path)
# out.stdout.must_equal '' => we have partial stdout output right now
out.stderr.must_include 'You must supply a --profiles-path to inherit' out.stderr.must_include 'You must supply a --profiles-path to inherit'
out.exit_status.must_equal 1 out.exit_status.must_equal 1
File.exist?(dst.path).must_equal false
end end
it 'archive is successful with --profiles-path' do it 'archive is successful with --profiles-path' do
out = inspec('archive ' + path + ' --overwrite --profiles-path ' + examples_path) out = inspec('archive ' + path + ' --output ' + dst.path + ' --profiles-path ' + examples_path)
out.exit_status.must_equal 0 out.stderr.must_equal ''
out.stdout.must_match /Generate archive [^ ]*inheritance.tar.gz/ out.stdout.must_include 'Generate archive '+dst.path
out.stdout.must_include 'Finished archive generation.' out.stdout.must_include 'Finished archive generation.'
out.exit_status.must_equal 0
File.exist?(dst.path).must_equal true
end end
end end
end end