Class: Aspera::Ssh

Inherits:
Object
  • Object
show all
Defined in:
lib/aspera/ssh.rb

Overview

A simple wrapper around Net::SSH executes one command and get its result from stdout

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, username, ssh_options) ⇒ Ssh

ssh_options: same as Net::SSH.start see: net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/aspera/ssh.rb', line 33

def initialize(host, username, ssh_options)
  Log.log.debug{"ssh:#{username}@#{host}"}
  Log.log.debug{"ssh_options:#{ssh_options}"}
  Aspera.assert_type(host, String)
  Aspera.assert_type(username, String)
  Aspera.assert_type(ssh_options, Hash)
  @host = host
  @username = username
  @ssh_options = ssh_options
  @ssh_options[:logger] = Log.log
end

Class Method Details

.disable_ecd_sha2_algorithmsObject



25
26
27
28
29
# File 'lib/aspera/ssh.rb', line 25

def disable_ecd_sha2_algorithms
  Log.log.debug('Disabling SSH ecdsa')
  Net::SSH::Transport::Algorithms::ALGORITHMS.each_value { |a| a.reject! { |a| a =~ /^ecd(sa|h)-sha2/ } }
  Net::SSH::KnownHosts::SUPPORTED_TYPE.reject! { |t| t =~ /^ecd(sa|h)-sha2/ }
end

.disable_ed25519_keysObject



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/aspera/ssh.rb', line 12

def disable_ed25519_keys
  Log.log.debug('Disabling SSH ed25519 user keys')
  old_verbose = $VERBOSE
  $VERBOSE = nil
  Net::SSH::Authentication::Session.class_eval do
    define_method(:default_keys) do
      %w[~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa].freeze
    end
    private(:default_keys)
  end rescue nil
  $VERBOSE = old_verbose
end

Instance Method Details

#execute(cmd, input = nil) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/aspera/ssh.rb', line 45

def execute(cmd, input=nil)
  Aspera.assert_type(cmd, String)
  Log.log.debug{"cmd=#{cmd}"}
  response = []
  Net::SSH.start(@host, @username, @ssh_options) do |session|
    ssh_channel = session.open_channel do |channel|
      # prepare stdout processing
      channel.on_data{|_chan, data|response.push(data)}
      # prepare stderr processing, stderr if type = 1
      channel.on_extended_data do |_chan, _type, data|
        error_message = "#{cmd}: [#{data.chomp}]"
        # Happens when windows user hasn't logged in and created home account.
        error_message += "\nHint: home not created in Windows?" if data.include?('Could not chdir to home directory')
        raise error_message
      end
      # send command to SSH channel (execute) cspell: disable-next-line
      channel.send('cexe'.reverse, cmd){|_ch, _success|channel.send_data(input) unless input.nil?}
    end
    # wait for channel to finish (command exit)
    ssh_channel.wait
    # main ssh session loop
    session.loop
  end
  # response as single string
  return response.join
end