1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
##############################################################################
# Copyright (c) 2015 Ericsson AB and others.
# Authors: George Paraskevopoulos (geopar@intracom-telecom.com)
# Jose Lausuch (jose.lausuch@ericsson.com)
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
import paramiko
import functest.utils.functest_logger as rl
import os
logger = rl.Logger('SSHUtils').getLogger()
def get_ssh_client(hostname, username, password=None, proxy=None):
client = None
try:
if proxy is None:
client = paramiko.SSHClient()
else:
client = ProxyHopClient()
client.configure_jump_host(proxy['ip'],
proxy['username'],
proxy['password'])
if client is None:
raise Exception('Could not connect to client')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname,
username=username,
password=password)
return client
except Exception, e:
logger.error(e)
return None
def get_file(ssh_conn, src, dest):
try:
sftp = ssh_conn.open_sftp()
sftp.get(src, dest)
return True
except Exception, e:
logger.error("Error [get_file(ssh_conn, '%s', '%s']: %s" %
(src, dest, e))
return None
def put_file(ssh_conn, src, dest):
try:
sftp = ssh_conn.open_sftp()
sftp.put(src, dest)
return True
except Exception, e:
logger.error("Error [put_file(ssh_conn, '%s', '%s']: %s" %
(src, dest, e))
return None
class ProxyHopClient(paramiko.SSHClient):
'''
Connect to a remote server using a proxy hop
'''
def __init__(self, *args, **kwargs):
self.logger = rl.Logger("ProxyHopClient").getLogger()
self.proxy_ssh = None
self.proxy_transport = None
self.proxy_channel = None
self.proxy_ip = None
self.proxy_ssh_key = None
self.local_ssh_key = os.path.join(os.getcwd(), 'id_rsa')
super(ProxyHopClient, self).__init__(*args, **kwargs)
def configure_jump_host(self, jh_ip, jh_user, jh_pass,
jh_ssh_key='/root/.ssh/id_rsa'):
self.proxy_ip = jh_ip
self.proxy_ssh_key = jh_ssh_key
self.proxy_ssh = paramiko.SSHClient()
self.proxy_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.proxy_ssh.connect(jh_ip,
username=jh_user,
password=jh_pass)
self.proxy_transport = self.proxy_ssh.get_transport()
def connect(self, hostname, port=22, username='root', password=None,
pkey=None, key_filename=None, timeout=None, allow_agent=True,
look_for_keys=True, compress=False, sock=None, gss_auth=False,
gss_kex=False, gss_deleg_creds=True, gss_host=None,
banner_timeout=None):
try:
if self.proxy_ssh is None:
raise Exception('You must configure the jump '
'host before calling connect')
get_file_res = get_file(self.proxy_ssh,
self.proxy_ssh_key,
self.local_ssh_key)
if get_file_res is None:
raise Exception('Could\'t fetch SSH key from jump host')
proxy_key = (paramiko.RSAKey
.from_private_key_file(self.local_ssh_key))
self.proxy_channel = self.proxy_transport.open_channel(
"direct-tcpip",
(hostname, 22),
(self.proxy_ip, 22))
self.set_missing_host_key_policy(paramiko.AutoAddPolicy())
super(ProxyHopClient, self).connect(hostname,
username=username,
pkey=proxy_key,
sock=self.proxy_channel)
os.remove(self.local_ssh_key)
except Exception, e:
self.logger.error(e)
|