class Toolshed::ServerAdministration::SSH

SSH class that can ssh to a host and perform commands

Attributes

channel[RW]
commands[RW]
data[RW]
host[RW]
keys[RW]
password[RW]
silent[R]
ssh_options[RW]
sudo_password[RW]
timeout[R]
user[RW]

Public Class Methods

new(options = nil) click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 16
def initialize(options = nil) # rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity, LineLength
  options ||= {}
  @password = options[:password] || ''
  @sudo_password = options[:sudo_password] || ''
  @keys = options[:keys] || ''
  @host = options[:host] || ''
  @user = options[:user] || ''
  @ssh_options = options[:ssh_options] || {}
  @commands = options[:commands] || ''
  @password = options[:password] || ''
  @data = []
  @silent = options[:silent] || false
  timeout_period = options[:timeout_period].to_i || 30
  @timeout = Toolshed::Timeout.new(timeout_period: timeout_period)

  set_ssh_options
end

Public Instance Methods

execute() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 34
def execute
  begin
    timeout.start do
      Net::SSH.start(host, user, ssh_options) do |ssh|
        ssh.open_channel do |channel|
          self.channel = channel
          request_pty
          run_commands
        end
        ssh.loop
      end
    end
  rescue Toolshed::Timeout::Error => e
    Toolshed.logger.fatal e.message
    raise SSHResponseException, "Unable to handle response for #{data.last}"
  end
  data
end

Protected Instance Methods

on_close() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 77
def on_close
  channel.on_close do |_ch|
    puts 'Channel is closing!' unless silent
  end
end
on_data() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 90
def on_data
  channel.on_data do |_ch, data|
    puts "#{data}" unless silent
    self.data << data
    timeout.reset_start_time
    send_data(data)
  end
end
on_extended_data() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 83
def on_extended_data
  channel.on_extended_data do |_ch, _type, data|
    timeout.reset_start_time
    puts "stderr: #{data}" unless silent
  end
end
request_pty() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 67
def request_pty
  channel.request_pty do |_ch, success|
    timeout.reset_start_time
    unless silent
      message = (success) ? 'Successfully obtained pty' : 'Could not obtain pty'
      puts message
    end
  end
end
run_commands() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 55
def run_commands
  # @TODO fix this so it does not just pass in the commands option
  # Converts to string like command1;command2
  channel.exec(commands) do |_ch, success|
    abort 'Could not execute commands!' unless success

    on_data
    on_extended_data
    on_close
  end
end
send_data(data) click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 99
def send_data(data)
  send_password_data if data =~ /password/
  send_yes_no_data if data =~ %r{Do you want to continue [Y/n]?}
end
send_password_data() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 104
def send_password_data
  channel.send_data "#{password_from_config(sudo_password)}\n"
end
send_yes_no_data() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 108
def send_yes_no_data
  channel.send_data "Y\n"
end
set_ssh_options() click to toggle source
# File lib/toolshed/server_administration/ssh.rb, line 112
def set_ssh_options # rubocop:disable AbcSize
  if keys.nil? || keys.empty?
    final_password = password_from_config(password)
    ssh_options.merge!(password: final_password)
  else
    ssh_options.merge!(keys: [keys]) unless keys.nil? || keys.empty?
  end
end