Class: ExecuteSSH

Inherits:
ExecuteBase show all
Defined in:
lib/teuton/case/execute/execute_ssh.rb

Instance Method Summary collapse

Methods inherited from ExecuteBase

#initialize

Methods included from Verbose

#verbose, #verboseln

Constructor Details

This class inherits a constructor from ExecuteBase

Instance Method Details

#call(input_hostname) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/teuton/case/execute/execute_ssh.rb', line 9

def call(input_hostname)
  action[:conn_type] = :ssh
  hostname = input_hostname.to_s
  ip = config.get("#{hostname}_ip".to_sym).to_s
  username = config.get("#{hostname}_username".to_sym).to_s
  password = config.get("#{hostname}_password".to_sym).to_s
  port = config.get("#{hostname}_port".to_sym).to_i
  port = 22 if port.zero?

  unless config.get("#{hostname}_route".to_sym) == "NODATA"
    # Reconfigure command with gateway. Example host1_route: IP.
    # hostname2 = hostname ¿not used?
    ip2 = ip
    username2 = username
    password2 = password
    command2 = action[:command]
    hostname = config.get("#{hostname}_route".to_sym)
    ip = config.get("#{hostname}_ip".to_sym).to_s
    username = config.get("#{hostname}_username".to_sym).to_s
    password = config.get("#{hostname}_password".to_sym).to_s
    ostype = config.get("#{hostname}_ostype".to_sym).to_s

    action[:command] = if ostype.downcase.start_with? "win"
      "echo y | plink #{username2}@#{ip2} -ssh -pw #{password2} \"#{command2}\""
    else
      "sshpass -p #{password2} #{username2}@#{ip2} #{command2}"
    end
  end

  text = "TEUTON_NODATA"
  exitcode = 0
  begin
    if sessions[hostname].nil?
      sessions[hostname] = Net::SSH.start(
        ip,
        username,
        port: port,
        password: password,
        keepalive: true,
        timeout: 30,
        non_interactive: true
      )
    end
    if sessions[hostname].instance_of? Net::SSH::Connection::Session
      text = sessions[hostname].exec!(action[:command])
      exitcode = text.exitstatus
    else
      text = "TEUTON_ERROR_SSH_NO_CONNECTION"
      exitcode = -1
    end
  rescue Errno::EHOSTUNREACH
    sessions[hostname] = :nosession
    conn_status[hostname] = :host_unreachable
    text = "TEUTON_ERROR_SSH_HOST_UNREACHABLE"
    exitcode = -1
    log("Host #{ip} unreachable!", :error)
  rescue Net::SSH::AuthenticationFailed
    sessions[hostname] = :nosession
    conn_status[hostname] = :error_authentication_failed
    text = "TEUTON_ERROR_SSH_AUTH_FAILED"
    exitcode = -1
    log("SSH::AuthenticationFailed!", :error)
  rescue Net::SSH::HostKeyMismatch
    sessions[hostname] = :nosession
    conn_status[hostname] = :host_key_mismatch
    text = "TEUTON_ERROR_SSH_HOST_KEY"
    exitcode = -1
    log("SSH::HostKeyMismatch!", :error)
    log("* The destination server's fingerprint is not matching " \
        "what is in your local known_hosts file.", :error)
    log("* Remove the existing entry in your local known_hosts file", :error)
    log("* Try this => ssh-keygen -f '/home/USERNAME/.ssh/known_hosts' " \
        "-R #{ip}", :error)
  rescue => e
    sessions[hostname] = :nosession
    conn_status[hostname] = :error
    text = "TEUTON_ERROR_SSH"
    exitcode = -1
    log("[#{e.class}] SSH on <#{username}@#{ip}>" \
        " exec: #{action[:command]}", :error)
  end
  result.exitcode = exitcode
  result.content = encode_and_split(action[:encoding], text)
end