Difference between revisions of "Satori/SSHModuleProposal"
< Satori
m |
Ziad Sawalha (talk | contribs) |
||
Line 1: | Line 1: | ||
== SSH Module Proposal == | == SSH Module Proposal == | ||
− | <big> | + | <big>Implement an SSH wrapper module to enable logging on to servers so we can do [[Satori/glossary|data plane discovery]]</big> |
==== Desired Interface ==== | ==== Desired Interface ==== | ||
− | >>> from satori | + | >>> from satori import ssh |
− | >>> client = | + | >>> 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) | >>> output = client.remote_execute("sudo echo hello", with_exit_code=True) | ||
>>> print output | >>> print output | ||
Line 13: | Line 14: | ||
==== Requirements ==== | ==== 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. | ||
+ | |||
+ | |||
+ | The main functions needed are: | ||
+ | |||
+ | * 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, <code>platform_info</code>, that will return the remote host's platform info using (python >=2.4)'s [http://docs.python.org/2/library/platform.html platform module] | ||
+ | |||
+ | |||
+ | ==== Implementation ==== | ||
+ | * Use [https://github.com/paramiko/paramiko paramiko] and extend its [http://www.lag.net/paramiko/docs/paramiko.SSHClient-class.html 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. | * 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. | * Manage authentication mechanisms, retry authenticating, and prefer SSH keys. | ||
Line 22: | Line 45: | ||
* Support ssh proxy connections<ref name="sshproxy_connections"/>, and create an implementation that provides the same behavior whether connecting through a proxy or connecting to the remote host directly. | * Support ssh proxy connections<ref name="sshproxy_connections"/>, 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, <code>platform_info</code>, that will return the remote host's platform info using (python >=2.4)'s [http://docs.python.org/2/library/platform.html platform module] | * Implement an instance property, <code>platform_info</code>, that will return the remote host's platform info using (python >=2.4)'s [http://docs.python.org/2/library/platform.html platform module] | ||
− | + | ||
− | + | For the platform requirements: | |
− | + | * Remote system requires python>=2.4 | |
− | + | * architecture, distro, version | |
+ | * e.g. Ubuntu 12.04 x86_64 would return | ||
+ | ** <code>{'arch': 'x86_64', 'dist': 'ubuntu', 'version': '12.04'}</code> | ||
+ | |||
+ | |||
+ | # 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 | ||
+ | """ | ||
<ref name="get_pty"> [https://github.com/paramiko/paramiko/blob/master/paramiko/channel.py#L122-L155 paramiko.channel.Channel.get_pty] See <tt>get_pty()</tt>.</ref> | <ref name="get_pty"> [https://github.com/paramiko/paramiko/blob/master/paramiko/channel.py#L122-L155 paramiko.channel.Channel.get_pty] See <tt>get_pty()</tt>.</ref> | ||
<ref name="sshproxy_connections"> [https://github.com/paramiko/paramiko/blob/master/paramiko/client.py#L210-L212 paramiko.client.SSHClient.connect] See <tt>sock</tt> keyword argument.</ref> | <ref name="sshproxy_connections"> [https://github.com/paramiko/paramiko/blob/master/paramiko/client.py#L210-L212 paramiko.client.SSHClient.connect] See <tt>sock</tt> keyword argument.</ref> | ||
<references /> | <references /> |
Revision as of 19:58, 7 March 2014
SSH Module Proposal
Implement an SSH wrapper module to enable logging on to servers so we can do data plane discovery
Desired 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.
The main functions needed are:
- 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.
- Implement/override a
- 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.0 1.1 paramiko.channel.Channel.get_pty See get_pty().
- ↑ 2.0 2.1 paramiko.client.SSHClient.connect See sock keyword argument.