Jump to: navigation, search

Difference between revisions of "Satori/SSHModuleProposal"

m
(Interface)
Line 4: Line 4:
 
:<big>This wiki page defines the full specification for the [https://blueprints.launchpad.net/satori/+spec/ssh-module ssh-module blueprint].</big>
 
:<big>This wiki page defines the full specification for the [https://blueprints.launchpad.net/satori/+spec/ssh-module ssh-module blueprint].</big>
  
==== Interface ====
+
==== Interface ====  
>>> from satori import ssh
+
  from satori import ssh
>>> creds = {"username": "Tobias", "password": "pa$$word"}
+
  if proxy_ip:
>>> client = ssh.connect("123.456.789.11", credentials=creds) # see signature in implementation section
+
    proxy = ssh.client(proxy_ip, port=22, username=proxy_user, password=proxy_pass)
>>> output = client.remote_execute("sudo echo hello", with_exit_code=True)
+
  else:
  >>> print output
+
    proxy = None
{'stdout': 'hello', 'stderr': <nowiki>''</nowiki>, 'exit_code': 0}
+
 
 
+
  client = ssh.client("10.1.1.20", username="root", password="Password", key=None)
 +
  connection = client.connect(proxy=proxy)
 +
 
 +
  output = connection.remote_execute("sudo echo hello", with_exit_code=True)
 +
  >>> {'stdout': 'hello', 'stderr': <nowiki>''</nowiki>, 'exit_code': 0}
  
 
==== Requirements ====
 
==== Requirements ====

Revision as of 16:43, 10 March 2014

SSH Module Proposal

Implement an SSH wrapper module to enable logging on to servers so we can do data plane discovery.
This wiki page defines the full specification for the ssh-module blueprint.

Interface

 from satori import ssh
 if proxy_ip:
   proxy = ssh.client(proxy_ip, port=22, username=proxy_user, password=proxy_pass)
 else:
   proxy = None
 
 client = ssh.client("10.1.1.20", username="root", password="Password", key=None)
 connection = client.connect(proxy=proxy)
 
 output = connection.remote_execute("sudo echo hello", with_exit_code=True)
>>> {'stdout': 'hello', 'stderr': '', 'exit_code': 0}

Requirements

Support the following logins:

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


Primary class 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.