Imported repo juju-charms
[osm/devops.git] / juju-charms / layers / vyos-proxy / reactive / vyos_proxy.py
diff --git a/juju-charms/layers/vyos-proxy/reactive/vyos_proxy.py b/juju-charms/layers/vyos-proxy/reactive/vyos_proxy.py
new file mode 100644 (file)
index 0000000..a8fd5e0
--- /dev/null
@@ -0,0 +1,99 @@
+
+import subprocess
+import paramiko
+
+from charmhelpers.core.hookenv import (
+    config,
+    status_set,
+    action_get,
+    action_set,
+    action_fail,
+)
+
+from charms.reactive import (
+    when,
+    when_not,
+    set_state as set_flag,
+    remove_state as remove_flag,
+)
+
+
+@when('config.changed')
+def test_connection():
+    status_set('maintenance', 'configuring ssh connection')
+    remove_flag('vyos-proxy.ready')
+    try:
+        who, _ = run('whoami')
+    except MgmtNotConfigured as e:
+        remove_flag('vyos-proxy.configured')
+        status_set('blocked', str(e))
+    except subprocess.CalledProcessError as e:
+        remove_flag('vyos-proxy.configured')
+        status_set('blocked', e.output)
+    else:
+        set_flag('vyos-proxy.configured')
+
+
+@when('vyos-proxy.configured')
+@when_not('vyos-proxy.ready')
+def vyos_proxy_ready():
+    status_set('active', 'ready')
+    set_flag('vyos-proxy.ready')
+
+
+@when('actions.ping')
+@when_not('vyos-proxy.configured')
+def pingme():
+    action_fail('proxy is not ready')
+
+
+@when('actions.ping')
+@when('vyos-proxy.configured')
+def pingme_forreal():
+    try:
+        result, err = run('ping -qc {} {}'.format(action_get('count'), action_get('destination')))
+    except:
+        action_fail('ping command failed')
+    finally:
+        remove_flag('actions.ping')
+
+    # Here you can send results back from ping, if you had time to parse it
+    action_set({'output': result})
+
+
+
+class MgmtNotConfigured(Exception):
+    pass
+
+
+def run(cmd):
+    ''' 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 '''
+
+    cfg = config()
+
+    hostname = cfg.get('hostname')
+    password = cfg.get('pass')
+    username = cfg.get('user')
+
+    if not (username and password and hostname):
+        raise MgmtNotConfigured('incomplete remote credentials')
+
+    client = paramiko.SSHClient()
+    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+    try:
+        client.connect(cfg.get('hostname'), port=22,
+                       username=cfg.get('user'), password=cfg.get('pass'))
+    except paramiko.ssh_exception.AuthenticationException:
+        raise MgmtNotConfigured('invalid credentials')
+
+    stdin, stdout, stderr = client.exec_command(cmd)
+    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))