mirror of
https://github.com/inspec/inspec
synced 2024-11-11 07:34:15 +00:00
wrap basecli in inspec module
Take care of a rare error which has Inspec undefined
This commit is contained in:
parent
c695885c9d
commit
bb264897f4
1 changed files with 113 additions and 111 deletions
|
@ -4,126 +4,128 @@
|
||||||
|
|
||||||
require 'thor'
|
require 'thor'
|
||||||
|
|
||||||
class Inspec::BaseCLI < Thor # rubocop:disable Metrics/ClassLength
|
module Inspec
|
||||||
def self.target_options
|
class BaseCLI < Thor # rubocop:disable Metrics/ClassLength
|
||||||
option :target, aliases: :t, type: :string,
|
def self.target_options
|
||||||
desc: 'Simple targeting option using URIs, e.g. ssh://user:pass@host:port'
|
option :target, aliases: :t, type: :string,
|
||||||
option :backend, aliases: :b, type: :string,
|
desc: 'Simple targeting option using URIs, e.g. ssh://user:pass@host:port'
|
||||||
desc: 'Choose a backend: local, ssh, winrm, docker.'
|
option :backend, aliases: :b, type: :string,
|
||||||
option :host, type: :string,
|
desc: 'Choose a backend: local, ssh, winrm, docker.'
|
||||||
desc: 'Specify a remote host which is tested.'
|
option :host, type: :string,
|
||||||
option :port, aliases: :p, type: :numeric,
|
desc: 'Specify a remote host which is tested.'
|
||||||
desc: 'Specify the login port for a remote scan.'
|
option :port, aliases: :p, type: :numeric,
|
||||||
option :user, type: :string,
|
desc: 'Specify the login port for a remote scan.'
|
||||||
desc: 'The login user for a remote scan.'
|
option :user, type: :string,
|
||||||
option :password, type: :string,
|
desc: 'The login user for a remote scan.'
|
||||||
desc: 'Login password for a remote scan, if required.'
|
option :password, type: :string,
|
||||||
option :key_files, aliases: :i, type: :array,
|
desc: 'Login password for a remote scan, if required.'
|
||||||
desc: 'Login key or certificate file for a remote scan.'
|
option :key_files, aliases: :i, type: :array,
|
||||||
option :path, type: :string,
|
desc: 'Login key or certificate file for a remote scan.'
|
||||||
desc: 'Login path to use when connecting to the target (WinRM).'
|
option :path, type: :string,
|
||||||
option :sudo, type: :boolean,
|
desc: 'Login path to use when connecting to the target (WinRM).'
|
||||||
desc: 'Run scans with sudo. Only activates on Unix and non-root user.'
|
option :sudo, type: :boolean,
|
||||||
option :sudo_password, type: :string,
|
desc: 'Run scans with sudo. Only activates on Unix and non-root user.'
|
||||||
desc: 'Specify a sudo password, if it is required.'
|
option :sudo_password, type: :string,
|
||||||
option :sudo_options, type: :string,
|
desc: 'Specify a sudo password, if it is required.'
|
||||||
desc: 'Additional sudo options for a remote scan.'
|
option :sudo_options, type: :string,
|
||||||
option :ssl, type: :boolean,
|
desc: 'Additional sudo options for a remote scan.'
|
||||||
desc: 'Use SSL for transport layer encryption (WinRM).'
|
option :ssl, type: :boolean,
|
||||||
option :self_signed, type: :boolean,
|
desc: 'Use SSL for transport layer encryption (WinRM).'
|
||||||
desc: 'Allow remote scans with self-signed certificates (WinRM).'
|
option :self_signed, type: :boolean,
|
||||||
option :json_config, type: :string,
|
desc: 'Allow remote scans with self-signed certificates (WinRM).'
|
||||||
desc: 'Read configuration from JSON file (`-` reads from stdin).'
|
option :json_config, type: :string,
|
||||||
option :log_level, aliases: :l, type: :string,
|
desc: 'Read configuration from JSON file (`-` reads from stdin).'
|
||||||
desc: 'Set the log level: info (default), debug, warn, error'
|
option :log_level, aliases: :l, type: :string,
|
||||||
end
|
desc: 'Set the log level: info (default), debug, warn, error'
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# helper method to run tests
|
|
||||||
def run_tests(opts, tests)
|
|
||||||
o = opts.dup
|
|
||||||
o[:logger] = Logger.new(opts['format'] == 'json' ? nil : STDOUT)
|
|
||||||
o[:logger].level = get_log_level(o.log_level)
|
|
||||||
|
|
||||||
runner = Inspec::Runner.new(o)
|
|
||||||
runner.add_tests(tests)
|
|
||||||
exit runner.run
|
|
||||||
rescue RuntimeError => e
|
|
||||||
puts e.message
|
|
||||||
end
|
|
||||||
|
|
||||||
def diagnose
|
|
||||||
return unless opts['diagnose']
|
|
||||||
puts "InSpec version: #{Inspec::VERSION}"
|
|
||||||
puts "Train version: #{Train::VERSION}"
|
|
||||||
puts 'Command line configuration:'
|
|
||||||
pp options
|
|
||||||
puts 'JSON configuration file:'
|
|
||||||
pp options_json
|
|
||||||
puts 'Merged configuration:'
|
|
||||||
pp opts
|
|
||||||
puts
|
|
||||||
end
|
|
||||||
|
|
||||||
def opts
|
|
||||||
# argv overrides json
|
|
||||||
Thor::CoreExt::HashWithIndifferentAccess.new(options_json.merge(options))
|
|
||||||
end
|
|
||||||
|
|
||||||
def options_json
|
|
||||||
conffile = options['json_config']
|
|
||||||
@json ||= conffile ? read_config(conffile) : {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def read_config(file)
|
|
||||||
if file == '-'
|
|
||||||
puts 'WARN: reading JSON config from standard input' if STDIN.tty?
|
|
||||||
config = STDIN.read
|
|
||||||
else
|
|
||||||
config = File.read(file)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
JSON.load(config)
|
private
|
||||||
rescue JSON::ParserError => e
|
|
||||||
puts "Failed to load JSON configuration: #{e}\nConfig was: #{config.inspect}"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
# get the log level
|
# helper method to run tests
|
||||||
# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
def run_tests(opts, tests)
|
||||||
def get_log_level(level)
|
o = opts.dup
|
||||||
valid = %w{debug info warn error fatal}
|
o[:logger] = Logger.new(opts['format'] == 'json' ? nil : STDOUT)
|
||||||
|
o[:logger].level = get_log_level(o.log_level)
|
||||||
|
|
||||||
if valid.include?(level)
|
runner = Inspec::Runner.new(o)
|
||||||
l = level
|
runner.add_tests(tests)
|
||||||
else
|
exit runner.run
|
||||||
l = 'info'
|
rescue RuntimeError => e
|
||||||
|
puts e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
Logger.const_get(l.upcase)
|
def diagnose
|
||||||
end
|
return unless opts['diagnose']
|
||||||
|
puts "InSpec version: #{Inspec::VERSION}"
|
||||||
def configure_logger(o)
|
puts "Train version: #{Train::VERSION}"
|
||||||
o[:logger] = Logger.new(STDOUT)
|
puts 'Command line configuration:'
|
||||||
# output json if we have activated the json formatter
|
pp options
|
||||||
if opts['log-format'] == 'json'
|
puts 'JSON configuration file:'
|
||||||
o[:logger].formatter = Logger::JSONFormatter.new
|
pp options_json
|
||||||
|
puts 'Merged configuration:'
|
||||||
|
pp opts
|
||||||
|
puts
|
||||||
end
|
end
|
||||||
o[:logger].level = get_log_level(o.log_level)
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_text(text)
|
def opts
|
||||||
"\e[0;32m#{text}\e[0m"
|
# argv overrides json
|
||||||
end
|
Thor::CoreExt::HashWithIndifferentAccess.new(options_json.merge(options))
|
||||||
|
end
|
||||||
|
|
||||||
def headline(title)
|
def options_json
|
||||||
puts title
|
conffile = options['json_config']
|
||||||
title.each_char { print '-' }
|
@json ||= conffile ? read_config(conffile) : {}
|
||||||
puts
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def li(entry)
|
def read_config(file)
|
||||||
puts " #{mark_text('*')} #{entry}"
|
if file == '-'
|
||||||
|
puts 'WARN: reading JSON config from standard input' if STDIN.tty?
|
||||||
|
config = STDIN.read
|
||||||
|
else
|
||||||
|
config = File.read(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
JSON.load(config)
|
||||||
|
rescue JSON::ParserError => e
|
||||||
|
puts "Failed to load JSON configuration: #{e}\nConfig was: #{config.inspect}"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# get the log level
|
||||||
|
# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
||||||
|
def get_log_level(level)
|
||||||
|
valid = %w{debug info warn error fatal}
|
||||||
|
|
||||||
|
if valid.include?(level)
|
||||||
|
l = level
|
||||||
|
else
|
||||||
|
l = 'info'
|
||||||
|
end
|
||||||
|
|
||||||
|
Logger.const_get(l.upcase)
|
||||||
|
end
|
||||||
|
|
||||||
|
def configure_logger(o)
|
||||||
|
o[:logger] = Logger.new(STDOUT)
|
||||||
|
# output json if we have activated the json formatter
|
||||||
|
if opts['log-format'] == 'json'
|
||||||
|
o[:logger].formatter = Logger::JSONFormatter.new
|
||||||
|
end
|
||||||
|
o[:logger].level = get_log_level(o.log_level)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_text(text)
|
||||||
|
"\e[0;32m#{text}\e[0m"
|
||||||
|
end
|
||||||
|
|
||||||
|
def headline(title)
|
||||||
|
puts title
|
||||||
|
title.each_char { print '-' }
|
||||||
|
puts
|
||||||
|
end
|
||||||
|
|
||||||
|
def li(entry)
|
||||||
|
puts " #{mark_text('*')} #{entry}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue