5 from charmhelpers.core.hookenv import config
9 def __init__(self, name):
13 def create(cls, name):
14 # @TODO: Need to check if namespace exists already
16 ip('netns', 'add', name)
17 except Exception as e:
18 raise Exception('could not create net namespace: %s' % e)
22 def up(self, iface, cidr):
23 self.do('ip', 'link', 'set', 'dev', iface, 'up')
24 self.do('ip', 'address', 'add', cidr, 'dev', iface)
26 def add_iface(self, iface):
27 ip('link', 'set', 'dev', iface, 'netns', self.name)
30 ip(*['netns', 'exec', self.name] + cmd)
34 return _run(['ip'] + list(args))
37 def _run(cmd, env=None):
38 if isinstance(cmd, str):
39 cmd = cmd.split() if ' ' in cmd else [cmd]
42 if all(k in cfg for k in ['pass', 'vpe-router', 'user']):
43 router = cfg['vpe-router']
47 if router and user and passwd:
48 return ssh(cmd, router, user, passwd)
50 p = subprocess.Popen(cmd,
52 stdout=subprocess.PIPE,
53 stderr=subprocess.PIPE)
54 stdout, stderr = p.communicate()
57 raise subprocess.CalledProcessError(returncode=retcode,
59 output=stderr.decode("utf-8").strip())
60 return (''.join(stdout), ''.join(stderr))
63 def ssh(cmd, host, user, password=None):
64 ''' Suddenly this project needs to SSH to something. So we replicate what
65 _run was doing with subprocess using the Paramiko library. This is
66 temporary until this charm /is/ the VPE Router '''
69 client = paramiko.SSHClient()
70 client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
71 client.connect(host, port=22, username=user, password=password)
73 stdin, stdout, stderr = client.exec_command(cmds)
74 retcode = stdout.channel.recv_exit_status()
75 client.close() # @TODO re-use connections
77 output = stderr.read().strip()
78 raise subprocess.CalledProcessError(returncode=retcode, cmd=cmd,
80 return (''.join(stdout), ''.join(stderr))