Newer
Older
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
import paramiko
import subprocess
from charmhelpers.core.hookenv import config
class NetNS(object):
def __init__(self, name):
pass
@classmethod
def create(cls, name):
# @TODO: Need to check if namespace exists already
try:
ip('netns', 'add', name)
except Exception as e:
raise Exception('could not create net namespace: %s' % e)
return cls(name)
def up(self, iface, cidr):
self.do('ip', 'link', 'set', 'dev', iface, 'up')
self.do('ip', 'address', 'add', cidr, 'dev', iface)
def add_iface(self, iface):
ip('link', 'set', 'dev', iface, 'netns', self.name)
def do(self, *cmd):
ip(*['netns', 'exec', self.name] + cmd)
def ip(*args):
return _run(['ip'] + list(args))
def _run(cmd, env=None):
if isinstance(cmd, str):
cmd = cmd.split() if ' ' in cmd else [cmd]
cfg = config()
if all(k in cfg for k in ['pass', 'vpe-router', 'user']):
router = cfg['vpe-router']
user = cfg['user']
passwd = cfg['pass']
if router and user and passwd:
return ssh(cmd, router, user, passwd)
p = subprocess.Popen(cmd,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
retcode = p.poll()
if retcode > 0:
raise subprocess.CalledProcessError(returncode=retcode,
cmd=cmd,
output=stderr.decode("utf-8").strip())
return (''.join(stdout), ''.join(stderr))
def ssh(cmd, host, user, password=None):
''' Suddenly this project needs to SSH to something. So we replicate what
_run was doing with subprocess using the Paramiko library. This is
temporary until this charm /is/ the VPE Router '''
cmds = ' '.join(cmd)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, port=22, username=user, password=password)
stdin, stdout, stderr = client.exec_command(cmds)
retcode = stdout.channel.recv_exit_status()
client.close() # @TODO re-use connections
if retcode > 0:
output = stderr.read().strip()
raise subprocess.CalledProcessError(returncode=retcode, cmd=cmd,
output=output)
return (''.join(stdout), ''.join(stderr))