Class: Spectre::SSH::SSHConnection

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

Instance Method Summary collapse

Constructor Details

#initialize(host, username, opts, logger) ⇒ SSHConnection

Returns a new instance of SSHConnection.



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/spectre/ssh.rb', line 15

def initialize host, username, opts, logger
  opts[:non_interactive] = true

  @__logger = logger
  @__host = host
  @__username = username
  @__opts = opts
  @__session = nil
  @__exit_code = nil
  @__output = ''
end

Instance Method Details

#can_connect?Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/spectre/ssh.rb', line 73

def can_connect?
  @__output = nil

  begin
    connect!
    @__session.open_channel.close
    @__output = "successfully connected to #{@__host} with user #{@__username}"
    @__exit_code = 0
    return true
  rescue Exception => e
    @__logger.error e.message
    @__output = "unable to connect to #{@__host} with user #{@__username}"
    @__exit_code = 1
  end

  return false
end

#closeObject



67
68
69
70
71
# File 'lib/spectre/ssh.rb', line 67

def close
  return unless @__session and not @__session.closed?

  @__session.close
end

#connect!Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/spectre/ssh.rb', line 55

def connect!
  return unless @__session == nil or @__session.closed?

  begin
    @__session = Net::SSH.start(@__host, @__username, @__opts)
  rescue SocketError
    raise SSHError.new("Unable to connect to #{@__host} with user #{@__username}")
  rescue Net::SSH::AuthenticationFailed
    raise SSHError.new("Authentication failed for #{@__username}@#{@__host}. Please check password, SSH keys and passphrases.")
  end
end

#exec(command) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/spectre/ssh.rb', line 91

def exec command
  connect!

  log_str = "#{@__session.options[:user]}@#{@__session.host} -p #{@__session.options[:port]} #{command}"

  @channel = @__session.open_channel do |channel|
    channel.exec(command) do |_ch, success|
      abort "could not execute #{command} on #{@__session.host}" unless success

      @__output = ''

      channel.on_data do |_, data|
        @__output += data
      end

      channel.on_extended_data do |_, _type, data|
        @__output += data
      end

      channel.on_request('exit-status') do |_, data|
        @__exit_code = data.read_long
      end

      # channel.on_request('exit-signal') do |ch, data|
      #   exit_code = data.read_long
      # end
    end
  end

  @channel.wait
  @__session.loop

  log_str += "\n" + @__output
  @__logger.info log_str
end

#exit_codeObject



131
132
133
# File 'lib/spectre/ssh.rb', line 131

def exit_code
  @__exit_code
end

#file_exists(path) ⇒ Object



45
46
47
48
# File 'lib/spectre/ssh.rb', line 45

def file_exists path
  exec "ls #{path}"
  exit_code == 0
end

#outputObject



127
128
129
# File 'lib/spectre/ssh.rb', line 127

def output
  @__output
end

#owner_of(path) ⇒ Object



50
51
52
53
# File 'lib/spectre/ssh.rb', line 50

def owner_of path
  exec "stat -c %U #{path}"
  output.chomp
end

#passphrase(phrase) ⇒ Object



41
42
43
# File 'lib/spectre/ssh.rb', line 41

def passphrase phrase
  @__opts[:passphrase] = phrase
end

#password(pass) ⇒ Object



31
32
33
34
# File 'lib/spectre/ssh.rb', line 31

def password pass
  @__opts[:password] = pass
  @__opts[:auth_methods].push 'password' unless @__opts[:auth_methods].include? 'password'
end

#private_key(file_path) ⇒ Object



36
37
38
39
# File 'lib/spectre/ssh.rb', line 36

def private_key file_path
  @__opts[:keys] = [file_path]
  @__opts[:auth_methods].push 'publickey' unless @__opts[:auth_methods].include? 'publickey'
end

#username(user) ⇒ Object



27
28
29
# File 'lib/spectre/ssh.rb', line 27

def username user
  @__username = user
end