inspec/lib/vulcano/backend/ssh.rb

107 lines
2.6 KiB
Ruby
Raw Normal View History

# encoding: utf-8
2015-10-06 16:55:44 +00:00
# author: Dominik Richter
# author: Christoph Hartmann
module Vulcano::Backends
class SSH < Vulcano.backend(1)
name 'ssh'
attr_reader :os
def initialize(conf)
@conf = conf
@files = {}
@conf['host'] ||
fail('You must specify a SSH host.')
@ssh = start_ssh
@os = OS.new(self)
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.exec(cmd) do |_, success|
unless success
abort 'Couldn\'t execute command on SSH.'
end
channel.on_data do |_, data|
stdout += data
end
channel.on_extended_data do |_, _type, data|
stderr += data
end
channel.on_request('exit-status') do |_, data|
exit_status = data.read_long
end
channel.on_request('exit-signal') do |_, data|
exit_status = data.read_long
end
end
end
@ssh.loop
CommandResult.new(stdout, stderr, exit_status)
end
private
def validate_options(options)
if options[:keys].empty? and options[:password].nil?
fail 'You must configure at least one authentication method for SSH:'\
' Password or key.'
end
unless options[:keys].empty?
options[:auth_methods].push('publickey')
options[:keys_only] = true if options[:password].nil?
end
# rubocop:disable Style/GuardClause
unless options[:password].nil?
options[:auth_methods].push('password')
end
# rubocop:enable Style/GuardClause
end
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,
keepalive: true,
keepalive_interval: 60,
compression: true,
compression_level: 6,
password: @conf['password'] || ssh_config[:password],
keys: keys,
}
validate_options(options)
Net::SSH.start(host, user, options)
end
class OS < OSCommon
def initialize(backend)
super(backend, { family: 'unix' })
end
end
end
end