Skip to content
Snippets Groups Projects
layer_netutils.py 2.67 KiB
Newer Older
israelad's avatar
israelad committed
from charmhelpers.core.hookenv import (
    config,
    status_set,
    action_get,
    action_set,
    action_fail,
    log,
)

from charms.reactive import (
    when,
    when_not,
    set_state as set_flag,
    remove_state as remove_flag,
)

import subprocess


@when_not('netutils.ready')
def ready():
    status_set('active', 'Ready!')
    set_flag('netutils.ready')

israelad's avatar
israelad committed
@when('actions.dig')
def dig():
    err = ''
    try:
        nsserver = action_get('nsserver')
        host = action_get('host')
        nstype = action_get('type')
        cmd = "dig"

        if nsserver:
            cmd += " @{}".format(nsserver)
        if host:
            cmd += " {}".format(host)
        else:
            action_fail('Hostname required.')
        if nstype:
            cmd += " -t {}".format(nstype)

        result, err = _run(cmd)
    except:
        action_fail('dig command failed:' + err)
    else:
        action_set({'outout': result})
    finally:
        remove_flag('actions.dig')
israelad's avatar
israelad committed

@when('actions.nmap')
def nmap():
    err = ''
    try:
        result, err = _run('nmap {}'.format(action_get('destination')))
    except:
        action_fail('nmap command failed:' + err)
    else:
        action_set({'outout': result})
    finally:
        remove_flag('actions.nmap')


@when('actions.ping')
def ping():
    err = ''
    try:
        result, err = _run('ping -qc {} {}'.format(
            action_get('count'), action_get('destination'))
        )

    except:
        action_fail('ping command failed:' + err)
    else:
        # Here you can send results back from ping, if you had time to parse it
        action_set({'output': result})
    finally:
        remove_flag('actions.ping')



@when('actions.traceroute')
def traceroute():
    try:
        result, err = _run('traceroute -m {} {}'.format(action_get('hops'), action_get('destination')))
    except:
        action_fail('traceroute command failed')
    else:
        # Here you can send results back from ping, if you had time to parse it
        action_set({'output': result})
    finally:
        remove_flag('actions.traceroute')



def _run(cmd, env=None):
    if isinstance(cmd, str):
        cmd = cmd.split() if ' ' in cmd else [cmd]

    log(cmd)
    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 (stdout.decode('utf-8'), stderr.decode('utf-8'))