parallel-ssh 2.14.0__tar.gz → 2.15.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/PKG-INFO +19 -6
  2. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/parallel_ssh.egg-info/PKG-INFO +19 -6
  3. parallel_ssh-2.15.0/pssh/__init__.py +39 -0
  4. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/_version.py +3 -3
  5. parallel_ssh-2.15.0/pssh/clients/__init__.py +19 -0
  6. parallel_ssh-2.15.0/pssh/clients/base/__init__.py +16 -0
  7. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/base/parallel.py +19 -14
  8. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/base/single.py +22 -16
  9. parallel_ssh-2.15.0/pssh/clients/common.py +51 -0
  10. parallel_ssh-2.15.0/pssh/clients/native/__init__.py +20 -0
  11. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/native/parallel.py +26 -13
  12. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/native/single.py +39 -16
  13. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/native/tunnel.py +13 -13
  14. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/reader.py +13 -13
  15. parallel_ssh-2.15.0/pssh/clients/ssh/__init__.py +20 -0
  16. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/ssh/parallel.py +18 -13
  17. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/clients/ssh/single.py +19 -13
  18. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/config.py +35 -14
  19. parallel_ssh-2.15.0/pssh/constants.py +28 -0
  20. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/exceptions.py +17 -13
  21. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/output.py +13 -13
  22. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/pssh/utils.py +13 -13
  23. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/setup.py +21 -15
  24. parallel_ssh-2.14.0/pssh/__init__.py +0 -39
  25. parallel_ssh-2.14.0/pssh/clients/__init__.py +0 -19
  26. parallel_ssh-2.14.0/pssh/clients/base/__init__.py +0 -0
  27. parallel_ssh-2.14.0/pssh/clients/common.py +0 -41
  28. parallel_ssh-2.14.0/pssh/clients/native/__init__.py +0 -20
  29. parallel_ssh-2.14.0/pssh/clients/ssh/__init__.py +0 -20
  30. parallel_ssh-2.14.0/pssh/constants.py +0 -28
  31. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/COPYING +0 -0
  32. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/COPYING.LESSER +0 -0
  33. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/LICENSE +0 -0
  34. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/MANIFEST.in +0 -0
  35. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/README.rst +0 -0
  36. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/parallel_ssh.egg-info/SOURCES.txt +0 -0
  37. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/parallel_ssh.egg-info/dependency_links.txt +0 -0
  38. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/parallel_ssh.egg-info/requires.txt +0 -0
  39. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/parallel_ssh.egg-info/top_level.txt +0 -0
  40. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/setup.cfg +0 -0
  41. {parallel_ssh-2.14.0 → parallel_ssh-2.15.0}/versioneer.py +0 -0
@@ -1,25 +1,29 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: parallel-ssh
3
- Version: 2.14.0
3
+ Version: 2.15.0
4
4
  Summary: Asynchronous parallel SSH library
5
5
  Home-page: https://github.com/ParallelSSH/parallel-ssh
6
6
  Author: Panos Kittenis
7
- Author-email: zuboci@yandex.com
8
- License: LGPLv2.1
7
+ Author-email: danst@tutanota.com
8
+ License: LGPL-2.1-only
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)
11
10
  Classifier: Intended Audience :: Developers
12
11
  Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python
14
12
  Classifier: Programming Language :: Python :: 3
15
13
  Classifier: Programming Language :: Python :: 3.8
16
14
  Classifier: Programming Language :: Python :: 3.9
17
15
  Classifier: Programming Language :: Python :: 3.10
18
16
  Classifier: Programming Language :: Python :: 3.11
19
17
  Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Programming Language :: Python :: Implementation :: CPython
21
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
22
+ Classifier: Topic :: System :: Shells
20
23
  Classifier: Topic :: System :: Networking
21
24
  Classifier: Topic :: Software Development :: Libraries
22
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Operating System :: POSIX
23
27
  Classifier: Operating System :: POSIX :: Linux
24
28
  Classifier: Operating System :: POSIX :: BSD
25
29
  Classifier: Operating System :: Microsoft :: Windows
@@ -30,6 +34,15 @@ License-File: COPYING.LESSER
30
34
  Requires-Dist: gevent
31
35
  Requires-Dist: ssh2-python
32
36
  Requires-Dist: ssh-python
37
+ Dynamic: author
38
+ Dynamic: author-email
39
+ Dynamic: classifier
40
+ Dynamic: description
41
+ Dynamic: home-page
42
+ Dynamic: license
43
+ Dynamic: license-file
44
+ Dynamic: requires-dist
45
+ Dynamic: summary
33
46
 
34
47
  ============
