33"""Module containing wrapper classes over paramiko.SSHClient
44See SSHClient and ParallelSSHClient"""
55
6- import paramiko
7- import os
86import gevent .pool
97from gevent import monkey
108monkey .patch_all ()
9+ import paramiko
10+ import os
1111import logging
1212import socket
1313
@@ -35,7 +35,8 @@ class SSHClient(object):
3535 """Wrapper class over paramiko.SSHClient with sane defaults"""
3636
3737 def __init__ (self , host ,
38- user = None ):
38+ user = None ,
39+ password = None ):
3940 """Connect to host honoring any user set configuration in ~/.ssh/config or /etc/ssh/ssh_config
4041 :type: str
4142 :param host: Hostname to connect to
@@ -66,13 +67,17 @@ def __init__(self, host,
6667 self .client = client
6768 self .channel = None
6869 self .user = user
70+ self .password = password
6971 self .host = resolved_address
7072 self ._connect ()
7173
7274 def _connect (self ):
7375 """Connect to host, throw UnknownHost exception on DNS errors"""
7476 try :
75- self .client .connect (self .host , username = self .user )
77+ if self .password is not None :
78+ self .client .connect (self .host , username = self .user , password = self .password )
79+ else :
80+ self .client .connect (self .host , username = self .user )
7681 except socket .gaierror , e :
7782 logger .error ("Could not resolve host '%s'" % (self .host ,))
7883 raise UnknownHostException ("%s - %s" % (str (e .args [1 ]), self .host ,))
@@ -97,8 +102,9 @@ def exec_command(self, command, sudo = False, **kwargs):
97102class ParallelSSHClient (object ):
98103 """Uses SSHClient, runs command on multiple hosts in parallel"""
99104
100- def __init__ (self , hosts , pool_size = 10 ,
101- user = None ):
105+ def __init__ (self , hosts ,
106+ pool_size = 10 ):
107+
102108 """Connect to hosts
103109 :type: list(str)
104110 :param hosts: Hosts to connect to
@@ -112,9 +118,9 @@ def __init__(self, hosts, pool_size = 10,
112118 self .pool = gevent .pool .Pool (size = pool_size )
113119 self .pool_size = pool_size
114120 self .hosts = hosts
115- self . user = user
121+
116122 # Initialise connections to all hosts
117- self .host_clients = dict ((host , SSHClient (host , user = user )) for host in hosts )
123+ self .host_clients = dict ((host [ 0 ] , SSHClient (host [ 0 ] , user = host [ 1 ], password = host [ 2 ] )) for host in hosts )
118124
119125 def exec_command (self , * args , ** kwargs ):
120126 """Run command on all hosts in parallel, honoring self.pool_size"""
0 commit comments