Skip to content

Commit a626243

Browse files
author
Dan
committed
Merged py3 branch changes. Bumped gevent requirement to 1.1rc3. Added agent parameter to ParallelSSHClient class and made agent parameter in SSHClient public. Added explicit agent usage in tests to avoid using system agent in tests.
1 parent 2b15fe4 commit a626243

File tree

8 files changed

+49
-28
lines changed

8 files changed

+49
-28
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ sudo: false
44
python:
55
- 2.6
66
- 2.7
7+
- 3.4
8+
- 3.5
79
install:
810
- pip install -r requirements.txt
911
- pip install coveralls
10-
script: nosetests --with-coverage --cover-package=pssh
12+
script: python setup.py nosetests --with-coverage --cover-package=pssh
1113
notifications:
1214
email:
1315
on_failure: change

embedded_server/embedded_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
host_key = paramiko.RSAKey(filename = os.path.sep.join([os.path.dirname(__file__), 'rsa.key']))
4646

47-
class Server (paramiko.ServerInterface):
47+
class Server(paramiko.ServerInterface):
4848
def __init__(self, transport, fail_auth=False,
4949
ssh_exception=False):
5050
self.event = Event()

pssh/pssh_client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class ParallelSSHClient(object):
5050
def __init__(self, hosts,
5151
user=None, password=None, port=None, pkey=None,
5252
forward_ssh_agent=True, num_retries=DEFAULT_RETRIES, timeout=120,
53-
pool_size=10, proxy_host=None, proxy_port=22):
53+
pool_size=10, proxy_host=None, proxy_port=22,
54+
agent=None):
5455
"""
5556
:param hosts: Hosts to connect to
5657
:type hosts: list(str)
@@ -196,6 +197,7 @@ def __init__(self, hosts,
196197
self.proxy_host, self.proxy_port = proxy_host, proxy_port
197198
# To hold host clients
198199
self.host_clients = dict((host, None) for host in hosts)
200+
self.agent = agent
199201

200202
def run_command(self, *args, **kwargs):
201203
"""Run command on all hosts in parallel, honoring self.pool_size,
@@ -325,7 +327,8 @@ def _exec_command(self, host, *args, **kwargs):
325327
num_retries=self.num_retries,
326328
timeout=self.timeout,
327329
proxy_host=self.proxy_host,
328-
proxy_port=self.proxy_port)
330+
proxy_port=self.proxy_port,
331+
agent=self.agent)
329332
return self.host_clients[host].exec_command(*args, **kwargs)
330333

331334
def get_output(self, cmd, output):