35
48
  parallel-ssh
@@ -1,25 +1,29 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: parallel-ssh
3
- Version: 2.14.0
3
+ Version: 2.15.0
4
4
  Summary: Asynchronous parallel SSH library
5
5
  Home-page: https://github.com/ParallelSSH/parallel-ssh
6
6
  Author: Panos Kittenis
7
- Author-email: zuboci@yandex.com
8
- License: LGPLv2.1
7
+ Author-email: danst@tutanota.com
8
+ License: LGPL-2.1-only
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)
11
10
  Classifier: Intended Audience :: Developers
12
11
  Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python
14
12
  Classifier: Programming Language :: Python :: 3
15
13
  Classifier: Programming Language :: Python :: 3.8
16
14
  Classifier: Programming Language :: Python :: 3.9
17
15
  Classifier: Programming Language :: Python :: 3.10
18
16
  Classifier: Programming Language :: Python :: 3.11
19
17
  Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Programming Language :: Python :: Implementation :: CPython
21
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
22
+ Classifier: Topic :: System :: Shells
20
23
  Classifier: Topic :: System :: Networking
21
24
  Classifier: Topic :: Software Development :: Libraries
22
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Operating System :: POSIX
23
27
  Classifier: Operating System :: POSIX :: Linux
24
28
  Classifier: Operating System :: POSIX :: BSD
25
29
  Classifier: Operating System :: Microsoft :: Windows
@@ -30,6 +34,15 @@ License-File: COPYING.LESSER
30
34
  Requires-Dist: gevent
31
35
  Requires-Dist: ssh2-python
32
36
  Requires-Dist: ssh-python
37
+ Dynamic: author
38
+ Dynamic: author-email
39
+ Dynamic: classifier
40
+ Dynamic: description
41
+ Dynamic: home-page
42
+ Dynamic: license
43
+ Dynamic: license-file
44
+ Dynamic: requires-dist
45
+ Dynamic: summary
33
46
 
34
47
  ============
35
48
  parallel-ssh
@@ -0,0 +1,39 @@
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ """Asynchronous parallel SSH client library.
19
+
20
+ Run SSH commands over many - hundreds/hundreds of thousands - number of servers
21
+ asynchronously and with minimal system load on the client host.
22
+
23
+ New users should start with `pssh.clients.ParallelSSHClient.run_command` and
24
+ `pssh.clients.SSHClient.run_command`
25
+
26
+ See also `pssh.clients.ParallelSSHClient` and pssh.clients.SSHClient`
27
+ for class documentation.
28
+ """
29
+
30
+
31
+ from logging import getLogger, NullHandler
32
+ from . import _version
33
+ __version__ = _version.get_versions()['version']
34
+ del _version
35
+
36
+ host_logger = getLogger('pssh.host_logger')
37
+ logger = getLogger('pssh')
38
+ host_logger.addHandler(NullHandler())
39
+ logger.addHandler(NullHandler())
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-02-02T18:31:06+0000",
11
+ "date": "2025-10-12T14:04:45+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "987dd584c17c5aca9e1ea62f67a695672f6f4c9e",
15
- "version": "2.14.0"
14
+ "full-revisionid": "8fa5a91bbfb7cd87148a566cc3772006ec2ba989",
15
+ "version": "2.15.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,19 @@
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ # flake8: noqa: F401
19
+ from .native import ParallelSSHClient, SSHClient
@@ -0,0 +1,16 @@
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -1,19 +1,19 @@
1
- # This file is part of parallel-ssh.
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
2
4
  #
3
- # Copyright (C) 2014-2022 Panos Kittenis and contributors.
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
4
8
  #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation, version 2.1.
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
8
13
  #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  """Abstract parallel SSH client package"""
19
19
 
@@ -23,7 +23,7 @@ import gevent.pool
23
23
  from gevent import joinall, spawn, Timeout as GTimeout
24
24
  from gevent.hub import Hub
25
25
 
26
- from ..common import _validate_pkey_path, _validate_pkey
26
+ from ..common import _validate_pkey_path, _validate_pkey, _validate_api
27
27
  from ...config import HostConfig
28
28
  from ...constants import DEFAULT_RETRIES, RETRY_DELAY
29
29
  from ...exceptions import HostArgumentError, Timeout, ShellError, HostConfigError
@@ -55,6 +55,8 @@ class BaseParallelSSHClient(object):
55
55
  gssapi_client_identity=None,
56
56
  gssapi_delegate_credentials=False,
57
57
  forward_ssh_agent=False,
58
+ compress=False,
59
+ keyboard_interactive=False,
58
60
  _auth_thread_pool=True,
