inspec/lib/vulcano/backend/specinfra.rb

271 lines
6.4 KiB
Ruby
Raw Normal View History

# encoding: utf-8
require 'shellwords'
module Vulcano::Backends
class SpecinfraHelper < Vulcano.backend(1)
name 'specinfra'
def initialize(conf)
@conf = conf
@files = {}
type = @conf[:backend]
configure_shared_options
# configure the given backend, if we can handle it
# e.g. backend = exec ==> try to call configure_exec
# if we don't support it, error out
m = "configure_#{type}"
if self.respond_to?(m.to_sym)
self.send(m)
else
raise "Cannot configure Specinfra backend #{type}: it isn't supported yet."
end
end
def file(path)
@files[path] ||= File.new(path)
end
def run_command(cmd)
Specinfra::Runner.run_command(cmd)
end
def to_s
'SpecInfra Backend Runner'
end
def configure_shared_options
Specinfra::Backend::Cmd.send(:include, Specinfra::Helper::Set)
si = Specinfra.configuration
si.os = nil
if @conf['disable_sudo']
si.disable_sudo = true
else
si.sudo_password = @conf['sudo_password']
si.sudo_options = @conf['sudo_options']
end
end
def configure_docker
host = @conf['host'].to_s
Specinfra.configuration.backend = :docker
Specinfra.configuration.docker_container = host
end
def configure_exec
Specinfra.configuration.backend = :exec
end
def configure_ssh
si = Specinfra.configuration
si.backend = :ssh
si.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
si.ssh_options = ssh_opts
end
def configure_winrm
si = Specinfra.configuration
si.backend = :winrm
si.os = { family: 'windows'}
# common options
host = conf['host'].to_s
port = conf['port']
user = conf['user'].to_s
pass = conf['password'].to_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'],
)
si.winrm = winrm
end
end
class SpecinfraHelper
class File
def initialize(path)
@path = path
end
def type
path = Shellwords.escape(@path)
Specinfra::Runner.run_command("stat -c %f #{path}").stdout
end
def exists?
Specinfra::Runner.check_file_exists(@path)
end
def file?
Specinfra::Runner.check_file_is_file(@path)
end
def block_device?
Specinfra::Runner.check_file_is_block_device(@path)
end
def character_device?
Specinfra::Runner.check_file_is_character_device(@path)
end
def socket?
Specinfra::Runner.check_file_is_socket(@path)
end
def directory?
Specinfra::Runner.check_file_is_directory(@path)
end
def symlink?
Specinfra::Runner.check_file_is_symlink(@path)
end
def pipe?
Specinfra::Runner.check_file_is_pipe(@path)
end
def mode
Specinfra::Runner.get_file_mode(@path).stdout
end
def owner
Specinfra::Runner.get_file_owner(@path).stdout
end
def group
Specinfra::Runner.get_file_group(@path).stdout
end
def link_target
path = Shellwords.escape(@path)
Specinfra::Runner.run_command("readlink #{path}").stdout
end
def content
Specinfra::Runner.get_file_content(@path).stdout
end
def mtime
Specinfra::Runner.get_file_mtime(@path).stdout.strip
end
def ctime
Specinfra::Runner.get_file_ctime(@path).stdout.strip
end
def size
Specinfra::Runner.get_file_size(@path).stdout.strip.to_i
end
def selinux_label
Specinfra::Runner.get_file_selinuxlabel(@path).stdout.strip
end
def readable?(by_type, by_user)
if by_user.nil?
Specinfra::Runner.check_file_is_readable(@path, by_type)
else
Specinfra::Runner.check_file_is_accessible_by_user(@path, by_user, 'r')
end
end
def writable?(by_type, by_user)
if by_user.nil?
Specinfra::Runner.check_file_is_writable(@path, by_type)
else
Specinfra::Runner.check_file_is_accessible_by_user(@path, by_user, 'w')
end
end
def executable?(by_type, by_user)
if by_user.nil?
Specinfra::Runner.check_file_is_executable(@path, by_type)
else
Specinfra::Runner.check_file_is_accessible_by_user(@path, by_user, 'x')
end
end
def mounted?(opts, only_with)
Specinfra::Runner.check_file_is_mounted(@name, opts, only_with)
end
def immutable?
Specinfra::Runner.get_file_immutable(@path)
end
end
end
end