module Dopi::Connector::Ssh

Public Instance Methods

base64() click to toggle source
# File lib/dopi/connector/ssh.rb, line 42
def base64
  @base64 || base64_valid? ? hash[:base64] : true
end
check_host_key() click to toggle source
# File lib/dopi/connector/ssh.rb, line 38
def check_host_key
  @check_host_key || check_host_key_valid? ? hash[:check_host_key] : false
end
port() click to toggle source
# File lib/dopi/connector/ssh.rb, line 30
def port
  @port ||= port_valid? ? hash[:port].to_s : '22'
end
quiet() click to toggle source
# File lib/dopi/connector/ssh.rb, line 34
def quiet
  @quiet || quiet_valid? ? hash[:quiet] : true
end
ssh_command(env, command_string) click to toggle source
# File lib/dopi/connector/ssh.rb, line 22
def ssh_command(env, command_string)
  credential = working_ssh_credential
  ssh_command_string = create_ssh_command_string(credential, env, command_string)
  local_env = create_local_env(credential)
  local_env.merge!(env) unless base64 # keep old behaviour for escaping
  local_command(local_env, ssh_command_string)
end
ssh_options() click to toggle source
# File lib/dopi/connector/ssh.rb, line 46
def ssh_options
  #TBD
  []
end
supported_credential_types() click to toggle source
# File lib/dopi/connector/ssh.rb, line 51
def supported_credential_types
  [:username_password, :ssh_key]
end
validate_ssh() click to toggle source
# File lib/dopi/connector/ssh.rb, line 13
def validate_ssh
  log_validation_method(:port_valid?, CommandParsingError)
  log_validation_method(:quiet_valid?, CommandParsingError)
  log_validation_method(:check_host_key_valid?, CommandParsingError)
  log_validation_method(:base64_valid?, CommandParsingError)
  log_validation_method(:ssh_options_valid?, CommandParsingError)
  validate_credentials
end

Private Instance Methods

base64_valid?() click to toggle source
# File lib/dopi/connector/ssh.rb, line 156
def base64_valid?
  return false unless hash.kind_of?(Hash)
  return false if hash[:base64].nil? # is optional
  hash[:base64].kind_of?(TrueClass) or hash[:base64].kind_of?(FalseClass) or
    raise CommandParsingError, "Plugin #{name}: The value for 'base64' must be boolean"
end
check_host_key_valid?() click to toggle source
# File lib/dopi/connector/ssh.rb, line 149
def check_host_key_valid?
  return false unless hash.kind_of?(Hash)
  return false if hash[:check_host_key].nil? # is optional
  hash[:check_host_key].kind_of?(TrueClass) or hash[:check_host_key].kind_of?(FalseClass) or
    raise CommandParsingError, "Plugin #{name}: The value for 'check_host_key' must be boolean"
end
create_local_env(credential) click to toggle source
# File lib/dopi/connector/ssh.rb, line 70
def create_local_env(credential)
  if credential.type == :username_password
    { 'SSHPASS' => credential.password }
  else
    {}
  end
end
create_ssh_command_string(credential, env, command_string) click to toggle source
# File lib/dopi/connector/ssh.rb, line 78
def create_ssh_command_string(credential, env, command_string)
  address = @node.address(port)
  opts = options(credential)
  prefix = credential.type == :username_password ? sshpass_cmd : ''
  cmd = "#{ssh_env_string(env)} #{command_string}"
  real_cmd = if base64
    log(:debug, "Unencoded command: '#{cmd}'")
    ssh_encode_command(cmd)
  else
    ssh_escape_command(cmd)
  end
  "#{prefix}ssh #{opts} #{credential.username}@#{address} \"#{real_cmd}\""
end
options(credential) click to toggle source
# File lib/dopi/connector/ssh.rb, line 92
def options(credential)
  opts = []
  opts << "-p #{port}"
  opts << '-q' if quiet
  opts << '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' unless check_host_key
  if credential.type == :ssh_key
    opts << '-o ChallengeResponseAuthentication=no'
    opts << '-o PasswordAuthentication=no'
    opts << "-i #{credential.private_key}"
  end
  # Force allocation of tty, needed to propagate signals to remotely
  # spawned processes
  opts << '-tt'
  opts += ssh_options
  opts += ssh_options_defaults if respond_to?(:ssh_options_defaults)
  opts.join(' ')
end
port_valid?() click to toggle source
# File lib/dopi/connector/ssh.rb, line 132
def port_valid?
  return false unless hash.kind_of?(Hash)
  return false if hash[:port].nil? # is optional
  hash[:port].kind_of?(Fixnum) or
    raise CommandParsingError, "Plugin #{name}: The value for port must be a number"
  hash[:port].between?(0, 65536) or
    raise CommandParsingError, "Plugin #{name}: The value for port must bigger than 0 and below 65536"
  true
end
quiet_valid?() click to toggle source
# File lib/dopi/connector/ssh.rb, line 142
def quiet_valid?
  return false unless hash.kind_of?(Hash)
  return false if hash[:quiet].nil? # is optional
  hash[:quiet].kind_of?(TrueClass) or hash[:quiet].kind_of?(FalseClass) or
    raise CommandParsingError, "Plugin #{name}: The value for 'quiet' must be boolean"
end
ssh_encode_command(cmd) click to toggle source
# File lib/dopi/connector/ssh.rb, line 128
def ssh_encode_command(cmd)
  "echo -n #{Base64.strict_encode64(cmd)} | base64 -d | bash"
end
ssh_env_string(env) click to toggle source
# File lib/dopi/connector/ssh.rb, line 120
def ssh_env_string(env)
  env.map{|variable,value| "export #{variable}=#{value};" }.join(' ')
end
ssh_escape_command(cmd) click to toggle source
# File lib/dopi/connector/ssh.rb, line 124
def ssh_escape_command(cmd)
  cmd.gsub("\\", "\\\\\\\\").gsub('"', '\\"')
end
ssh_options_valid?() click to toggle source
# File lib/dopi/connector/ssh.rb, line 163
def ssh_options_valid?
  #TBD
  false
end
sshpass_bin() click to toggle source
# File lib/dopi/connector/ssh.rb, line 110
def sshpass_bin
  @sshpass_bin ||= ENV['PATH'].split(':').map{|p| File.join(p, 'sshpass')}.find do |f|
    File.exists?(f) && File.executable?(f)
  end
end
sshpass_cmd() click to toggle source
# File lib/dopi/connector/ssh.rb, line 116
def sshpass_cmd
  @sshpass_cmd ||= sshpass_bin ? sshpass_bin + ' -e ' : ""
end
working_ssh_credential() click to toggle source

this method checks for every credential if a login is possible and will return the first one where it is possible. If none of the credentials work it will raise a CommandConnectionError.

# File lib/dopi/connector/ssh.rb, line 60
def working_ssh_credential
  credentials.find do |credential|
    ssh_command_string = create_ssh_command_string(credential, {}, 'exit')
    local_env = create_local_env(credential)
    local_command(local_env, ssh_command_string)[2] == 0
  end or raise CommandConnectionError,
    "Can't establish connection with node #{@node.name} with any of the given" +
    "credentials #{credentials.map{|c| c.name}.join(', ')}"
end