pssh/ssh_client.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class SSHClient(object):
4646
def __init__(self, host,
4747
user=None, password=None, port=None,
4848
pkey=None, forward_ssh_agent=True,
49-
num_retries=DEFAULT_RETRIES, _agent=None, timeout=10,
49+
num_retries=DEFAULT_RETRIES, agent=None, timeout=10,
5050
proxy_host=None, proxy_port=22):
5151
"""Connect to host honouring any user set configuration in ~/.ssh/config \
5252
or /etc/ssh/ssh_config
@@ -74,11 +74,11 @@ def __init__(self, host,
7474
equivalent to `ssh -A` from the `ssh` command line utility. \
7575
Defaults to True if not set.
7676
:type forward_ssh_agent: bool
77-
:param _agent: (Optional) Override SSH agent object with the provided. \
77+
:param agent: (Optional) Override SSH agent object with the provided. \
7878
This allows for overriding of the default paramiko behaviour of \
79-
connecting to local SSH agent to lookup keys with our own SSH agent. \
80-
Only really useful for testing, hence the internal variable prefix.
81-
:type _agent: :mod:`paramiko.agent.Agent`
79+
connecting to local SSH agent to lookup keys with our own SSH agent \
80+
object.
81+
:type agent: :mod:`paramiko.agent.Agent`
8282
:param proxy_host: (Optional) SSH host to tunnel connection through \
8383
so that SSH clients connects to self.host via client -> proxy_host -> host
8484
:type proxy_host: str
@@ -109,8 +109,8 @@ def __init__(self, host,
109109
self.pkey = pkey
110110
self.port = port if port else 22
111111
self.host = resolved_address
112-
if _agent:
113-
self.client._agent = _agent
112+
if agent:
113+
self.client._agent = agent
114114
self.num_retries = num_retries
115115
self.timeout = timeout
116116
self.proxy_host, self.proxy_port = proxy_host, proxy_port

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
paramiko>=1.9
2-
gevent>=1.0.1
2+
gevent>=1.1rc3

setup.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1515

1616
from setuptools import setup, find_packages
17+
import sys
18+
19+
convert_2_to_3 = {}
20+
if sys.version_info >= (3,):
21+
convert_2_to_3['use_2to3'] = True
1722

1823
setup(name='parallel-ssh',
1924
version='0.80.6',
@@ -30,8 +35,12 @@
3035
'Programming Language :: Python :: 2',
3136
'Programming Language :: Python :: 2.6',
3237
'Programming Language :: Python :: 2.7',
38+
'Programming Language :: Python :: 3',
39+
'Programming Language :: Python :: 3.4',
40+
'Programming Language :: Python :: 3.5',
3341
'Topic :: Utilities',
3442
'Operating System :: POSIX :: Linux',
3543
'Operating System :: POSIX :: BSD',
3644
],
45+
**convert_2_to_3
3746
)

tests/test_pssh_client.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
AuthenticationException, ConnectionErrorException, SSHException, logger as pssh_logger
2525
from embedded_server.embedded_server import start_server, make_socket, \
2626
logger as server_logger, paramiko_logger
27+
from embedded_server.fake_agent import FakeAgent
2728
import random
2829
import logging
2930
import gevent
@@ -51,36 +52,39 @@ def setUp(self):
5152
self.listen_socket = make_socket(self.host)
5253
self.listen_port = self.listen_socket.getsockname()[1]
5354
self.server = start_server(self.listen_socket)
54-
55+
self.agent = FakeAgent()
56+
self.agent.add_key(USER_KEY)
57+
self.client = ParallelSSHClient([self.host], port=self.listen_port,
58+
pkey=self.user_key,
59+
agent=self.agent)
60+
5561
def tearDown(self):
5662
del self.server
5763
del self.listen_socket
64+
del self.client
5865

5966
def test_pssh_client_exec_command(self):
60-
client = ParallelSSHClient([self.host], port=self.listen_port,
61-
pkey=self.user_key)
62-
cmd = client.exec_command(self.fake_cmd)[0]
63-
output = client.get_stdout(cmd)
67+
cmd = self.client.exec_command(self.fake_cmd)[0]
68+
output = self.client.get_stdout(cmd)
6469
expected = {self.host : {'exit_code' : 0}}
6570
self.assertEqual(expected, output,
6671
msg="Got unexpected command output - %s" % (output,))
6772
self.assertTrue(output[self.host]['exit_code'] == 0)
6873

6974
def test_pssh_client_no_stdout_non_zero_exit_code(self):
70-
client = ParallelSSHClient([self.host], port=self.listen_port,
71-
pkey=self.user_key)
72-
output = client.run_command('exit 1')
75+
output = self.client.run_command('exit 1')
7376
expected_exit_code = 1
7477
exit_code = output[self.host]['exit_code']
75-
client.pool.join()
78+
self.client.pool.join()
7679
self.assertEqual(expected_exit_code, exit_code,
7780
msg="Got unexpected exit code - %s, expected %s" %
7881
(exit_code,
7982
expected_exit_code,))
8083

8184
def test_pssh_client_exec_command_get_buffers(self):
8285
client = ParallelSSHClient([self.host], port=self.listen_port,
83-
pkey=self.user_key)
86+
pkey=self.user_key,
87+
agent=self.agent)
8488
cmd = client.exec_command(self.fake_cmd)[0]
8589
output = client.get_stdout(cmd, return_buffers=True)
8690
expected_exit_code = 0
@@ -104,7 +108,8 @@ def test_pssh_client_exec_command_get_buffers(self):
104108

105109
def test_pssh_client_run_command_get_output(self):
106110
client = ParallelSSHClient([self.host], port=self.listen_port,
107-
pkey=self.user_key)
111+
pkey=self.user_key,
112+
agent=self.agent)
108113
output = client.run_command(self.fake_cmd)
109114
expected_exit_code = 0
110115
expected_stdout = [self.fake_resp]
@@ -170,7 +175,8 @@ def test_pssh_client_auth_failure(self):
170175
listen_port = listen_socket.getsockname()[1]
171176
server = start_server(listen_socket, fail_auth=True)
172177
client = ParallelSSHClient([self.host], port=listen_port,
173-
pkey=self.user_key)
178+
pkey=self.user_key,
179+
agent=self.agent)
174180
cmd = client.exec_command(self.fake_cmd)[0]
175181
# Handle exception
176182
try:
@@ -191,7 +197,7 @@ def test_pssh_client_hosts_list_part_failure(self):
191197
client = ParallelSSHClient(hosts,
192198
port=self.listen_port,
193199
pkey=self.user_key,
194-
)
200+
agent=self.agent)
195201
output = client.run_command(self.fake_cmd,
196202
stop_on_errors=False)
197203
self.assertTrue(hosts[0] in output,
@@ -258,7 +264,7 @@ def test_pssh_client_timeout(self):
258264
server.join()
259265

260266
def test_pssh_client_exec_command_password(self):
261-
"""Test password authentication. Fake server accepts any password
267+
"""Test password authentication. Embedded server accepts any password
262268
even empty string"""
263269
client = ParallelSSHClient([self.host], port=self.listen_port,
264270
password='')
@@ -501,7 +507,8 @@ def test_authentication_exception(self):
501507
server = start_server(_socket, fail_auth=True)
502508
hosts = [self.host]
503509
client = ParallelSSHClient(hosts, port=port,
504-
pkey=self.user_key)
510+
pkey=self.user_key,
511+
agent=self.agent)
505512
output = client.run_command(self.fake_cmd, stop_on_errors=False)
506513
client.pool.join()
507514
self.assertTrue('exception' in output[self.host],

tests/test_ssh_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def test_ssh_agent_authentication(self):
203203
agent = FakeAgent()
204204
agent.add_key(USER_KEY)
205205
client = SSHClient(self.host, port=self.listen_port,
206-
_agent=agent)
206+
agent=agent)
207207
channel, host, stdout, stderr = client.exec_command(self.fake_cmd)
208208
channel.close()
209209
output = list(stdout)

0 commit comments

Comments
 (0)