From d7c69331f517eb0cae83812314d218b7f0dc55a0 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:21:47 +0200 Subject: [PATCH 01/57] added alias parameter this is useful for weird ssh proxies like cyberark PAM. Without this, it is difficult to identify the source of the output, as they all have the same hostname. --- pssh/config.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pssh/config.py b/pssh/config.py index 5c1cc949..9d3970c4 100644 --- a/pssh/config.py +++ b/pssh/config.py @@ -25,7 +25,7 @@ class HostConfig(object): Used to hold individual configuration for each host in ParallelSSHClient host list. """ __slots__ = ('user', 'port', 'password', 'private_key', 'allow_agent', - 'num_retries', 'retry_delay', 'timeout', 'identity_auth', + 'alias', 'num_retries', 'retry_delay', 'timeout', 'identity_auth', 'proxy_host', 'proxy_port', 'proxy_user', 'proxy_password', 'proxy_pkey', 'keepalive_seconds', 'ipv6_only', 'cert_file', 'auth_thread_pool', 'gssapi_auth', 'gssapi_server_identity', 'gssapi_client_identity', 'gssapi_delegate_credentials', @@ -33,7 +33,7 @@ class HostConfig(object): ) def __init__(self, user=None, port=None, password=None, private_key=None, - allow_agent=None, num_retries=None, retry_delay=None, timeout=None, + allow_agent=None, alias=None, num_retries=None, retry_delay=None, timeout=None, identity_auth=None, proxy_host=None, proxy_port=None, proxy_user=None, proxy_password=None, proxy_pkey=None, @@ -58,6 +58,8 @@ def __init__(self, user=None, port=None, password=None, private_key=None, :type private_key: str :param allow_agent: Enable/disable SSH agent authentication. :type allow_agent: bool + :param alias: Use an alias for this host. + :type alias: str or int :param num_retries: Number of retry attempts before giving up on connection and SSH operations. :type num_retries: int @@ -130,6 +132,8 @@ def _sanity_checks(self): raise ValueError("Port %s is not an integer" % (self.port,)) if self.password is not None and not isinstance(self.password, str): raise ValueError("Password %s is not a string" % (self.password,)) + if self.alias is not None and not isinstance(self.alias, (str, int)): + raise ValueError("Alias %s is not a string or integer" % (self.alias,)) if self.private_key is not None and not ( isinstance(self.private_key, str) or isinstance(self.private_key, bytes) ): From f3a11def21372fb0aa8ba4b507f5644315415135 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:27:31 +0200 Subject: [PATCH 02/57] added alias parameter --- pssh/output.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pssh/output.py b/pssh/output.py index c7e9375e..6f94af33 100644 --- a/pssh/output.py +++ b/pssh/output.py @@ -56,12 +56,12 @@ class HostOutput(object): __slots__ = ('host', 'channel', 'stdin', 'client', 'exception', 'encoding', 'read_timeout', - 'buffers', + 'buffers', 'alias', ) def __init__(self, host, channel, stdin, client, exception=None, encoding='utf-8', read_timeout=None, - buffers=None): + buffers=None, alias): """ :param host: Host name output is for :type host: str @@ -77,6 +77,8 @@ def __init__(self, host, channel, stdin, :type read_timeout: float :param buffers: Host buffer data. :type buffers: :py:class:`HostOutputBuffers` + :param alias: Host alias. + :type alias: str or int """ self.host = host self.channel = channel @@ -86,6 +88,7 @@ def __init__(self, host, channel, stdin, self.encoding = encoding self.read_timeout = read_timeout self.buffers = buffers + self.alias = alias @property def stdout(self): From 2024ac3ab809afa9a51eb4a09a9746386980b9de Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:38:30 +0200 Subject: [PATCH 03/57] fix syntax error SyntaxError: non-default argument follows default argument --- pssh/output.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pssh/output.py b/pssh/output.py index 6f94af33..658ec217 100644 --- a/pssh/output.py +++ b/pssh/output.py @@ -55,13 +55,13 @@ class HostOutput(object): """Host output""" __slots__ = ('host', 'channel', 'stdin', - 'client', 'exception', 'encoding', 'read_timeout', - 'buffers', 'alias', + 'client', 'alias', 'exception', + 'encoding', 'read_timeout', 'buffers', ) def __init__(self, host, channel, stdin, - client, exception=None, encoding='utf-8', read_timeout=None, - buffers=None, alias): + client, alias, exception=None, encoding='utf-8', read_timeout=None, + buffers=None): """ :param host: Host name output is for :type host: str @@ -71,24 +71,24 @@ def __init__(self, host, channel, stdin, :type stdin: :py:func:`file`-like object :param client: `SSHClient` output is coming from. :type client: :py:class:`pssh.clients.base.single.BaseSSHClient` + :param alias: Host alias. + :type alias: str or int :param exception: Exception from host if any :type exception: :py:class:`Exception` or ``None`` :param read_timeout: Timeout in seconds for reading from buffers. :type read_timeout: float :param buffers: Host buffer data. :type buffers: :py:class:`HostOutputBuffers` - :param alias: Host alias. - :type alias: str or int """ self.host = host self.channel = channel self.stdin = stdin self.client = client + self.alias = alias self.exception = exception self.encoding = encoding self.read_timeout = read_timeout self.buffers = buffers - self.alias = alias @property def stdout(self): From d657374025cffa4072ac6856ef861f69d0f43b93 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:56:16 +0200 Subject: [PATCH 04/57] added alias parameter --- tests/test_host_config.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_host_config.py b/tests/test_host_config.py index 0bdf863c..5f6a8b7c 100644 --- a/tests/test_host_config.py +++ b/tests/test_host_config.py @@ -26,6 +26,7 @@ def test_host_config_entries(self): user = 'user' port = 22 password = 'password' + alias = 'alias' private_key = 'private key' allow_agent = False num_retries = 1 @@ -43,7 +44,7 @@ def test_host_config_entries(self): gssapi_client_identity = 'some_id' gssapi_delegate_credentials = True cfg = HostConfig( - user=user, port=port, password=password, private_key=private_key, + user=user, port=port, password=password, alias=alias, private_key=private_key, allow_agent=allow_agent, num_retries=num_retries, retry_delay=retry_delay, timeout=timeout, identity_auth=identity_auth, proxy_host=proxy_host, ipv6_only=ipv6_only, @@ -59,6 +60,7 @@ def test_host_config_entries(self): self.assertEqual(cfg.user, user) self.assertEqual(cfg.port, port) self.assertEqual(cfg.password, password) + self.assertEqual(cfg.alias, alias) self.assertEqual(cfg.private_key, private_key) self.assertEqual(cfg.allow_agent, allow_agent) self.assertEqual(cfg.num_retries, num_retries) @@ -79,6 +81,7 @@ def test_host_config_bad_entries(self): self.assertRaises(ValueError, HostConfig, user=22) self.assertRaises(ValueError, HostConfig, password=22) self.assertRaises(ValueError, HostConfig, port='22') + self.assertRaises(ValueError, HostConfig, alias=2.2) self.assertRaises(ValueError, HostConfig, private_key=1) self.assertRaises(ValueError, HostConfig, allow_agent=1) self.assertRaises(ValueError, HostConfig, num_retries='') From ac085bcd906ae58505a7da0a44b5ab1992bcd8fa Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 11:14:46 +0200 Subject: [PATCH 05/57] fix: alias is optional --- pssh/output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/output.py b/pssh/output.py index 658ec217..98acecaa 100644 --- a/pssh/output.py +++ b/pssh/output.py @@ -60,7 +60,7 @@ class HostOutput(object): ) def __init__(self, host, channel, stdin, - client, alias, exception=None, encoding='utf-8', read_timeout=None, + client, alias=None, exception=None, encoding='utf-8', read_timeout=None, buffers=None): """ :param host: Host name output is for From f02b6c64784aa361bbfb6bd60fd0c85a59d36738 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:18:25 +0200 Subject: [PATCH 06/57] add alias parameter to self stupid mistake --- pssh/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pssh/config.py b/pssh/config.py index 9d3970c4..723b5d1e 100644 --- a/pssh/config.py +++ b/pssh/config.py @@ -105,6 +105,7 @@ def __init__(self, user=None, port=None, password=None, private_key=None, self.password = password self.private_key = private_key self.allow_agent = allow_agent + self.alias = alias self.num_retries = num_retries self.timeout = timeout self.retry_delay = retry_delay From 35f11e8dfc0669460e3694e9f27649e157946194 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:49:50 +0200 Subject: [PATCH 07/57] add test: if alias passes through properly --- tests/native/test_parallel_client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 5b760985..db4a1f14 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -930,6 +930,7 @@ def test_host_config(self): servers = [] password = 'overriden_pass' fake_key = 'FAKE KEY' + alias = ["alias " + host for host in hosts] for host_i, (host, port) in enumerate(hosts): server = OpenSSHServer(listen_ip=host, port=port) server.start_server() @@ -937,6 +938,7 @@ def test_host_config(self): host_config[host_i].user = self.user host_config[host_i].password = password host_config[host_i].private_key = self.user_key + host_config[host_i].alias = alias[host_i] servers.append(server) host_config[1].private_key = fake_key client = ParallelSSHClient([h for h, _ in hosts], @@ -954,6 +956,8 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) + for idx, alias_ in enumerate(alias): + self.assertEqual(client._host_clients[idx, hosts[0][0]].alias, alias_) for server in servers: server.stop() From e17d3c973dbd640fbbf41f676ef401130cd16d35 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:52:56 +0200 Subject: [PATCH 08/57] update alias passthrough test --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index db4a1f14..83d1c67b 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -930,7 +930,7 @@ def test_host_config(self): servers = [] password = 'overriden_pass' fake_key = 'FAKE KEY' - alias = ["alias " + host for host in hosts] + alias = [f"alias {host}" for host in hosts] for host_i, (host, port) in enumerate(hosts): server = OpenSSHServer(listen_ip=host, port=port) server.start_server() From 0892b6bf7ea75c881df59f251deced051dca183c Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:56:13 +0200 Subject: [PATCH 09/57] update alias test - look in output, not client --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 83d1c67b..d1af8a69 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -957,7 +957,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) for idx, alias_ in enumerate(alias): - self.assertEqual(client._host_clients[idx, hosts[0][0]].alias, alias_) + self.assertEqual(output[idx].alias, alias_) for server in servers: server.stop() From afa6c92681c792246683b0712b01d65a498c0107 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:05:24 +0200 Subject: [PATCH 10/57] add alias parameter --- pssh/clients/native/parallel.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pssh/clients/native/parallel.py b/pssh/clients/native/parallel.py index 0b95a51e..f5374567 100644 --- a/pssh/clients/native/parallel.py +++ b/pssh/clients/native/parallel.py @@ -29,7 +29,7 @@ class ParallelSSHClient(BaseParallelSSHClient): """ssh2-python based parallel client.""" - def __init__(self, hosts, user=None, password=None, port=22, pkey=None, + def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=None, num_retries=DEFAULT_RETRIES, timeout=None, pool_size=100, allow_agent=True, host_config=None, retry_delay=RETRY_DELAY, proxy_host=None, proxy_port=None, @@ -46,6 +46,8 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, :param password: (Optional) Password to use for login. Defaults to no password :type password: str + :param alias: Use an alias for this host. + :type alias: str or int :param port: (Optional) Port number to use for SSH connection. Defaults to 22. :type port: int @@ -121,7 +123,7 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, """ BaseParallelSSHClient.__init__( self, hosts, user=user, password=password, port=port, pkey=pkey, - allow_agent=allow_agent, num_retries=num_retries, + alias=alias, allow_agent=allow_agent, num_retries=num_retries, timeout=timeout, pool_size=pool_size, host_config=host_config, retry_delay=retry_delay, identity_auth=identity_auth, @@ -231,6 +233,7 @@ def _make_ssh_client(self, host, cfg, _pkey_data): _client = SSHClient( host, user=cfg.user or self.user, password=cfg.password or self.password, port=cfg.port or self.port, pkey=_pkey_data, num_retries=cfg.num_retries or self.num_retries, + alias=cfg.alias or self.alias, timeout=cfg.timeout or self.timeout, allow_agent=cfg.allow_agent or self.allow_agent, retry_delay=cfg.retry_delay or self.retry_delay, proxy_host=cfg.proxy_host or self.proxy_host, From 207dedc4121b0b15e2b83d59ae7dd359f7996a63 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:16:35 +0200 Subject: [PATCH 11/57] add alias parameter --- pssh/clients/native/single.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pssh/clients/native/single.py b/pssh/clients/native/single.py index 2dc4e7cf..03f69f6f 100644 --- a/pssh/clients/native/single.py +++ b/pssh/clients/native/single.py @@ -50,7 +50,7 @@ class SSHClient(BaseSSHClient): def __init__(self, host, user=None, password=None, port=None, - pkey=None, + pkey=None, alias=None, num_retries=DEFAULT_RETRIES, retry_delay=RETRY_DELAY, allow_agent=True, timeout=None, @@ -70,6 +70,8 @@ def __init__(self, host, :type user: str :param password: Password to use for password authentication. :type password: str + :param alias: Use an alias for this host. + :type alias: str or int :param port: SSH port to connect to. Defaults to SSH default (22) :type port: int :param pkey: Private key file path to use for authentication. Path must @@ -133,7 +135,7 @@ def __init__(self, host, proxy_host = '127.0.0.1' self._chan_lock = RLock() super(SSHClient, self).__init__( - host, user=user, password=password, port=port, pkey=pkey, + host, user=user, password=password, alias=alias, port=port, pkey=pkey, num_retries=num_retries, retry_delay=retry_delay, allow_agent=allow_agent, _auth_thread_pool=_auth_thread_pool, timeout=timeout, @@ -146,7 +148,7 @@ def _shell(self, channel): return self._eagain(channel.shell) def _connect_proxy(self, proxy_host, proxy_port, proxy_pkey, - user=None, password=None, + user=None, password=None, alias=None, num_retries=DEFAULT_RETRIES, retry_delay=RETRY_DELAY, allow_agent=True, timeout=None, @@ -156,7 +158,7 @@ def _connect_proxy(self, proxy_host, proxy_port, proxy_pkey, assert isinstance(self.port, int) try: self._proxy_client = SSHClient( - proxy_host, port=proxy_port, pkey=proxy_pkey, + proxy_host, port=proxy_port, pkey=proxy_pkey, alias=alias, num_retries=num_retries, user=user, password=password, retry_delay=retry_delay, allow_agent=allow_agent, timeout=timeout, forward_ssh_agent=forward_ssh_agent, From 42a077b3d2b10e056bc4aee9600dfa76e8081d2f Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:34:29 +0200 Subject: [PATCH 12/57] added alias parameter --- pssh/clients/base/parallel.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 43f05db1..0a2f0856 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -36,7 +36,7 @@ class BaseParallelSSHClient(object): """Parallel client base class.""" - def __init__(self, hosts, user=None, password=None, port=None, pkey=None, + def __init__(self, hosts, user=None, password=None, port=None, pkey=None, alias=None, allow_agent=True, num_retries=DEFAULT_RETRIES, timeout=120, pool_size=10, @@ -64,6 +64,7 @@ def __init__(self, hosts, user=None, password=None, port=None, pkey=None, self.user = user self.password = password self.port = port + self.alias = alias self.pkey = pkey self.num_retries = num_retries self.timeout = timeout @@ -259,7 +260,7 @@ def get_last_output(self, cmds=None): def _get_host_config(self, host_i, host): if self.host_config is None: config = HostConfig( - user=self.user, port=self.port, password=self.password, private_key=self.pkey, + user=self.user, port=self.port, password=self.password, private_key=self.pkey, alias=self.alias, allow_agent=self.allow_agent, num_retries=self.num_retries, retry_delay=self.retry_delay, timeout=self.timeout, identity_auth=self.identity_auth, proxy_host=self.proxy_host, proxy_port=self.proxy_port, proxy_user=self.proxy_user, proxy_password=self.proxy_password, From 694fbc9326d82366be0345cdf5a09b6197d3e7ef Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:35:38 +0200 Subject: [PATCH 13/57] added alias parameter --- pssh/clients/ssh/parallel.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pssh/clients/ssh/parallel.py b/pssh/clients/ssh/parallel.py index bd7a11a8..198fc914 100644 --- a/pssh/clients/ssh/parallel.py +++ b/pssh/clients/ssh/parallel.py @@ -30,7 +30,7 @@ class ParallelSSHClient(BaseParallelSSHClient): """ssh-python based parallel client.""" def __init__(self, hosts, user=None, password=None, port=22, pkey=None, - cert_file=None, + cert_file=None, alias=None, num_retries=DEFAULT_RETRIES, timeout=None, pool_size=100, allow_agent=True, host_config=None, retry_delay=RETRY_DELAY, forward_ssh_agent=False, @@ -49,6 +49,8 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, :param password: (Optional) Password to use for login. Defaults to no password :type password: str + :param alias: Use an alias for this host. + :type alias: str or int :param port: (Optional) Port number to use for SSH connection. Defaults to 22. :type port: int @@ -119,7 +121,7 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, provided private key. """ BaseParallelSSHClient.__init__( - self, hosts, user=user, password=password, port=port, pkey=pkey, + self, hosts, user=user, password=password, port=port, pkey=pkey, alias=alias, allow_agent=allow_agent, num_retries=num_retries, timeout=timeout, pool_size=pool_size, host_config=host_config, retry_delay=retry_delay, @@ -217,6 +219,7 @@ def _make_ssh_client(self, host, cfg, _pkey_data): _client = SSHClient( host, user=cfg.user or self.user, password=cfg.password or self.password, port=cfg.port or self.port, pkey=_pkey_data, num_retries=cfg.num_retries or self.num_retries, + alias=cfg.alias or self.alias, timeout=cfg.timeout or self.timeout, allow_agent=cfg.allow_agent or self.allow_agent, retry_delay=cfg.retry_delay or self.retry_delay, _auth_thread_pool=cfg.auth_thread_pool or self._auth_thread_pool, From d48593f4dbe5e3aa70a742ec84d5e86312f4520b Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:44:24 +0200 Subject: [PATCH 14/57] add alias parameter --- pssh/clients/ssh/single.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pssh/clients/ssh/single.py b/pssh/clients/ssh/single.py index 855ada98..6caa93a6 100644 --- a/pssh/clients/ssh/single.py +++ b/pssh/clients/ssh/single.py @@ -40,7 +40,7 @@ class SSHClient(BaseSSHClient): def __init__(self, host, user=None, password=None, port=None, - pkey=None, + pkey=None, alias=None, cert_file=None, num_retries=DEFAULT_RETRIES, retry_delay=RETRY_DELAY, @@ -60,6 +60,8 @@ def __init__(self, host, :type password: str :param port: SSH port to connect to. Defaults to SSH default (22) :type port: int + :param alias: Use an alias for this host. + :type alias: str or int :param pkey: Private key file path to use for authentication. Path must be either absolute path or relative to user home directory like ``~/``. @@ -114,7 +116,7 @@ def __init__(self, host, self.gssapi_client_identity = gssapi_client_identity self.gssapi_delegate_credentials = gssapi_delegate_credentials super(SSHClient, self).__init__( - host, user=user, password=password, port=port, pkey=pkey, + host, user=user, password=password, port=port, pkey=pkey, alias=alias, num_retries=num_retries, retry_delay=retry_delay, allow_agent=allow_agent, _auth_thread_pool=_auth_thread_pool, From 8b9c02125c8ea430349ae43152f66aa9c2edb369 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:45:49 +0200 Subject: [PATCH 15/57] added alias parameter --- pssh/clients/base/single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/base/single.py b/pssh/clients/base/single.py index 4255a14f..8fc14eec 100644 --- a/pssh/clients/base/single.py +++ b/pssh/clients/base/single.py @@ -159,7 +159,7 @@ class BaseSSHClient(object): def __init__(self, host, user=None, password=None, port=None, - pkey=None, + pkey=None, alias=None, num_retries=DEFAULT_RETRIES, retry_delay=RETRY_DELAY, allow_agent=True, timeout=None, From 23d070a8e2bb1dba5ebbc53e6bdb9c9799b0ea99 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:57:59 +0200 Subject: [PATCH 16/57] look for alias in client instead --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index d1af8a69..83d1c67b 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -957,7 +957,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) for idx, alias_ in enumerate(alias): - self.assertEqual(output[idx].alias, alias_) + self.assertEqual(client._host_clients[idx, hosts[0][0]].alias, alias_) for server in servers: server.stop() From ce298fd9cc6e861ccd3903adf0004985ed425284 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:14:14 +0200 Subject: [PATCH 17/57] test --- tests/native/test_parallel_client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 83d1c67b..3d4582e9 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -957,6 +957,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) for idx, alias_ in enumerate(alias): + print(client._host_clients[idx, hosts[0][0]]) self.assertEqual(client._host_clients[idx, hosts[0][0]].alias, alias_) for server in servers: server.stop() From 433daa436116c307c067f5ea1cedc9d7ff6d26d3 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:26:22 +0200 Subject: [PATCH 18/57] pass alias to run_command --- pssh/clients/native/parallel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pssh/clients/native/parallel.py b/pssh/clients/native/parallel.py index f5374567..229fff33 100644 --- a/pssh/clients/native/parallel.py +++ b/pssh/clients/native/parallel.py @@ -140,7 +140,7 @@ def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=No def run_command(self, command, sudo=False, user=None, stop_on_errors=True, use_pty=False, host_args=None, shell=None, - encoding='utf-8', read_timeout=None, + encoding='utf-8', read_timeout=None, alias=None, ): """Run command on all hosts in parallel, honoring self.pool_size, and return output. @@ -215,7 +215,7 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, self, command, stop_on_errors=stop_on_errors, host_args=host_args, user=user, shell=shell, sudo=sudo, encoding=encoding, use_pty=use_pty, - read_timeout=read_timeout, + read_timeout=read_timeout, alias=alias, ) def __del__(self): From e6501f0e7d43e492912438e0038ebd608e018ab1 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:26:34 +0200 Subject: [PATCH 19/57] look for alias in output --- tests/native/test_parallel_client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 3d4582e9..63a0d59c 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -957,8 +957,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) for idx, alias_ in enumerate(alias): - print(client._host_clients[idx, hosts[0][0]]) - self.assertEqual(client._host_clients[idx, hosts[0][0]].alias, alias_) + self.assertTrue(alias_ in output[idx]) for server in servers: server.stop() From 26fc4f63e41233872e52ff8a50bbd357d25129ad Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:28:30 +0200 Subject: [PATCH 20/57] update docstring --- pssh/clients/native/parallel.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pssh/clients/native/parallel.py b/pssh/clients/native/parallel.py index 229fff33..5a4d9059 100644 --- a/pssh/clients/native/parallel.py +++ b/pssh/clients/native/parallel.py @@ -117,6 +117,8 @@ def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=No for the host(s) or raise NoIPv6AddressFoundError otherwise. Note this will disable connecting to an IPv4 address if an IP address is provided instead. :type ipv6_only: bool + :param alias: Use an alias for this host. + :type alias: str or int :raises: :py:class:`pssh.exceptions.PKeyFileError` on errors finding provided private key. @@ -185,6 +187,8 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, :param encoding: Encoding to use for command string and output. Must be valid `Python codec `_ :type encoding: str + :param alias: Use an alias for this host. + :type alias: str or int :param read_timeout: (Optional) Timeout in seconds for reading from stdout or stderr. Reading from stdout/stderr will raise :py:class:`pssh.exceptions.Timeout` From 074ededb5cff89e7374b37af7ade5bb0a9eac4bd Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:30:56 +0200 Subject: [PATCH 21/57] add alias parameter to run_command --- pssh/clients/ssh/parallel.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pssh/clients/ssh/parallel.py b/pssh/clients/ssh/parallel.py index 198fc914..df82de8e 100644 --- a/pssh/clients/ssh/parallel.py +++ b/pssh/clients/ssh/parallel.py @@ -138,7 +138,7 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, def run_command(self, command, sudo=False, user=None, stop_on_errors=True, use_pty=False, host_args=None, shell=None, - encoding='utf-8', read_timeout=None, + encoding='utf-8', read_timeout=None, alias=None, ): """Run command on all hosts in parallel, honoring self.pool_size, and return output. @@ -163,6 +163,8 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, :param user: (Optional) User to run command as. Requires sudo access for that user from the logged in user account. :type user: str + :param alias: Use an alias for this host. + :type alias: str or int :param stop_on_errors: (Optional) Raise exception on errors running command. Defaults to True. With stop_on_errors set to False, exceptions are instead added to output of `run_command`. See example @@ -212,7 +214,7 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, self, command, stop_on_errors=stop_on_errors, host_args=host_args, user=user, shell=shell, sudo=sudo, encoding=encoding, use_pty=use_pty, - read_timeout=read_timeout, + read_timeout=read_timeout, alias=alias, ) def _make_ssh_client(self, host, cfg, _pkey_data): From 5929b9d287f3b4f9c8b93682d2ffb224b2445b67 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:33:12 +0200 Subject: [PATCH 22/57] add alias to open_shell --- pssh/clients/base/single.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pssh/clients/base/single.py b/pssh/clients/base/single.py index 8fc14eec..ac86b350 100644 --- a/pssh/clients/base/single.py +++ b/pssh/clients/base/single.py @@ -225,7 +225,7 @@ def __enter__(self): def __exit__(self, *args): self.disconnect() - def open_shell(self, encoding='utf-8', read_timeout=None): + def open_shell(self, encoding='utf-8', read_timeout=None, alias=None): """Open interactive shell on new channel. Can be used as context manager - ``with open_shell() as shell``. @@ -236,7 +236,7 @@ def open_shell(self, encoding='utf-8', read_timeout=None): :type read_timeout: float """ chan = self.open_session() - shell = InteractiveShell(chan, self, encoding=encoding, read_timeout=read_timeout) + shell = InteractiveShell(chan, self, encoding=encoding, read_timeout=read_timeout, alias=alias) return shell def _shell(self, channel): From ad5a813d6afbaefcbed10973150757771cc328d0 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:39:46 +0200 Subject: [PATCH 23/57] update alias test --- tests/native/test_parallel_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 63a0d59c..5572543a 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -956,8 +956,8 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - for idx, alias_ in enumerate(alias): - self.assertTrue(alias_ in output[idx]) + for alias_ in alias: + self.assertTrue(alias_ in output) for server in servers: server.stop() From e158623e61fc47837c8ddcfb05c088b83aa03411 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:45:59 +0200 Subject: [PATCH 24/57] add alias to alias --- pssh/clients/base/parallel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 0a2f0856..f47ff6b5 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -199,7 +199,7 @@ def join_shells(self, shells, timeout=None): def run_command(self, command, user=None, stop_on_errors=True, host_args=None, use_pty=False, shell=None, - encoding='utf-8', + encoding='utf-8', alias=None, *args, **kwargs): if host_args: try: From 3e6db9b085f545deea177305c2389d1e5aa5f5fc Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:52:00 +0200 Subject: [PATCH 25/57] remove alias from open_shell, add to init.. --- pssh/clients/base/single.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pssh/clients/base/single.py b/pssh/clients/base/single.py index ac86b350..1ab5aa0a 100644 --- a/pssh/clients/base/single.py +++ b/pssh/clients/base/single.py @@ -171,6 +171,7 @@ def __init__(self, host, ): self._auth_thread_pool = _auth_thread_pool self.host = host + self.alias = alias self.user = user if user else getuser() self.password = password self.port = port if port else 22 @@ -225,7 +226,7 @@ def __enter__(self): def __exit__(self, *args): self.disconnect() - def open_shell(self, encoding='utf-8', read_timeout=None, alias=None): + def open_shell(self, encoding='utf-8', read_timeout=None): """Open interactive shell on new channel. Can be used as context manager - ``with open_shell() as shell``. @@ -236,7 +237,7 @@ def open_shell(self, encoding='utf-8', read_timeout=None, alias=None): :type read_timeout: float """ chan = self.open_session() - shell = InteractiveShell(chan, self, encoding=encoding, read_timeout=read_timeout, alias=alias) + shell = InteractiveShell(chan, self, encoding=encoding, read_timeout=read_timeout) return shell def _shell(self, channel): From 1a66230fc8f0a0d83ad48bcda534fef1aeb6247d Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:01:27 +0200 Subject: [PATCH 26/57] update alias test --- tests/native/test_parallel_client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 5572543a..65191ebd 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -930,7 +930,7 @@ def test_host_config(self): servers = [] password = 'overriden_pass' fake_key = 'FAKE KEY' - alias = [f"alias {host}" for host in hosts] + aliases = [f"alias {host}" for host in hosts] for host_i, (host, port) in enumerate(hosts): server = OpenSSHServer(listen_ip=host, port=port) server.start_server() @@ -938,7 +938,7 @@ def test_host_config(self): host_config[host_i].user = self.user host_config[host_i].password = password host_config[host_i].private_key = self.user_key - host_config[host_i].alias = alias[host_i] + host_config[host_i].alias = aliases[host_i] servers.append(server) host_config[1].private_key = fake_key client = ParallelSSHClient([h for h, _ in hosts], @@ -956,8 +956,8 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - for alias_ in alias: - self.assertTrue(alias_ in output) + self.assertTrue(any(aliases) in client._host_clients[0, hosts[0][0]].alias, + msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") for server in servers: server.stop() From 5aff92eab1313f08bc139d2c4fffb3d0d367bcc2 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:03:01 +0200 Subject: [PATCH 27/57] update alias test --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 65191ebd..a912b6bd 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -956,7 +956,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - self.assertTrue(any(aliases) in client._host_clients[0, hosts[0][0]].alias, + self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") for server in servers: server.stop() From 40887ed9864897bb61b8054428fbdba00b4504de Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:20:21 +0200 Subject: [PATCH 28/57] add test for duplicate aliases --- tests/native/test_parallel_client.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index a912b6bd..d8b3aec2 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -958,6 +958,9 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") + client_aliases = [client._host_clients[idx, hosts[0][0]].alias for idx in range(len(output))] + self.assertTrue(len(set(client_aliases), len(aliases), + msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: server.stop() From dcc438d85d70d59427714476575c089ac86411a3 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:22:13 +0200 Subject: [PATCH 29/57] dumb syntax error --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index d8b3aec2..7a6c88e3 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -959,7 +959,7 @@ def test_host_config(self): self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") client_aliases = [client._host_clients[idx, hosts[0][0]].alias for idx in range(len(output))] - self.assertTrue(len(set(client_aliases), len(aliases), + self.assertTrue(len(set(client_aliases)), len(aliases), msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: server.stop() From 11d78f82ff902256a6e28483f8a312b237405822 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:24:02 +0200 Subject: [PATCH 30/57] another dumb syntax error --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 7a6c88e3..d352ac31 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -959,7 +959,7 @@ def test_host_config(self): self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") client_aliases = [client._host_clients[idx, hosts[0][0]].alias for idx in range(len(output))] - self.assertTrue(len(set(client_aliases)), len(aliases), + self.assertTrue(len(set(client_aliases)) == len(aliases), msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: server.stop() From c24cd5d9e352350ee368730e4e700ada4b2125d6 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:40:56 +0200 Subject: [PATCH 31/57] fix alias duplicate test --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index d352ac31..ac3b3442 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -958,7 +958,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") - client_aliases = [client._host_clients[idx, hosts[0][0]].alias for idx in range(len(output))] + client_aliases = [client._host_clients[idx, hosts[idx][0]].alias for idx in range(len(output))] self.assertTrue(len(set(client_aliases)) == len(aliases), msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: From a8d36a1e4a89330ad2fbdbc93c05bff63d17ba39 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:08:07 +0200 Subject: [PATCH 32/57] fix unpacking of _host_clients tuple --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index ac3b3442..0d994f0f 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -958,7 +958,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") - client_aliases = [client._host_clients[idx, hosts[idx][0]].alias for idx in range(len(output))] + client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]]) self.assertTrue(len(set(client_aliases)) == len(aliases), msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: From afdd0186e54b2d9d294669fc4d0409b541e675f2 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:09:49 +0200 Subject: [PATCH 33/57] another dumb syntax error - it's getting late.. --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 0d994f0f..3d70906e 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -958,7 +958,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") - client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]]) + client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]] self.assertTrue(len(set(client_aliases)) == len(aliases), msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: From eb512202a53cee2a610fbaebf21db0bf489675b3 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:16:15 +0200 Subject: [PATCH 34/57] fix alias test. --- tests/native/test_parallel_client.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 3d70906e..8cd7d689 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -945,6 +945,14 @@ def test_host_config(self): host_config=host_config, num_retries=1) output = client.run_command(self.cmd, stop_on_errors=False) + + # this needs to happen before client.join + client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]] + self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, + msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") + self.assertTrue(len(set(client_aliases)) == len(aliases), + msg=f"Alias passthrough problem: client_aliases contain duplicate values. Expected {aliases} but got {client_aliases}") + client.join(output) self.assertEqual(len(hosts), len(output)) try: @@ -956,11 +964,6 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, - msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") - client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]] - self.assertTrue(len(set(client_aliases)) == len(aliases), - msg=f"Alias passthrough problem: {client_aliases} contain duplicate values. Expected {aliases}") for server in servers: server.stop() From e0e42a47178ecd53f20845d929aac3502f772f7f Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:23:10 +0200 Subject: [PATCH 35/57] this cant work because of how the rest works it's getting late here.. --- tests/native/test_parallel_client.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 8cd7d689..e2b0e5a4 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -946,13 +946,6 @@ def test_host_config(self): num_retries=1) output = client.run_command(self.cmd, stop_on_errors=False) - # this needs to happen before client.join - client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]] - self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, - msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") - self.assertTrue(len(set(client_aliases)) == len(aliases), - msg=f"Alias passthrough problem: client_aliases contain duplicate values. Expected {aliases} but got {client_aliases}") - client.join(output) self.assertEqual(len(hosts), len(output)) try: @@ -964,6 +957,15 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) + + client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]] + self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, + msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") + + ### this works but requires more than one successful connection. for example if n hosts was 3, not 2. + # self.assertEqual(len(set(client_aliases)), len(aliases), + # msg=f"Alias passthrough problem: client_aliases contain duplicate values. Expected {aliases} but got {client_aliases}") + ### for server in servers: server.stop() From 694ad1e7b8892d65beec810e0803b51f3010b062 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 19:19:31 +0200 Subject: [PATCH 36/57] alias should be per host --- pssh/clients/base/parallel.py | 7 +++---- pssh/clients/base/single.py | 2 +- pssh/clients/native/parallel.py | 16 +++++----------- pssh/clients/native/single.py | 1 + pssh/clients/ssh/parallel.py | 14 +++++--------- pssh/output.py | 3 ++- tests/native/test_parallel_client.py | 10 ++-------- 7 files changed, 19 insertions(+), 34 deletions(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index f47ff6b5..43f05db1 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -36,7 +36,7 @@ class BaseParallelSSHClient(object): """Parallel client base class.""" - def __init__(self, hosts, user=None, password=None, port=None, pkey=None, alias=None, + def __init__(self, hosts, user=None, password=None, port=None, pkey=None, allow_agent=True, num_retries=DEFAULT_RETRIES, timeout=120, pool_size=10, @@ -64,7 +64,6 @@ def __init__(self, hosts, user=None, password=None, port=None, pkey=None, alias= self.user = user self.password = password self.port = port - self.alias = alias self.pkey = pkey self.num_retries = num_retries self.timeout = timeout @@ -199,7 +198,7 @@ def join_shells(self, shells, timeout=None): def run_command(self, command, user=None, stop_on_errors=True, host_args=None, use_pty=False, shell=None, - encoding='utf-8', alias=None, + encoding='utf-8', *args, **kwargs): if host_args: try: @@ -260,7 +259,7 @@ def get_last_output(self, cmds=None): def _get_host_config(self, host_i, host): if self.host_config is None: config = HostConfig( - user=self.user, port=self.port, password=self.password, private_key=self.pkey, alias=self.alias, + user=self.user, port=self.port, password=self.password, private_key=self.pkey, allow_agent=self.allow_agent, num_retries=self.num_retries, retry_delay=self.retry_delay, timeout=self.timeout, identity_auth=self.identity_auth, proxy_host=self.proxy_host, proxy_port=self.proxy_port, proxy_user=self.proxy_user, proxy_password=self.proxy_password, diff --git a/pssh/clients/base/single.py b/pssh/clients/base/single.py index 1ab5aa0a..17db66d4 100644 --- a/pssh/clients/base/single.py +++ b/pssh/clients/base/single.py @@ -410,7 +410,7 @@ def _make_host_output(self, channel, encoding, read_timeout): stdout=BufferData(rw_buffer=_stdout_buffer, reader=_stdout_reader), stderr=BufferData(rw_buffer=_stderr_buffer, reader=_stderr_reader)) host_out = HostOutput( - host=self.host, channel=channel, stdin=Stdin(channel, self), + host=self.host, alias=self.alias, channel=channel, stdin=Stdin(channel, self), client=self, encoding=encoding, read_timeout=read_timeout, buffers=_buffers, ) diff --git a/pssh/clients/native/parallel.py b/pssh/clients/native/parallel.py index 5a4d9059..9cb94995 100644 --- a/pssh/clients/native/parallel.py +++ b/pssh/clients/native/parallel.py @@ -29,7 +29,7 @@ class ParallelSSHClient(BaseParallelSSHClient): """ssh2-python based parallel client.""" - def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=None, + def __init__(self, hosts, user=None, password=None, port=22, pkey=None, num_retries=DEFAULT_RETRIES, timeout=None, pool_size=100, allow_agent=True, host_config=None, retry_delay=RETRY_DELAY, proxy_host=None, proxy_port=None, @@ -46,8 +46,6 @@ def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=No :param password: (Optional) Password to use for login. Defaults to no password :type password: str - :param alias: Use an alias for this host. - :type alias: str or int :param port: (Optional) Port number to use for SSH connection. Defaults to 22. :type port: int @@ -117,15 +115,13 @@ def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=No for the host(s) or raise NoIPv6AddressFoundError otherwise. Note this will disable connecting to an IPv4 address if an IP address is provided instead. :type ipv6_only: bool - :param alias: Use an alias for this host. - :type alias: str or int :raises: :py:class:`pssh.exceptions.PKeyFileError` on errors finding provided private key. """ BaseParallelSSHClient.__init__( self, hosts, user=user, password=password, port=port, pkey=pkey, - alias=alias, allow_agent=allow_agent, num_retries=num_retries, + allow_agent=allow_agent, num_retries=num_retries, timeout=timeout, pool_size=pool_size, host_config=host_config, retry_delay=retry_delay, identity_auth=identity_auth, @@ -142,7 +138,7 @@ def __init__(self, hosts, user=None, password=None, port=22, alias=None, pkey=No def run_command(self, command, sudo=False, user=None, stop_on_errors=True, use_pty=False, host_args=None, shell=None, - encoding='utf-8', read_timeout=None, alias=None, + encoding='utf-8', read_timeout=None, ): """Run command on all hosts in parallel, honoring self.pool_size, and return output. @@ -187,8 +183,6 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, :param encoding: Encoding to use for command string and output. Must be valid `Python codec `_ :type encoding: str - :param alias: Use an alias for this host. - :type alias: str or int :param read_timeout: (Optional) Timeout in seconds for reading from stdout or stderr. Reading from stdout/stderr will raise :py:class:`pssh.exceptions.Timeout` @@ -219,7 +213,7 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, self, command, stop_on_errors=stop_on_errors, host_args=host_args, user=user, shell=shell, sudo=sudo, encoding=encoding, use_pty=use_pty, - read_timeout=read_timeout, alias=alias, + read_timeout=read_timeout, ) def __del__(self): @@ -237,7 +231,7 @@ def _make_ssh_client(self, host, cfg, _pkey_data): _client = SSHClient( host, user=cfg.user or self.user, password=cfg.password or self.password, port=cfg.port or self.port, pkey=_pkey_data, num_retries=cfg.num_retries or self.num_retries, - alias=cfg.alias or self.alias, + alias=cfg.alias, timeout=cfg.timeout or self.timeout, allow_agent=cfg.allow_agent or self.allow_agent, retry_delay=cfg.retry_delay or self.retry_delay, proxy_host=cfg.proxy_host or self.proxy_host, diff --git a/pssh/clients/native/single.py b/pssh/clients/native/single.py index 03f69f6f..4b8b70b6 100644 --- a/pssh/clients/native/single.py +++ b/pssh/clients/native/single.py @@ -117,6 +117,7 @@ def __init__(self, host, self.keepalive_seconds = keepalive_seconds self._keepalive_greenlet = None self._proxy_client = None + self.alias = alias self.host = host self.port = port if port is not None else 22 if proxy_host is not None: diff --git a/pssh/clients/ssh/parallel.py b/pssh/clients/ssh/parallel.py index df82de8e..7ab4aafd 100644 --- a/pssh/clients/ssh/parallel.py +++ b/pssh/clients/ssh/parallel.py @@ -30,7 +30,7 @@ class ParallelSSHClient(BaseParallelSSHClient): """ssh-python based parallel client.""" def __init__(self, hosts, user=None, password=None, port=22, pkey=None, - cert_file=None, alias=None, + cert_file=None, num_retries=DEFAULT_RETRIES, timeout=None, pool_size=100, allow_agent=True, host_config=None, retry_delay=RETRY_DELAY, forward_ssh_agent=False, @@ -49,8 +49,6 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, :param password: (Optional) Password to use for login. Defaults to no password :type password: str - :param alias: Use an alias for this host. - :type alias: str or int :param port: (Optional) Port number to use for SSH connection. Defaults to 22. :type port: int @@ -121,7 +119,7 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, provided private key. """ BaseParallelSSHClient.__init__( - self, hosts, user=user, password=password, port=port, pkey=pkey, alias=alias, + self, hosts, user=user, password=password, port=port, pkey=pkey, allow_agent=allow_agent, num_retries=num_retries, timeout=timeout, pool_size=pool_size, host_config=host_config, retry_delay=retry_delay, @@ -138,7 +136,7 @@ def __init__(self, hosts, user=None, password=None, port=22, pkey=None, def run_command(self, command, sudo=False, user=None, stop_on_errors=True, use_pty=False, host_args=None, shell=None, - encoding='utf-8', read_timeout=None, alias=None, + encoding='utf-8', read_timeout=None, ): """Run command on all hosts in parallel, honoring self.pool_size, and return output. @@ -163,8 +161,6 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, :param user: (Optional) User to run command as. Requires sudo access for that user from the logged in user account. :type user: str - :param alias: Use an alias for this host. - :type alias: str or int :param stop_on_errors: (Optional) Raise exception on errors running command. Defaults to True. With stop_on_errors set to False, exceptions are instead added to output of `run_command`. See example @@ -214,14 +210,14 @@ def run_command(self, command, sudo=False, user=None, stop_on_errors=True, self, command, stop_on_errors=stop_on_errors, host_args=host_args, user=user, shell=shell, sudo=sudo, encoding=encoding, use_pty=use_pty, - read_timeout=read_timeout, alias=alias, + read_timeout=read_timeout, ) def _make_ssh_client(self, host, cfg, _pkey_data): _client = SSHClient( host, user=cfg.user or self.user, password=cfg.password or self.password, port=cfg.port or self.port, pkey=_pkey_data, num_retries=cfg.num_retries or self.num_retries, - alias=cfg.alias or self.alias, + alias=cfg.alias, timeout=cfg.timeout or self.timeout, allow_agent=cfg.allow_agent or self.allow_agent, retry_delay=cfg.retry_delay or self.retry_delay, _auth_thread_pool=cfg.auth_thread_pool or self._auth_thread_pool, diff --git a/pssh/output.py b/pssh/output.py index 98acecaa..4c63365c 100644 --- a/pssh/output.py +++ b/pssh/output.py @@ -120,12 +120,13 @@ def exit_code(self): def __repr__(self): return "\thost={host}{linesep}" \ + "\talias={alias}{linesep}" \ "\texit_code={exit_code}{linesep}" \ "\tchannel={channel}{linesep}" \ "\texception={exception}{linesep}" \ "\tencoding={encoding}{linesep}" \ "\tread_timeout={read_timeout}".format( - host=self.host, channel=self.channel, + host=self.host, alias=self.alias, channel=self.channel, exception=self.exception, linesep=linesep, exit_code=self.exit_code, encoding=self.encoding, read_timeout=self.read_timeout, ) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index e2b0e5a4..62050692 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -958,14 +958,8 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - client_aliases = [alias for alias in [client.alias for client in [client._host_clients[x] for x in client._host_clients]]] - self.assertTrue(client._host_clients[0, hosts[0][0]].alias in aliases, - msg=f"Alias didn't pass through: {client._host_clients[0, hosts[0][0]].alias} did not contain any of {aliases}") - - ### this works but requires more than one successful connection. for example if n hosts was 3, not 2. - # self.assertEqual(len(set(client_aliases)), len(aliases), - # msg=f"Alias passthrough problem: client_aliases contain duplicate values. Expected {aliases} but got {client_aliases}") - ### + ### TODO: add test for alias passthrough + for server in servers: server.stop() From afb88b4b17234cb4b60fa9930d4b538b094477a5 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 19:35:29 +0200 Subject: [PATCH 37/57] add alias passthrough test --- tests/native/test_single_client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/native/test_single_client.py b/tests/native/test_single_client.py index 61df944e..ec09093d 100644 --- a/tests/native/test_single_client.py +++ b/tests/native/test_single_client.py @@ -180,6 +180,14 @@ def test_execute(self): exit_code = host_out.channel.get_exit_status() self.assertEqual(host_out.exit_code, 0) self.assertEqual(expected, output) + + def test_alias(self): + client = _SSHClient(self.host, port=self.port, + num_retries=1, alias='test') + host_out = client.run_command(self.cmd) + output = list(host_out.stdout) + stderr = list(host_out.stderr) + self.assertEqual(host_out.alias, 'test') def test_open_session_timeout(self): client = SSHClient(self.host, port=self.port, From 0f7c44d975c7564ce630c3527de86e86bddf3e11 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 19:46:37 +0200 Subject: [PATCH 38/57] test alias passthrough --- tests/native/test_parallel_client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 62050692..7c3c6308 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -957,8 +957,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - - ### TODO: add test for alias passthrough + self.assertEqual(set(aliases), set(output.alias)) for server in servers: server.stop() From 4401bddf0b9b889a53554679cc19f9ee93cd582b Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 19:47:50 +0200 Subject: [PATCH 39/57] cleanup --- tests/native/test_single_client.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/native/test_single_client.py b/tests/native/test_single_client.py index ec09093d..094b1b8e 100644 --- a/tests/native/test_single_client.py +++ b/tests/native/test_single_client.py @@ -185,8 +185,6 @@ def test_alias(self): client = _SSHClient(self.host, port=self.port, num_retries=1, alias='test') host_out = client.run_command(self.cmd) - output = list(host_out.stdout) - stderr = list(host_out.stderr) self.assertEqual(host_out.alias, 'test') def test_open_session_timeout(self): From 48c85bb69944773c5b8f1da5f3183802b1b770e7 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 19:53:39 +0200 Subject: [PATCH 40/57] fix dumb error --- tests/native/test_single_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_single_client.py b/tests/native/test_single_client.py index 094b1b8e..3e617563 100644 --- a/tests/native/test_single_client.py +++ b/tests/native/test_single_client.py @@ -182,7 +182,7 @@ def test_execute(self): self.assertEqual(expected, output) def test_alias(self): - client = _SSHClient(self.host, port=self.port, + client = SSHClient(self.host, port=self.port, num_retries=1, alias='test') host_out = client.run_command(self.cmd) self.assertEqual(host_out.alias, 'test') From b3c7604edbceed380398a02427320ddc7b1bdfc5 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 20:00:20 +0200 Subject: [PATCH 41/57] test client needs auth --- tests/native/test_single_client.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/native/test_single_client.py b/tests/native/test_single_client.py index 3e617563..762a6366 100644 --- a/tests/native/test_single_client.py +++ b/tests/native/test_single_client.py @@ -182,8 +182,9 @@ def test_execute(self): self.assertEqual(expected, output) def test_alias(self): - client = SSHClient(self.host, port=self.port, - num_retries=1, alias='test') + client = SSHClient(self.host, port=self.port, + pkey=self.user_key, num_retries=1, + alias='test') host_out = client.run_command(self.cmd) self.assertEqual(host_out.alias, 'test') From 9370e3e892fbd3cd0e4938937b81ace0e825445c Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 20:05:06 +0200 Subject: [PATCH 42/57] fix test error with lists --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 7c3c6308..30c57952 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -957,7 +957,7 @@ def test_host_config(self): self.assertEqual(client._host_clients[0, hosts[0][0]].user, self.user) self.assertEqual(client._host_clients[0, hosts[0][0]].password, password) self.assertEqual(client._host_clients[0, hosts[0][0]].pkey, open(os.path.abspath(self.user_key), 'rb').read()) - self.assertEqual(set(aliases), set(output.alias)) + self.assertEqual(set(aliases), set([client.alias for client in output])) for server in servers: server.stop() From 69504acc99fcb8cce9347f8f3d51a5807d0b7564 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 20:19:50 +0200 Subject: [PATCH 43/57] make alias test more interpretable --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 30c57952..1c7c988c 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -930,7 +930,7 @@ def test_host_config(self): servers = [] password = 'overriden_pass' fake_key = 'FAKE KEY' - aliases = [f"alias {host}" for host in hosts] + aliases = [f"alias for host {host_i}" for host_i in hosts] for host_i, (host, port) in enumerate(hosts): server = OpenSSHServer(listen_ip=host, port=port) server.start_server() From b8ecb7214ea430bbb91b1d8f7a7282641c053fc7 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 20:27:25 +0200 Subject: [PATCH 44/57] the actual interpretability improvement --- tests/native/test_parallel_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native/test_parallel_client.py b/tests/native/test_parallel_client.py index 1c7c988c..9250a4df 100644 --- a/tests/native/test_parallel_client.py +++ b/tests/native/test_parallel_client.py @@ -930,7 +930,7 @@ def test_host_config(self): servers = [] password = 'overriden_pass' fake_key = 'FAKE KEY' - aliases = [f"alias for host {host_i}" for host_i in hosts] + aliases = [f"alias for host {host_i}" for host_i, _ in enumerate(hosts)] for host_i, (host, port) in enumerate(hosts): server = OpenSSHServer(listen_ip=host, port=port) server.start_server() From 1a51f3615a152967c2d0472edecb78bb5e636f38 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 22:38:12 +0200 Subject: [PATCH 45/57] get alias for host with error --- pssh/clients/base/parallel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 43f05db1..f46f4339 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -231,6 +231,7 @@ def _get_output_from_cmds(self, cmds, raise_error=False): def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): host = self.hosts[cmd_i] + alias = self._get_host_config(host_i, _).alias try: host_out = cmd.get() return host_out @@ -239,8 +240,7 @@ def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): ex = Timeout() if raise_error: raise ex - return HostOutput(host, None, None, None, - exception=ex) + return HostOutput(host=host,exception=ex, alias=alias) def get_last_output(self, cmds=None): """Get output for last commands executed by ``run_command``. From b05c4902e945d5b0cf6cdc90ecb124916c64255e Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 22:43:40 +0200 Subject: [PATCH 46/57] i hope this gets the config for the correct host --- pssh/clients/base/parallel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index f46f4339..26dfedf1 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -231,7 +231,7 @@ def _get_output_from_cmds(self, cmds, raise_error=False): def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): host = self.hosts[cmd_i] - alias = self._get_host_config(host_i, _).alias + alias = self._get_host_config(cmd_i, _).alias try: host_out = cmd.get() return host_out From fc48899a36dfa804dc6c12b110c7cb48eeda8391 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 22:48:00 +0200 Subject: [PATCH 47/57] make flake happy --- pssh/clients/base/parallel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 26dfedf1..3b569749 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -231,7 +231,7 @@ def _get_output_from_cmds(self, cmds, raise_error=False): def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): host = self.hosts[cmd_i] - alias = self._get_host_config(cmd_i, _).alias + alias = self._get_host_config(cmd_i, 'doesnt matter').alias try: host_out = cmd.get() return host_out @@ -240,7 +240,7 @@ def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): ex = Timeout() if raise_error: raise ex - return HostOutput(host=host,exception=ex, alias=alias) + return HostOutput(host=host, exception=ex, alias=alias) def get_last_output(self, cmds=None): """Get output for last commands executed by ``run_command``. From 72ef36d182cb9230699c9c7686b633b04013590f Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 22:55:53 +0200 Subject: [PATCH 48/57] fix alias for errors --- pssh/clients/base/parallel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 3b569749..0012fb1c 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -231,7 +231,7 @@ def _get_output_from_cmds(self, cmds, raise_error=False): def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): host = self.hosts[cmd_i] - alias = self._get_host_config(cmd_i, 'doesnt matter').alias + alias = self.host_config[cmd_i].alias try: host_out = cmd.get() return host_out From 91ae75ec2915607a0a6166bf85281eea12697e3f Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 22:57:53 +0200 Subject: [PATCH 49/57] reintroduce magic --- pssh/clients/base/parallel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 0012fb1c..5d484a01 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -240,7 +240,7 @@ def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): ex = Timeout() if raise_error: raise ex - return HostOutput(host=host, exception=ex, alias=alias) + return HostOutput(host, None, None, None, exception=ex, alias=alias) def get_last_output(self, cmds=None): """Get output for last commands executed by ``run_command``. From de4bbe891912287453a47cd1b7659d76369f9c98 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 23:07:55 +0200 Subject: [PATCH 50/57] no alias if host config is not set --- pssh/clients/base/parallel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 5d484a01..12c701d8 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -272,6 +272,7 @@ def _get_host_config(self, host_i, host): gssapi_server_identity=self.gssapi_server_identity, gssapi_client_identity=self.gssapi_client_identity, gssapi_delegate_credentials=self.gssapi_delegate_credentials, + alias=None, ) return config elif not isinstance(self.host_config, list): From 860fed1c567dc574dd8f455f1c2029c8402574f0 Mon Sep 17 00:00:00 2001 From: simonfelding <45149055+simonfelding@users.noreply.github.com> Date: Sat, 6 Aug 2022 23:14:56 +0200 Subject: [PATCH 51/57] now it works??? --- pssh/clients/base/parallel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/base/parallel.py b/pssh/clients/base/parallel.py index 12c701d8..f2b83df7 100644 --- a/pssh/clients/base/parallel.py +++ b/pssh/clients/base/parallel.py @@ -231,7 +231,7 @@ def _get_output_from_cmds(self, cmds, raise_error=False): def _get_output_from_greenlet(self, cmd_i, cmd, raise_error=False): host = self.hosts[cmd_i] - alias = self.host_config[cmd_i].alias + alias = self._get_host_config(cmd_i, host).alias try: host_out = cmd.get() return host_out From 607c2ec0bdeb7b6748a753882112c06e94f662ff Mon Sep 17 00:00:00 2001 From: Panos Date: Sat, 20 Aug 2022 10:51:08 +0100 Subject: [PATCH 52/57] Update tests/test_host_config.py --- tests/test_host_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_host_config.py b/tests/test_host_config.py index 5f6a8b7c..7327fb78 100644 --- a/tests/test_host_config.py +++ b/tests/test_host_config.py @@ -81,7 +81,7 @@ def test_host_config_bad_entries(self): self.assertRaises(ValueError, HostConfig, user=22) self.assertRaises(ValueError, HostConfig, password=22) self.assertRaises(ValueError, HostConfig, port='22') - self.assertRaises(ValueError, HostConfig, alias=2.2) + self.assertRaises(ValueError, HostConfig, alias=2) self.assertRaises(ValueError, HostConfig, private_key=1) self.assertRaises(ValueError, HostConfig, allow_agent=1) self.assertRaises(ValueError, HostConfig, num_retries='') From 0387a630e01aed90a46e670d45cf5fa45049a181 Mon Sep 17 00:00:00 2001 From: Panos Date: Sat, 20 Aug 2022 10:51:15 +0100 Subject: [PATCH 53/57] Update pssh/config.py --- pssh/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/config.py b/pssh/config.py index 723b5d1e..3c882f48 100644 --- a/pssh/config.py +++ b/pssh/config.py @@ -134,7 +134,7 @@ def _sanity_checks(self): if self.password is not None and not isinstance(self.password, str): raise ValueError("Password %s is not a string" % (self.password,)) if self.alias is not None and not isinstance(self.alias, (str, int)): - raise ValueError("Alias %s is not a string or integer" % (self.alias,)) + raise ValueError("Alias %s is not a string" % (self.alias,)) if self.private_key is not None and not ( isinstance(self.private_key, str) or isinstance(self.private_key, bytes) ): From e02013f4816a0c83326b4c3d8d06220788ea4c53 Mon Sep 17 00:00:00 2001 From: Panos Date: Sat, 20 Aug 2022 10:51:21 +0100 Subject: [PATCH 54/57] Update pssh/clients/native/single.py --- pssh/clients/native/single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/native/single.py b/pssh/clients/native/single.py index 4b8b70b6..335dfa56 100644 --- a/pssh/clients/native/single.py +++ b/pssh/clients/native/single.py @@ -71,7 +71,7 @@ def __init__(self, host, :param password: Password to use for password authentication. :type password: str :param alias: Use an alias for this host. - :type alias: str or int + :type alias: str :param port: SSH port to connect to. Defaults to SSH default (22) :type port: int :param pkey: Private key file path to use for authentication. Path must From b40ffe256cd0ce3123ed7b1ce3b487eba0fa1220 Mon Sep 17 00:00:00 2001 From: Panos Date: Sat, 20 Aug 2022 10:51:28 +0100 Subject: [PATCH 55/57] Update pssh/clients/ssh/single.py --- pssh/clients/ssh/single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/clients/ssh/single.py b/pssh/clients/ssh/single.py index 6caa93a6..9eee161e 100644 --- a/pssh/clients/ssh/single.py +++ b/pssh/clients/ssh/single.py @@ -61,7 +61,7 @@ def __init__(self, host, :param port: SSH port to connect to. Defaults to SSH default (22) :type port: int :param alias: Use an alias for this host. - :type alias: str or int + :type alias: str :param pkey: Private key file path to use for authentication. Path must be either absolute path or relative to user home directory like ``~/``. From 402f74fba178fc3a4ef4bee6659b82557bafd152 Mon Sep 17 00:00:00 2001 From: Panos Date: Sat, 20 Aug 2022 10:51:34 +0100 Subject: [PATCH 56/57] Update pssh/config.py --- pssh/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/config.py b/pssh/config.py index 3c882f48..65fc3e34 100644 --- a/pssh/config.py +++ b/pssh/config.py @@ -133,7 +133,7 @@ def _sanity_checks(self): raise ValueError("Port %s is not an integer" % (self.port,)) if self.password is not None and not isinstance(self.password, str): raise ValueError("Password %s is not a string" % (self.password,)) - if self.alias is not None and not isinstance(self.alias, (str, int)): + if self.alias is not None and not isinstance(self.alias, str): raise ValueError("Alias %s is not a string" % (self.alias,)) if self.private_key is not None and not ( isinstance(self.private_key, str) or isinstance(self.private_key, bytes) From 5b1be0ef5915d0a5755490a53296be166fcc6787 Mon Sep 17 00:00:00 2001 From: Panos Date: Sat, 20 Aug 2022 10:51:40 +0100 Subject: [PATCH 57/57] Update pssh/output.py --- pssh/output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pssh/output.py b/pssh/output.py index 4c63365c..01d709b2 100644 --- a/pssh/output.py +++ b/pssh/output.py @@ -72,7 +72,7 @@ def __init__(self, host, channel, stdin, :param client: `SSHClient` output is coming from. :type client: :py:class:`pssh.clients.base.single.BaseSSHClient` :param alias: Host alias. - :type alias: str or int + :type alias: str :param exception: Exception from host if any :type exception: :py:class:`Exception` or ``None`` :param read_timeout: Timeout in seconds for reading from buffers.