mirror of
https://github.com/inspec/inspec
synced 2024-11-10 23:24:18 +00:00
feature: generate profile archive
This commit is contained in:
parent
9da0e32f3d
commit
27150e5341
4 changed files with 130 additions and 0 deletions
19
bin/inspec
19
bin/inspec
|
@ -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
31
lib/inspec/archive/tar.rb
Normal 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
19
lib/inspec/archive/zip.rb
Normal 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
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue