feature: generate profile archive

This commit is contained in:
Christoph Hartmann 2015-12-12 22:47:04 +01:00 committed by Dominik Richter
parent 9da0e32f3d
commit 27150e5341
4 changed files with 130 additions and 0 deletions

View file

@ -77,6 +77,25 @@ class InspecCLI < Thor # rubocop:disable Metrics/ClassLength
exit 1 unless profile.check
end
desc 'archive PATH', 'archive a profile to tar.gz (default) or zip'
option :zip, type: :boolean, default: false,
desc: 'Generates a zip archive.'
option :tar, type: :boolean, default: false,
desc: 'Generates a tar.gz archive.'
option :overwrite, type: :boolean, default: false,
desc: 'Overwrite existing archive.'
option :ignore_errors, type: :boolean, default: false,
desc: 'Ignore profile warnings.'
def archive(path)
diagnose
o = options.dup
o[:logger] = Logger.new(STDOUT)
profile = Inspec::Profile.from_path(path, o)
# generate archive
exit 1 unless profile.archive(opts)
end
desc 'exec PATHS', 'run all test files at the specified PATH.'
option :id, type: :string,
desc: 'Attach a profile ID to all test results'

31
lib/inspec/archive/tar.rb Normal file
View file

@ -0,0 +1,31 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
require 'rubygems/package'
module Inspec::Archive
class TarArchiveGenerator
def archive(base_dir, files, archive)
File.open(archive, "wb") do |file|
Zlib::GzipWriter.wrap(file) do |gz|
Gem::Package::TarWriter.new(gz) do |tar|
files.each do |input_filename|
path = Pathname.new(base_dir).join(input_filename)
stat = File.stat(path)
if path.directory?
tar.mkdir(input_filename, stat.mode)
else
tar.add_file_simple(input_filename,
stat.mode, stat.size
) do |io|
io.write(File.read(path))
end
end
end
end
end
end
end
end
end

19
lib/inspec/archive/zip.rb Normal file
View file

@ -0,0 +1,19 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
require 'rubygems'
require 'zip'
require 'pathname'
module Inspec::Archive
class ZipArchiveGenerator
def archive(base_dir, files, archive)
Zip::File.open(archive, Zip::File::CREATE) do |zipfile|
files.each do |input_filename|
zipfile.add(input_filename, Pathname.new(base_dir).join(input_filename))
end
end
end
end
end

View file

@ -32,11 +32,15 @@ module Inspec
@metadata = read_metadata
@params = @metadata.params unless @metadata.nil?
# use the id from parameter, name or fallback to nil
@profile_id = options[:id] || @metadata.params[:name] || nil
@params[:rules] = rules = {}
@runner = Runner.new(
id: @profile_id,
backend: :mock,
)
@runner.add_tests([@path])
@runner.rules.each do |id, rule|
file = rule.instance_variable_get(:@__file)
@ -121,6 +125,63 @@ module Inspec
no_errors
end
# generates a archive of a folder profile
def archive(opts)
check_result = check
if check_result && !opts.ignore_errors == false then
@logger.info 'Profile check failed. Please fix the profile before generating an archive.'
return false
end
profile_name = @params[:name]
opts[:zip] ? ext='zip' : ext='tar.gz'
slug = profile_name.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '_')
archive = Pathname.new(File.dirname(__FILE__)).join("../..","#{slug}.#{ext}")
# check if file exists otherwise overwrite the archive
if archive.exist? && !opts[:overwrite]
@logger.info "Archive #{archive} exists already. Use --overwrite."
return false
end
# remove existing archive
File.delete(archive) if archive.exist?
@logger.info "Profile check finished. Generate archive #{archive}."
# find all files
files = Dir.glob("#{path}/**/*")
# filter files that should not be part of the profile
# TODO ignore all .files, but add the files to debug output
# map absolute paths to relative paths
files = files.collect { |f| Pathname.new(f).relative_path_from(Pathname.new(path)).to_s }
# display all files that will be part of the archive
@logger.debug "Add the following files to archive:"
files.each { |f|
@logger.debug " " + f
}
# generate zip archive
if opts[:zip]
require 'inspec/archive/zip'
zag = Inspec::Archive::ZipArchiveGenerator.new
zag.archive(path, files, archive)
else
# generate tar archive
require 'inspec/archive/tar'
tag = Inspec::Archive::TarArchiveGenerator.new
tag.archive(path, files, archive)
end
@logger.info "Finished archive generation."
true
end
private
def read_metadata