mirror of
https://github.com/inspec/inspec
synced 2025-02-16 22:18:38 +00:00
feature: configure ssh+winrm targets on CLI-runner
Signed-off-by: Dominik Richter <dominik.richter@gmail.com>
This commit is contained in:
parent
33043dd6a1
commit
360da9a7ba
2 changed files with 129 additions and 3 deletions
13
bin/vulcano
13
bin/vulcano
|
@ -44,8 +44,19 @@ class VulcanoCLI < Thor
|
|||
|
||||
desc "exec PATHS", "run all test files"
|
||||
option :id, type: :string
|
||||
option :backend, type: :string, default: 'exec'
|
||||
option :host, type: :string
|
||||
option :port, type: :numeric
|
||||
option :user, type: :string, default: 'root'
|
||||
option :password, type: :string, default: nil
|
||||
option :key_file, type: :string, default: nil
|
||||
option :disable_sudo, type: :boolean, default: false
|
||||
option :sudo_password, type: :string, default: nil
|
||||
option :sudo_options, type: :string, default: ''
|
||||
option :winrm_self_signed, type: :boolean, default: false
|
||||
option :winrm_ssl, type: :boolean, default: false
|
||||
def exec(*files)
|
||||
runner = Vulcano::Runner.new(options[:id])
|
||||
runner = Vulcano::Runner.new(options[:id], options)
|
||||
files.each do |file|
|
||||
runner.add_file(file)
|
||||
end
|
||||
|
|
|
@ -15,17 +15,132 @@ require 'vulcano/rspec_json_formatter'
|
|||
module Vulcano
|
||||
|
||||
class Runner
|
||||
def initialize(profile_id)
|
||||
def initialize(profile_id, conf)
|
||||
@rules = []
|
||||
@profile_id = profile_id
|
||||
@conf = conf
|
||||
# RSpec.configuration.output_stream = $stdout
|
||||
# RSpec.configuration.error_stream = $stderr
|
||||
RSpec.configuration.add_formatter(:json)
|
||||
|
||||
# specinfra
|
||||
configure_shared_options
|
||||
configure_target
|
||||
end
|
||||
|
||||
def configure_shared_options
|
||||
Specinfra::Backend::Cmd.send(:include, Specinfra::Helper::Set)
|
||||
conf = Specinfra.configuration
|
||||
conf.os = nil
|
||||
if @conf['disable_sudo']
|
||||
conf.disable_sudo = true
|
||||
else
|
||||
conf.sudo_password = @conf['sudo_password']
|
||||
conf.sudo_options = @conf['sudo_options']
|
||||
end
|
||||
end
|
||||
|
||||
def configure_target
|
||||
t = @conf[:backend]
|
||||
m = BACKEND_CONFIGS[t]
|
||||
raise "Don't understand backend '#{t}'" if m.nil?
|
||||
f = method(m)
|
||||
raise "Couldn't find internal backend method '#{m}'" if f.nil?
|
||||
f.call
|
||||
end
|
||||
|
||||
BACKEND_CONFIGS = {
|
||||
'exec' => :configure_localhost,
|
||||
'ssh' => :configure_ssh,
|
||||
'winrm' => :configure_winrm,
|
||||
}
|
||||
|
||||
def configure_localhost
|
||||
Specinfra.configuration.backend = :exec
|
||||
Specinfra.configuration.os = nil
|
||||
end
|
||||
|
||||
def configure_ssh
|
||||
conf = Specinfra.configuration
|
||||
conf.backend = :ssh
|
||||
conf.request_pty = true
|
||||
host = @conf['host'].to_s
|
||||
RSpec.configuration.host = host
|
||||
ssh_opts = {
|
||||
port: @conf['port'] || 22,
|
||||
auth_methods: ['none'],
|
||||
user_known_hosts_file: "/dev/null",
|
||||
global_known_hosts_file: "/dev/null",
|
||||
number_of_password_prompts: 0,
|
||||
user: @conf['user'],
|
||||
password: @conf['password'],
|
||||
keys: [@conf['key_file']].compact,
|
||||
}
|
||||
if host.empty?
|
||||
raise "You must configure a target host."
|
||||
end
|
||||
unless ssh_opts[:port] > 0
|
||||
raise "Port must be > 0 (not #{ssh_opts[:port]})"
|
||||
end
|
||||
if ssh_opts[:user].to_s.empty?
|
||||
raise "User must not be empty."
|
||||
end
|
||||
unless ssh_opts[:keys].empty?
|
||||
ssh_opts[:auth_methods].push('publickey')
|
||||
ssh_opts[:keys_only] = true if ssh_opts[:password].nil?
|
||||
end
|
||||
unless ssh_opts[:password].nil?
|
||||
ssh_opts[:auth_methods].push('password')
|
||||
end
|
||||
if ssh_opts[:keys].empty? and ssh_opts[:password].nil?
|
||||
raise "You must configure at least one authentication method" +
|
||||
": Password or key."
|
||||
end
|
||||
conf.ssh_options = ssh_opts
|
||||
end
|
||||
|
||||
def configure_winrm
|
||||
conf = Specinfra.configuration
|
||||
conf.backend = :winrm
|
||||
conf.os = { family: 'windows'}
|
||||
host = @conf['host'].to_s
|
||||
port = @conf['port']
|
||||
user = @conf['user'].to_s
|
||||
pass = @conf['pass'].tp_s
|
||||
|
||||
# SSL configuration
|
||||
if @conf['winrm_ssl']
|
||||
scheme = 'https'
|
||||
port = port || 5986
|
||||
else
|
||||
scheme = 'http'
|
||||
port = port || 5985
|
||||
end
|
||||
|
||||
# validation
|
||||
if host.empty?
|
||||
raise "You must configure a target host."
|
||||
end
|
||||
unless port > 0
|
||||
raise "Port must be > 0 (not #{port})"
|
||||
end
|
||||
if user.empty?
|
||||
raise "You must configure a WinRM user for login."
|
||||
end
|
||||
if pass.empty?
|
||||
raise "You must configure a WinRM password."
|
||||
end
|
||||
|
||||
# create the connection
|
||||
endpoint = "#{scheme}://#{host}:#{port}/wsman"
|
||||
winrm = ::WinRM::WinRMWebService.new(
|
||||
endpoint,
|
||||
:ssl,
|
||||
user: user,
|
||||
pass: pass,
|
||||
basic_auth_only: true,
|
||||
no_ssl_peer_verification: @conf['winrm_self_signed'],
|
||||
)
|
||||
conf.winrm = winrm
|
||||
end
|
||||
|
||||
def add_file(path)
|
||||
|
|
Loading…
Add table
Reference in a new issue