Module: ShellStrike::Ssh

Defined in:
lib/shell_strike/ssh.rb

Defined Under Namespace

Classes: CommandExecutionFailureError, CommandResult, HostUnreachableError, InvalidCredentialsError

Class Method Summary collapse

Class Method Details

.check_host_reachable(host) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/shell_strike/ssh.rb', line 6

def check_host_reachable(host)
  reachable = false
  explanation = nil

  begin
    establish_connection(host, 'fake_username', 'fake_password')
    reachable = true
  rescue Net::SSH::AuthenticationFailed
    reachable = true
  rescue Net::SSH::ConnectionTimeout
    explanation = :timeout
  rescue Errno::EHOSTUNREACH
    explanation = :unreachable
  rescue Net::SSH::Exception
    explanation = :unexpected_error
  end
  
  [reachable, explanation]
end

.execute_command(host, username, password, command) ⇒ CommandResult

Executes the specified command against the specified host.

Parameters:

  • host (ShellStrike::Host)

    The host to execute the command against.

  • username (String)

    The username to use to establish the connection.

  • password (String)

    The password to use to establish the connection.

  • command (String)

    The command to run against the remote host.

Returns:

  • (CommandResult)

    The result of the command’s execution.

Raises:



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
# File 'lib/shell_strike/ssh.rb', line 45

def execute_command(host, username, password, command)
  raise HostUnreachableError unless check_host_reachable(host)[0]
  raise InvalidCredentialsError unless valid_credentials?(host, username, password)

  exit_code = 1
  stdout_text = ''
  stderr_text = ''


  establish_connection(host, username, password) do |ssh|
    ssh.open_channel do |channel|
      channel.exec(command) do |ch, success|
        raise CommandExecutionFailureError unless success

        # Process the stdout stream
        ch.on_data do |_, stdout_buf|
          stdout_text << stdout_buf.read
        end

        # Process the stderr stream
        ch.on_extended_data do |_, stderr_buf|
          stderr_text << stderr_buf.read
        end

        ch.on_request('exit-status') do |_, status|
          exit_code = status.read_long
        end
      end

      channel.wait # Make sure we don't close the channel until the command has completed
    end
  end

  # Split the output streams at each linefeed
  stdout_arr = stdout_text.split("\n")
  stderr_arr = stderr_text.split("\n")

  CommandResult.new(command: command, exit_code: exit_code, stdout: stdout_arr, stderr: stderr_arr)
end

.valid_credentials?(host, username, password) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
29
30
31
32
33
34
35
# File 'lib/shell_strike/ssh.rb', line 26

def valid_credentials?(host, username, password)
  return false unless check_host_reachable(host)[0]

  begin
    establish_connection(host, username, password)
    true
  rescue Net::SSH::Exception, Errno::EHOSTUNREACH
    false
  end
end