-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the
SshAutoTransport
transport plugin (#6154)
This transport plugin subclasses the `SshTransport` plugin in order to remove all the configuration options. Instead, it parses the user's SSH config file using `paramiko.SSHConfig` when the transport is instantiated to determine the connection parameters automatically. The advantage of this approach is that when configuring a `Computer` using this plugin, the user is not prompted with a bunch of options. Rather, if they can connect to the target machine using `ssh` directly, the transport will also work. What's more, when the user updates their SSH config, the transport automatically uses these changes the next time it is instantiated as opposed to the `SshTransport` plugin which stores the configuration in an `AuthInfo` in the database and is therefore static. The original implementation of this plugin looked into the `fabric` library. This library builds on top of `paramiko` and aims to make configuration SSH connections easier, just as this new plugin was aiming to. However, after a closer look, it seems that fabric was not adding a lot of clever code when it comes to parsing the user's SSH config. It does implement some clever code for dealing with proxy jumps and commands but the `SshTransport` also already implements this. Therefore, it is not really justified to add `fabric` as a dependency but instead we opt to use `paramiko` to parse the config ourselves.
- Loading branch information
Showing
5 changed files
with
87 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
########################################################################### | ||
# Copyright (c), The AiiDA team. All rights reserved. # | ||
# This file is part of the AiiDA code. # | ||
# # | ||
# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # | ||
# For further information on the license, see the LICENSE.txt file # | ||
# For further information please visit http://www.aiida.net # | ||
########################################################################### | ||
"""Plugin for transport over SSH (and SFTP for file transfer).""" | ||
|
||
import pathlib | ||
|
||
import paramiko | ||
|
||
from .ssh import SshTransport | ||
|
||
__all__ = ('SshAutoTransport',) | ||
|
||
|
||
class SshAutoTransport(SshTransport): | ||
"""Support connection, command execution and data transfer to remote computers via SSH+SFTP.""" | ||
|
||
_valid_connect_params = [] | ||
_valid_auth_options = [] | ||
|
||
FILEPATH_CONFIG: pathlib.Path = pathlib.Path('~').expanduser() / '.ssh' / 'config' | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs, key_policy='AutoAddPolicy') | ||
|
||
config_ssh = paramiko.SSHConfig() | ||
|
||
try: | ||
with self.FILEPATH_CONFIG.open() as handle: | ||
config_ssh.parse(handle) | ||
except FileNotFoundError as exception: | ||
raise RuntimeError( | ||
f'Could not determine connection configuration as the `{self.FILEPATH_CONFIG}` does not exist.' | ||
) from exception | ||
except PermissionError as exception: | ||
raise RuntimeError( | ||
f'Could not determine connection configuration as the `{self.FILEPATH_CONFIG}` is not readable.' | ||
) from exception | ||
|
||
if self._machine not in config_ssh.get_hostnames(): | ||
self.logger.warning( | ||
f'The host `{self._machine}` is not defined in SSH config, connection will most likely fail to open.' | ||
) | ||
|
||
config_host = config_ssh.lookup(self._machine) | ||
|
||
self._connect_args = { | ||
'port': config_host.get('port', 22), | ||
'username': config_host.get('user'), | ||
'key_filename': config_host.get('identityfile', []), | ||
'timeout': config_host.get('connecttimeout', 60), | ||
'proxy_command': config_host.get('proxycommand', None), | ||
'proxy_jump': config_host.get('proxyjump', None), | ||
} | ||
|
||
self._machine = config_host['hostname'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters