inspec/lib/vulcano/backend/ssh.rb

91 lines
2.3 KiB
Ruby
Raw Normal View History

# encoding: utf-8
module Vulcano::Backends
class SSH < Vulcano.backend(1)
name 'ssh'
def initialize(conf)
@conf = conf
@files = {}
@conf['host'] ||
fail("You must specify a SSH host.")
@ssh = start_ssh
end
def file(path)
@files[path] ||= LinuxFile.new(self, path)
end
def run_command(cmd)
stdout = stderr = ''
exit_status = nil
cmd.force_encoding('binary') if cmd.respond_to?(:force_encoding)
@ssh.open_channel do |channel|
channel.request_pty do |ch, success|
abort 'Could not obtain pty on SSH channel ' if !success
end
channel.exec(cmd) do |ch, success|
unless success
abort 'Couldn\'t execute command on SSH.'
end
channel.on_data do |ch,data|
stdout += data
end
channel.on_extended_data do |ch,type,data|
stderr += data
end
channel.on_request("exit-status") do |ch,data|
exit_status = data.read_long
end
channel.on_request("exit-signal") do |ch, data|
exit_status = data.read_long
end
end
end
@ssh.loop
CommandResult.new(stdout, stderr, exit_status)
end
private
def start_ssh
host = @conf['host']
ssh_config = Net::SSH.configuration_for(host)
user = @conf['user'] || ssh_config[:user]
keys = [ @conf['key_file'], ssh_config[:keys] ].flatten.compact
options = {
port: @conf['port'] || ssh_config[:port] || 22,
auth_methods: ['none'],
user_known_hosts_file: '/dev/null',
global_known_hosts_file: '/dev/null',
number_of_password_prompts: 0,
password: @conf['password'] || ssh_config[:password],
keys: keys,
}
unless options[:keys].empty?
options[:auth_methods].push('publickey')
options[:keys_only] = true if options[:password].nil?
end
unless options[:password].nil?
options[:auth_methods].push('password')
end
if options[:keys].empty? and options[:password].nil?
fail('You must configure at least one authentication method for SSH:' +
' Password or key.')
end
Net::SSH.start( host, user, options )
end
end
end