mirror of
https://github.com/inspec/inspec
synced 2024-11-10 07:04:15 +00:00
move CLI components to lib/inspec/cli
This makes it easier for other applications to include this component. require from bin/inspec just doesnt behave (or needs workarounds)
This commit is contained in:
parent
3d19eb7394
commit
641572ec7f
2 changed files with 162 additions and 157 deletions
158
bin/inspec
158
bin/inspec
|
@ -4,162 +4,6 @@
|
|||
# author: Dominik Richter
|
||||
# author: Christoph Hartmann
|
||||
|
||||
require 'thor'
|
||||
require 'json'
|
||||
require 'pp'
|
||||
require_relative '../lib/utils/base_cli'
|
||||
require_relative '../lib/inspec'
|
||||
require_relative '../lib/utils/json_log'
|
||||
|
||||
class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
||||
class_option :diagnose, type: :boolean,
|
||||
desc: 'Show diagnostics (versions, configurations)'
|
||||
|
||||
desc 'json PATH', 'read all tests in PATH and generate a JSON summary'
|
||||
option :id, type: :string,
|
||||
desc: 'Attach a profile ID to all test results'
|
||||
option :output, aliases: :o, type: :string,
|
||||
desc: 'Save the created profile to a path'
|
||||
profile_options
|
||||
def json(target)
|
||||
diagnose
|
||||
o = opts.dup
|
||||
o[:ignore_supports] = true
|
||||
|
||||
profile = Inspec::Profile.for_target(target, o)
|
||||
dst = o[:output].to_s
|
||||
if dst.empty?
|
||||
puts JSON.pretty_generate(profile.info)
|
||||
else
|
||||
if File.exist? dst
|
||||
puts "----> updating #{dst}"
|
||||
else
|
||||
puts "----> creating #{dst}"
|
||||
end
|
||||
fdst = File.expand_path(dst)
|
||||
File.write(fdst, JSON.dump(profile.info))
|
||||
end
|
||||
end
|
||||
|
||||
desc 'check PATH', 'verify all tests at the specified PATH'
|
||||
option :format, type: :string
|
||||
profile_options
|
||||
def check(path) # rubocop:disable Metrics/AbcSize
|
||||
diagnose
|
||||
o = opts.dup
|
||||
# configure_logger(o) # we do not need a logger for check yet
|
||||
o[:ignore_supports] = true # we check for integrity only
|
||||
|
||||
# run check
|
||||
profile = Inspec::Profile.for_target(path, o)
|
||||
result = profile.check
|
||||
|
||||
if opts['format'] == 'json'
|
||||
puts JSON.generate(result)
|
||||
else
|
||||
headline('Summary')
|
||||
%w{location profile controls timestamp valid}.each { |item|
|
||||
puts "#{mark_text(item.to_s.capitalize + ':')} #{result[:summary][item.to_sym]}"
|
||||
}
|
||||
puts
|
||||
|
||||
%w{errors warnings}.each { |list|
|
||||
headline(list.to_s.capitalize)
|
||||
result[list.to_sym].each { |item|
|
||||
puts "#{item[:file]}:#{item[:line]}:#{item[:column]}: #{item[:msg]} "
|
||||
}
|
||||
puts
|
||||
}
|
||||
end
|
||||
exit 1 unless result[:summary][:valid]
|
||||
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 = opts.dup
|
||||
o[:logger] = Logger.new(STDOUT)
|
||||
o[:logger].level = get_log_level(o.log_level)
|
||||
|
||||
profile = Inspec::Profile.for_target(path, o)
|
||||
result = profile.check
|
||||
|
||||
if result && !opts[:ignore_errors] == false
|
||||
@logger.info 'Profile check failed. Please fix the profile before generating an archive.'
|
||||
return exit 1
|
||||
end
|
||||
|
||||
# generate archive
|
||||
exit 1 unless profile.archive(opts)
|
||||
end
|
||||
|
||||
desc 'exec PATHS', 'run all test files at the specified PATH.'
|
||||
exec_options
|
||||
def exec(*targets)
|
||||
diagnose
|
||||
run_tests(targets, opts)
|
||||
end
|
||||
|
||||
desc 'detect', 'detect the target OS'
|
||||
target_options
|
||||
def detect
|
||||
diagnose
|
||||
|
||||
rel = File.join(File.dirname(__FILE__), *%w{.. lib utils detect.rb})
|
||||
detect_util = File.expand_path(rel)
|
||||
# exits on execution:
|
||||
runner = Inspec::Runner.new(opts)
|
||||
profile = Inspec::Profile.for_target(detect_util, opts)
|
||||
runner.add_profile(profile)
|
||||
exit runner.run
|
||||
rescue RuntimeError => e
|
||||
puts e.message
|
||||
end
|
||||
|
||||
desc 'shell', 'open an interactive debugging shell'
|
||||
target_options
|
||||
option :format, type: :string, default: Inspec::NoSummaryFormatter, hide: true
|
||||
def shell_func
|
||||
diagnose
|
||||
o = opts.dup
|
||||
o[:logger] = Logger.new(STDOUT)
|
||||
o[:logger].level = get_log_level(o.log_level)
|
||||
|
||||
runner = Inspec::Runner.new(o)
|
||||
Inspec::Shell.new(runner).start
|
||||
rescue RuntimeError => e
|
||||
puts e.message
|
||||
end
|
||||
|
||||
desc 'version', 'prints the version of this tool'
|
||||
def version
|
||||
puts Inspec::VERSION
|
||||
end
|
||||
end
|
||||
|
||||
# Load all plugins on startup
|
||||
ctl = Inspec::PluginCtl.new
|
||||
ctl.list.each { |x| ctl.load(x) }
|
||||
|
||||
# load CLI plugins before the Inspec CLI has been started
|
||||
Inspec::Plugins::CLI.subcommands.each { |_subcommand, params|
|
||||
Inspec::InspecCLI.register(
|
||||
params[:klass],
|
||||
params[:subcommand_name],
|
||||
params[:usage],
|
||||
params[:description],
|
||||
params[:options],
|
||||
)
|
||||
}
|
||||
|
||||
# start the CLI
|
||||
require_relative '../lib/inspec/cli'
|
||||
Inspec::InspecCLI.start(ARGV)
|
||||
|
|
161
lib/inspec/cli.rb
Normal file
161
lib/inspec/cli.rb
Normal file
|
@ -0,0 +1,161 @@
|
|||
#!/usr/bin/env ruby
|
||||
# encoding: utf-8
|
||||
# Copyright 2015 Dominik Richter. All rights reserved.
|
||||
# author: Dominik Richter
|
||||
# author: Christoph Hartmann
|
||||
|
||||
require 'thor'
|
||||
require 'json'
|
||||
require 'pp'
|
||||
require 'utils/base_cli'
|
||||
require 'utils/json_log'
|
||||
|
||||
class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
||||
class_option :diagnose, type: :boolean,
|
||||
desc: 'Show diagnostics (versions, configurations)'
|
||||
|
||||
desc 'json PATH', 'read all tests in PATH and generate a JSON summary'
|
||||
option :id, type: :string,
|
||||
desc: 'Attach a profile ID to all test results'
|
||||
option :output, aliases: :o, type: :string,
|
||||
desc: 'Save the created profile to a path'
|
||||
profile_options
|
||||
def json(target)
|
||||
diagnose
|
||||
o = opts.dup
|
||||
o[:ignore_supports] = true
|
||||
|
||||
profile = Inspec::Profile.for_target(target, o)
|
||||
dst = o[:output].to_s
|
||||
if dst.empty?
|
||||
puts JSON.pretty_generate(profile.info)
|
||||
else
|
||||
if File.exist? dst
|
||||
puts "----> updating #{dst}"
|
||||
else
|
||||
puts "----> creating #{dst}"
|
||||
end
|
||||
fdst = File.expand_path(dst)
|
||||
File.write(fdst, JSON.dump(profile.info))
|
||||
end
|
||||
end
|
||||
|
||||
desc 'check PATH', 'verify all tests at the specified PATH'
|
||||
option :format, type: :string
|
||||
profile_options
|
||||
def check(path) # rubocop:disable Metrics/AbcSize
|
||||
diagnose
|
||||
o = opts.dup
|
||||
# configure_logger(o) # we do not need a logger for check yet
|
||||
o[:ignore_supports] = true # we check for integrity only
|
||||
|
||||
# run check
|
||||
profile = Inspec::Profile.for_target(path, o)
|
||||
result = profile.check
|
||||
|
||||
if opts['format'] == 'json'
|
||||
puts JSON.generate(result)
|
||||
else
|
||||
headline('Summary')
|
||||
%w{location profile controls timestamp valid}.each { |item|
|
||||
puts "#{mark_text(item.to_s.capitalize + ':')} #{result[:summary][item.to_sym]}"
|
||||
}
|
||||
puts
|
||||
|
||||
%w{errors warnings}.each { |list|
|
||||
headline(list.to_s.capitalize)
|
||||
result[list.to_sym].each { |item|
|
||||
puts "#{item[:file]}:#{item[:line]}:#{item[:column]}: #{item[:msg]} "
|
||||
}
|
||||
puts
|
||||
}
|
||||
end
|
||||
exit 1 unless result[:summary][:valid]
|
||||
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 = opts.dup
|
||||
o[:logger] = Logger.new(STDOUT)
|
||||
o[:logger].level = get_log_level(o.log_level)
|
||||
|
||||
profile = Inspec::Profile.for_target(path, o)
|
||||
result = profile.check
|
||||
|
||||
if result && !opts[:ignore_errors] == false
|
||||
@logger.info 'Profile check failed. Please fix the profile before generating an archive.'
|
||||
return exit 1
|
||||
end
|
||||
|
||||
# generate archive
|
||||
exit 1 unless profile.archive(opts)
|
||||
end
|
||||
|
||||
desc 'exec PATHS', 'run all test files at the specified PATH.'
|
||||
exec_options
|
||||
def exec(*targets)
|
||||
diagnose
|
||||
run_tests(targets, opts)
|
||||
end
|
||||
|
||||
desc 'detect', 'detect the target OS'
|
||||
target_options
|
||||
def detect
|
||||
diagnose
|
||||
|
||||
rel = File.join(File.dirname(__FILE__), *%w{.. lib utils detect.rb})
|
||||
detect_util = File.expand_path(rel)
|
||||
# exits on execution:
|
||||
runner = Inspec::Runner.new(opts)
|
||||
profile = Inspec::Profile.for_target(detect_util, opts)
|
||||
runner.add_profile(profile)
|
||||
exit runner.run
|
||||
rescue RuntimeError => e
|
||||
puts e.message
|
||||
end
|
||||
|
||||
desc 'shell', 'open an interactive debugging shell'
|
||||
target_options
|
||||
option :format, type: :string, default: Inspec::NoSummaryFormatter, hide: true
|
||||
def shell_func
|
||||
diagnose
|
||||
o = opts.dup
|
||||
o[:logger] = Logger.new(STDOUT)
|
||||
o[:logger].level = get_log_level(o.log_level)
|
||||
|
||||
runner = Inspec::Runner.new(o)
|
||||
Inspec::Shell.new(runner).start
|
||||
rescue RuntimeError => e
|
||||
puts e.message
|
||||
end
|
||||
|
||||
desc 'version', 'prints the version of this tool'
|
||||
def version
|
||||
puts Inspec::VERSION
|
||||
end
|
||||
end
|
||||
|
||||
# Load all plugins on startup
|
||||
ctl = Inspec::PluginCtl.new
|
||||
ctl.list.each { |x| ctl.load(x) }
|
||||
|
||||
# load CLI plugins before the Inspec CLI has been started
|
||||
Inspec::Plugins::CLI.subcommands.each { |_subcommand, params|
|
||||
Inspec::InspecCLI.register(
|
||||
params[:klass],
|
||||
params[:subcommand_name],
|
||||
params[:usage],
|
||||
params[:description],
|
||||
params[:options],
|
||||
)
|
||||
}
|
Loading…
Reference in a new issue