Jump to: navigation, search

Satori/SSHModuleProposal

< Satori
Revision as of 20:41, 7 March 2014 by Samstav (talk | contribs)

SSH Module Proposal

Implement an SSH wrapper module to enable logging on to servers so we can do data plane discovery


Interface

>>> from satori import ssh
>>> creds = {"username": "Tobias", "password": "pa$$word"}
>>> client = ssh.connect("123.456.789.11", credentials=creds)  # see signature in implementation section
>>> output = client.remote_execute("sudo echo hello", with_exit_code=True)
>>> print output
{'stdout': 'hello', 'stderr': '', 'exit_code': 0}


Requirements

Support the following login methods:

    • password/username
    • private key/username
    • private key file/username
    • for all the above methods, the module should support using a proxy (i.e. bastion)


Note: basically, support the options as would commonly be used through the ssh command-line.


Primary methods:

  • remote_execute: to execute a remote command and return stderr and stdout
  • test_connection: to test that a connection can be made

Additionally:

  • Implement an instance property, platform_info, that will return the remote host's platform info using (python >=2.4)'s platform module


Implementation

  • Use paramiko and extend its SSHClient class. Wrap paramiko to make it simpler to use and understand the code from other parts of satori.
  • Accept a password string, private key string, or path to private key file for auth. Paramiko will automatically check in the standard places for ssh keys if nothing else is provided.
  • Manage authentication mechanisms, retry authenticating, and prefer SSH keys.
    • Implement/override a connect() method to do this.
  • Provide a method, test_connection(), for doing just that.
  • Manage connecting and disconnecting when remote_execute() is called. (Lazy load the auth object)
  • Attempt to handle password prompts for non-passwordless sudoers
  • Attempt to handle hiccups with pty/tty rules by retrying the command with a pty channel[1] if the system responds with "sudo requires a tty" or similar
  • Support ssh proxy connections[2], and create an implementation that provides the same behavior whether connecting through a proxy or connecting to the remote host directly.
  • Implement an instance property, platform_info, that will return the remote host's platform info using (python >=2.4)'s platform module

For the platform requirements:

  • Remote system requires python>=2.4
  • architecture, distro, version
  • e.g. Ubuntu 12.04 x86_64 would return
    • {'arch': 'x86_64', 'dist': 'ubuntu', 'version': '12.04'}


 # function signature
 def connect(host, credentials, port=22, timeout=None, proxy=None):
     """Connect to remote host over SSH and return a client connection.
     
     credentials can have:
         username (required)
         password
         private_key
         private_key_file
     proxy can have:
         host (required if proxy supplied)
         username (required if proxy supplied)
         port
         timeout
         password
         private_key
         private_key_file
     """

[1] [2]

  1. 1.0 1.1 paramiko.channel.Channel.get_pty See get_pty().
  2. 2.0 2.1 paramiko.client.SSHClient.connect See sock keyword argument.