inspec/lib/bundles/inspec-compliance/cli.rb
Dominik Richter e56321f6c7 semantics: rename CLI plugins registry -> subcommands
Basically make sure everyone understands these are only subcommands. we might consider adding plugins for options or existing commands instead of new subcommands. this just ensures everyone knows what registry is for
2016-02-09 01:20:38 +01:00

146 lines
4.5 KiB
Ruby

# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
require 'thor'
module Compliance
class ComplianceCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
namespace 'compliance'
desc 'login SERVER', 'Log in to a Chef Compliance SERVER'
option :user, type: :string, required: true,
desc: 'Chef Compliance Username'
option :password, type: :string, required: true,
desc: 'Chef Compliance Password'
def login(server)
success, msg = Compliance::API.login(server, options['user'], options['password'])
if success
puts 'Successfully authenticated'
else
puts msg
end
end
desc 'profiles', 'list all available profiles in Chef Compliance'
def profiles
profiles = Compliance::API.profiles
if !profiles.empty?
# iterate over profiles
headline('Available profiles:')
profiles.each { |profile|
li("#{profile[:org]}/#{profile[:name]}")
}
else
puts 'Could not find any profiles'
end
end
desc 'exec PROFILE', 'executes a Chef Compliance profile'
option :id, type: :string,
desc: 'Attach a profile ID to all test results'
target_options
option :format, type: :string
def exec(*tests)
# iterate over tests and add compliance scheme
tests = tests.map { |t| 'compliance://' + t }
# execute profile from inspec exec implementation
diagnose
run_tests(opts, tests)
end
desc 'upload PATH', 'uploads a local profile to Chef Compliance'
option :overwrite, type: :boolean, default: false,
desc: 'Overwrite existing profile on Chef Compliance.'
def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, PerceivedComplexity
o = options.dup
configure_logger(o)
# check the profile, we only allow to upload valid profiles
profile = Inspec::Profile.from_path(path, o)
# start verification process
error_count = 0
error = lambda { |msg|
error_count += 1
puts msg
}
result = profile.check
unless result[:summary][:valid]
error.call('Profile check failed. Please fix the profile before upload.')
else
puts('Profile is valid')
end
# determine user information
config = Compliance::Configuration.new
if config['token'].nil? || config['user'].nil?
error.call('Please login via `inspec compliance login`')
end
# owner
owner = config['user']
# read profile name from inspec.yml
profile_name = profile.params[:name]
# check that the profile is not uploaded already,
# confirm upload to the user (overwrite with --force)
if Compliance::API.exist?("#{owner}/#{profile_name}") && !options['overwrite']
error.call('Profile exists on the server, use --overwrite')
end
# abort if we found an error
if error_count > 0
puts "Found #{error_count} error(s)"
exit 1
end
# if it is a directory, tar it to tmp directory
if File.directory?(path)
file = Tempfile.new([profile_name, '.tar.gz'])
archive_path = file.path
puts "Generate temporary profile archive at #{archive_path}"
profile.archive({ archive: archive_path, ignore_errors: false, overwrite: true })
else
archive_path = path
end
puts "Start upload to #{owner}/#{profile_name}"
# upload the tar to Chef Compliance
url = "#{config['server']}/owners/#{owner}/compliance/#{profile_name}/tar"
puts "Uploading to #{url}"
success, msg = Compliance::API.post_file(url, config['token'], '', archive_path)
if success
puts 'Successfully uploaded profile'
else
puts 'Error during profile upload:'
puts msg
end
end
desc 'version', 'displays the version of the Chef Compliance server'
def version
info = Compliance::API.version
if !info.nil? && info['version']
puts "Chef Compliance version: #{info['version']}"
else
puts 'Could not determine server version.'
end
end
desc 'logout', 'user logout from Chef Compliance'
def logout
if Compliance::API.logout
puts 'Successfully logged out'
else
puts 'Could not log out'
end
end
end
# register the subcommand to Inspec CLI registry
Inspec::Plugins::CLI.add_subcommand(ComplianceCLI, 'compliance', 'compliance SUBCOMMAND ...', 'Chef Compliance commands', {})
end