59
61
  ):
60
62
  self.allow_agent = allow_agent
@@ -86,6 +88,9 @@ class BaseParallelSSHClient(object):
86
88
  self.gssapi_server_identity = gssapi_server_identity
87
89
  self.gssapi_client_identity = gssapi_client_identity
88
90
  self.gssapi_delegate_credentials = gssapi_delegate_credentials
91
+ self.compress = compress
92
+ self.keyboard_interactive = keyboard_interactive
93
+ _validate_api(self.keyboard_interactive, self.password)
89
94
  self._auth_thread_pool = _auth_thread_pool
90
95
  self._check_host_config()
91
96
 
@@ -1,19 +1,19 @@
1
- # This file is part of parallel-ssh.
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
2
4
  #
3
- # Copyright (C) 2014-2022 Panos Kittenis and contributors.
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
4
8
  #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation, version 2.1.
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
8
13
  #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  import logging
19
19
  import os
@@ -23,14 +23,14 @@ from warnings import warn
23
23
 
24
24
  from gevent import sleep, socket, Timeout as GTimeout
25
25
  from gevent.hub import Hub
26
+ from gevent.pool import Pool
26
27
  from gevent.select import poll, POLLIN, POLLOUT
27
28
  from gevent.socket import SHUT_RDWR
28
- from gevent.pool import Pool
29
29
  from ssh2.exceptions import AgentConnectionError, AgentListIdentitiesError, \
30
30
  AgentAuthenticationError, AgentGetIdentityError
31
31
  from ssh2.utils import find_eol
32
32
 
33
- from ..common import _validate_pkey
33
+ from ..common import _validate_pkey, _validate_api
34
34
  from ..reader import ConcurrentRWBuffer
35
35
  from ...constants import DEFAULT_RETRIES, RETRY_DELAY
36
36
  from ...exceptions import UnknownHostError, AuthenticationError, \
@@ -226,6 +226,8 @@ class BaseSSHClient(PollMixIn):
226
226
  _auth_thread_pool=True,
227
227
  identity_auth=True,
228
228
  ipv6_only=False,
229
+ compress=False,
230
+ keyboard_interactive=False,
229
231
  ):
230
232
  super(PollMixIn, self).__init__()
231
233
  self._auth_thread_pool = _auth_thread_pool
@@ -233,6 +235,7 @@ class BaseSSHClient(PollMixIn):
233
235
  self.alias = alias
234
236
  self.user = user if user else getuser()
235
237
  self.password = password
238
+ self.keyboard_interactive = keyboard_interactive
236
239
  self.port = port if port else 22
237
240
  self.num_retries = num_retries
238
241
  self.timeout = timeout if timeout else None
@@ -245,6 +248,9 @@ class BaseSSHClient(PollMixIn):
245
248
  self.identity_auth = identity_auth
246
249
  self._keepalive_greenlet = None
247
250
  self.ipv6_only = ipv6_only
251
+ self.compress = compress
252
+ self.keyboard_interactive = keyboard_interactive
253
+ _validate_api(self.keyboard_interactive, self.password)
248
254
  self._pool = Pool()
249
255
  self._init()
250
256
 
@@ -437,7 +443,7 @@ class BaseSSHClient(PollMixIn):
437
443
  msg = "No remaining authentication methods"
438
444
  logger.error(msg)
439
445
  raise AuthenticationError(msg)
440
- logger.debug("Private key auth failed, trying password")
446
+ logger.debug("Private key auth failed or not enabled, trying password")
441
447
  self._password_auth()
442
448
 
443
449
  def _agent_auth(self):
@@ -0,0 +1,51 @@
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ import logging
19
+ import os
20
+
21
+ from ..exceptions import PKeyFileError, InvalidAPIUseError
22
+
23
+ logger = logging.getLogger('pssh')
24
+
25
+
26
+ def _validate_pkey_path(pkey):
27
+ if pkey is None:
28
+ return
29
+ pkey = os.path.normpath(os.path.expanduser(pkey))
30
+ if not os.path.exists(pkey):
31
+ msg = "File %s does not exist. " \
32
+ "Please use either absolute or relative to user directory " \
33
+ "paths like '~/.ssh/my_key' for pkey parameter"
34
+ ex = PKeyFileError(msg, pkey)
35
+ raise ex
36
+ return pkey
37
+
38
+
39
+ def _validate_pkey(pkey):
40
+ if pkey is None:
41
+ return
42
+ if isinstance(pkey, str):
43
+ return _validate_pkey_path(pkey)
44
+ return pkey
45
+
46
+
47
+ def _validate_api(keyboard_interactive, password):
48
+ if keyboard_interactive and not password:
49
+ msg = "Keyboard interactive authentication is enabled but no password is provided - cannot continue"
50
+ logger.error(msg)
51
+ raise InvalidAPIUseError(msg)
@@ -0,0 +1,20 @@
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ # flake8: noqa: F401
19
+ from .parallel import ParallelSSHClient
20
+ from .single import SSHClient, logger
@@ -1,19 +1,19 @@
1
- # This file is part of parallel-ssh.
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
2
4
  #
