| |
| 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)) |