Getting Started with ansible-pylibssh

Now that you have read the installation guide and installed ansible-pylibssh on a your system.

Tip

The examples on this page use Python 3.8. If your interpreter is older, you may need to modify the syntax when copying the snippets.

Checking software versions

from pylibsshext import (
    __full_version__,  # string with both ansible-pylibssh and libssh versions
    __libssh_version__,  # linked libssh lib version as a string
    __version__,  # ansible-pylibssh version as a string
    __version_info__,  # ansible-pylibssh version as a tuple
)


print(f'{__full_version__=}')
print(f'{__libssh_version__=}')
print(f'{__version__=}')
print(f'{__version_info__=}')

Creating a SSH session

Attention

The APIs that are shown below, are low-level. You should take a great care to ensure you process any exceptions that arise and always close all the resources once they are no longer necessary.

from pylibsshext.errors import LibsshSessionException
from pylibsshext.session import Session


ssh = Session()

Connecting with remote SSH server

HOST = 'CHANGEME'
USER = 'CHANGEME'
PASSWORD = 'CHANGEME'
TIMEOUT = 30
PORT = 22
try:
    ssh.connect(
        host=HOST,
        user=USER,
        password=PASSWORD,
        timeout=TIMEOUT,
        port=PORT,
    )
except LibsshSessionException as ssh_exc:
    print(f'Failed to connect to {HOST}:{PORT} over SSH: {ssh_exc!s}')

print(f'{ssh.is_connected=}')

Connecting over GSSAPI

Attention

This requires that your libssh is compiled with GSSAPI support enabled.

Using GSSAPI, password or private key is not necessary, but client and service principals may be specified.

ssh.connect(
    host=HOST,
    user=USER,
    timeout=TIMEOUT,
    port=PORT,
    # These parameters are not necessary, but can narrow down which token
    # should be used to connect, similar to specifying a ssh private key
    # gssapi_client_identity="client_principal_name",
    # gssapi_server_identity="server_principal_hostname",
)

Logging events

The ansible-pylibssh is passing all the libssh log messages into the Python logging subsystem by default. This is initialized when new session is created during the Session initialization.

You can configure your loggers and handlers as in any other Python project. The ansible-pylibssh Logger name is 'ansible-pylibssh'.

ssh = Session()

error_handler = logging.StreamHandler()
error_handler.setLevel(logging.ERROR)

debug_handler = logging.FileHandler('ansible-libssh-errors.log')
debug_handler.setLevel(ANSIBLE_PYLIBSSH_TRACE)

logging.getLogger('ansible-pylibssh').addHandler(error_handler)
logging.getLogger('ansible-pylibssh').addHandler(debug_handler)

Attention

When performance is critical, you can use the Session.set_log_level(ANSIBLE_PYLIBSSH_NOLOG) API to prevent libssh from emitting the log messages at the source. Note that it is different from logging.NOTSET which has the opposite semantics.

In addition to standard Python logging levels, the ansible-pylibssh supports two special levels:

ANSIBLE_PYLIBSSH_NOLOG

Indicates that ansible-pylibssh will not emit any events into the logging subsystem.

ANSIBLE_PYLIBSSH_TRACE

Indicates that ansible-pylibssh will make all possible logs available to the logging subsystem, generally useful for debugging low-level libssh operations.

Passing a command and reading response

ssh_channel = ssh.new_channel()
try:
    cmd_resp = ssh_channel.exec_command(b'ls')
    print(f'stdout:\n{cmd_resp.stdout}\n')
    print(f'stderr:\n{cmd_resp.stderr}\n')
    print(f'return code: {cmd_resp.returncode}\n')
finally:
    ssh_channel.close()

Opening a remote shell passing command and receiving response

chan_shell = ssh.invoke_shell()
try:
    chan_shell.sendall(b'ls\n')
    data_b = chan_shell.read_bulk_response(timeout=2, retry=10)
    print(data_b.decode())
finally:
    chan_shell.close()

Fetch file from remote host

Using SCP:

remote_file = '/etc/hosts'
local_file = '/tmp/hosts'
scp = ssh.scp()
scp.get(remote_file, local_file)

Using SFTP:

remote_file = '/etc/hosts'
local_file = '/tmp/hosts'
sftp = ssh.sftp()
try:
    sftp.get(remote_file, local_file)
finally:
    sftp.close()

Copy file to remote host

Using SCP:

remote_file = '/etc/hosts'
local_file = '/tmp/hosts'
scp = ssh.scp()
scp.put(local_file, remote_file)

Using SFTP:

remote_file = '/etc/hosts'
local_file = '/tmp/hosts'
sftp = ssh.sftp()
try:
    sftp.put(remote_file, local_file)
finally:
    sftp.close()

Closing SSH session

ssh.close()