3
- # Copyright (C) 2014-2022 Panos Kittenis and contributors.
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
4
8
  #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation, version 2.1.
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
8
13
  #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  import logging
19
19
 
@@ -37,6 +37,8 @@ class ParallelSSHClient(BaseParallelSSHClient):
37
37
  forward_ssh_agent=False,
38
38
  keepalive_seconds=60, identity_auth=True,
39
39
  ipv6_only=False,
40
+ compress=False,
41
+ keyboard_interactive=False,
40
42
  ):
41
43
  """
42
44
  :param hosts: Hosts to connect to
@@ -115,9 +117,17 @@ class ParallelSSHClient(BaseParallelSSHClient):
115
117
  for the host(s) or raise NoIPv6AddressFoundError otherwise. Note this will
116
118
  disable connecting to an IPv4 address if an IP address is provided instead.
117
119
  :type ipv6_only: bool
120
+ :param compress: Enable/Disable compression on the client. Defaults to off.
121
+ :type compress: bool
122
+ :param keyboard_interactive: Enable/Disable keyboard interactive authentication with provided username and
123
+ password. An `InvalidAPIUse` error is raised when keyboard_interactive is enabled without a provided password.
124
+ Defaults to off.
125
+ :type keyboard_interactive: bool
118
126
 
119
127
  :raises: :py:class:`pssh.exceptions.PKeyFileError` on errors finding
120
128
  provided private key.
129
+ :raises: :py:class:`pssh.exceptions.InvalidAPIUseError` when `keyboard_interactive=True` with no password
130
+ provided.
121
131
  """
122
132
  BaseParallelSSHClient.__init__(
123
133
  self, hosts, user=user, password=password, port=port, pkey=pkey,
@@ -126,6 +136,8 @@ class ParallelSSHClient(BaseParallelSSHClient):
126
136
  host_config=host_config, retry_delay=retry_delay,
127
137
  identity_auth=identity_auth,
128
138
  ipv6_only=ipv6_only,
139
+ compress=compress,
140
+ keyboard_interactive=keyboard_interactive,
129
141
  )
130
142
  self.proxy_host = proxy_host
131
143
  self.proxy_port = proxy_port
@@ -232,6 +244,7 @@ class ParallelSSHClient(BaseParallelSSHClient):
232
244
  keepalive_seconds=cfg.keepalive_seconds or self.keepalive_seconds,
233
245
  identity_auth=cfg.identity_auth or self.identity_auth,
234
246
  ipv6_only=cfg.ipv6_only or self.ipv6_only,
247
+ compress=cfg.compress or self.compress,
235
248
  )
236
249
  return _client
237
250
 
@@ -1,19 +1,19 @@
1
- # This file is part of parallel-ssh.
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
2
4
  #
3
- # Copyright (C) 2014-2022 Panos Kittenis and contributors.
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
4
8
  #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation, version 2.1.
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
8
13
  #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  from collections import deque
19
19
 
@@ -27,7 +27,7 @@ from gevent.timeout import Timeout as GTimeout
27
27
  from ssh2.error_codes import LIBSSH2_ERROR_EAGAIN
28
28
  from ssh2.exceptions import SFTPHandleError, SFTPProtocolError, \
29
29
  Timeout as SSH2Timeout
30
- from ssh2.session import Session, LIBSSH2_SESSION_BLOCK_INBOUND, LIBSSH2_SESSION_BLOCK_OUTBOUND
30
+ from ssh2.session import Session, LIBSSH2_SESSION_BLOCK_INBOUND, LIBSSH2_SESSION_BLOCK_OUTBOUND, LIBSSH2_FLAG_COMPRESS
31
31
  from ssh2.sftp import LIBSSH2_FXF_READ, LIBSSH2_FXF_CREAT, LIBSSH2_FXF_WRITE, \
32
32
  LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR, LIBSSH2_SFTP_S_IRGRP, \
33
33
  LIBSSH2_SFTP_S_IWUSR, LIBSSH2_SFTP_S_IXUSR, LIBSSH2_SFTP_S_IROTH, \
@@ -110,6 +110,8 @@ class SSHClient(BaseSSHClient):
110
110
  keepalive_seconds=60,
111
111
  identity_auth=True,
112
112
  ipv6_only=False,
113
+ compress=False,
114
+ keyboard_interactive=False,
113
115
  ):
114
116
  """
115
117
  :param host: Host name or IP to connect to.
@@ -158,9 +160,17 @@ class SSHClient(BaseSSHClient):
158
160
  for the host or raise NoIPv6AddressFoundError otherwise. Note this will
159
161
  disable connecting to an IPv4 address if an IP address is provided instead.
160
162
  :type ipv6_only: bool
163
+ :param compress: Enable/Disable compression on the client. Defaults to off.
164
+ :type compress: bool
165
+ :param keyboard_interactive: Enable/Disable keyboard interactive authentication with provided username and
166
+ password. An `InvalidAPIUse` error is raised when keyboard_interactive is enabled without a provided password.
167
+ Defaults to off.
168
+ :type keyboard_interactive: bool
161
169
 
162
170
  :raises: :py:class:`pssh.exceptions.PKeyFileError` on errors finding
163
171
  provided private key.
172
+ :raises: :py:class:`pssh.exceptions.InvalidAPIUseError` when `keyboard_interactive=True` with no password
173
+ provided.
164
174
  """
165
175
  self.forward_ssh_agent = forward_ssh_agent
166
176
  self._forward_requested = False
@@ -182,6 +192,8 @@ class SSHClient(BaseSSHClient):
182
192
  timeout=timeout,
183
193
  keepalive_seconds=keepalive_seconds,
184
194
  identity_auth=identity_auth,
195
+ compress=compress,
196
+ keyboard_interactive=keyboard_interactive,
185
197
  )
186
198
  proxy_host = '127.0.0.1'
187
199
  self._chan_stdout_lock = RLock()
@@ -194,6 +206,8 @@ class SSHClient(BaseSSHClient):
194
206
  proxy_host=proxy_host, proxy_port=proxy_port,
195
207
  identity_auth=identity_auth,
196
208
  ipv6_only=ipv6_only,
209
+ compress=compress,
210
+ keyboard_interactive=keyboard_interactive,
197
211
  )
198
212
 
199
213
  def _shell(self, channel):
@@ -206,7 +220,10 @@ class SSHClient(BaseSSHClient):
206
220
  allow_agent=True, timeout=None,
207
221
  forward_ssh_agent=False,
208
222
  keepalive_seconds=60,
209
- identity_auth=True):
223
+ identity_auth=True,
224
+ compress=False,
225
+ keyboard_interactive=False,
226
+ ):
210
227
  assert isinstance(self.port, int)
211
228
  try:
212
229
  self._proxy_client = SSHClient(
@@ -216,6 +233,8 @@ class SSHClient(BaseSSHClient):
216
233
  timeout=timeout, forward_ssh_agent=forward_ssh_agent,
217
234
  identity_auth=identity_auth,
218
235
  keepalive_seconds=keepalive_seconds,
236
+ compress=compress,
237
+ keyboard_interactive=keyboard_interactive,
219
238
  _auth_thread_pool=False)
220
239
  except Exception as ex:
221
240
  msg = "Proxy authentication failed. " \
@@ -263,6 +282,8 @@ class SSHClient(BaseSSHClient):
263
282
 
264
283
  def _init_session(self, retries=1):
265
284
  self.session = Session()
285
+ if self.compress:
286
+ self.session.flag(LIBSSH2_FLAG_COMPRESS)
266
287
 
267
288
  if self.timeout:
268
289
  # libssh2 timeout is in ms
@@ -310,7 +331,9 @@ class SSHClient(BaseSSHClient):
310
331
  )
311
332
 
312
333
  def _password_auth(self):
313
- self.session.userauth_password(self.user, self.password)
334
+ if self.keyboard_interactive:
335
+ return self.session.userauth_keyboardinteractive(self.user, self.password)
336
+ return self.session.userauth_password(self.user, self.password)
314
337
 
315
338
  def _open_session(self):
316
339
  chan = self.eagain(self.session.open_session)
@@ -1,19 +1,19 @@
1
- # This file is part of parallel-ssh.
1
+ # This file is part of parallel-ssh.
2
+ # Copyright (C) 2014-2025 Panos Kittenis.
3
+ # Copyright (C) 2014-2025 parallel-ssh Contributors.
2
4
  #
3
- # Copyright (C) 2014-2022 Panos Kittenis and contributors.
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation, version 2.1.
4
8
  #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation, version 2.1.
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
8
13
  #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  import atexit
19
19
  import logging