Add a "dig" action
[osm/devops.git] / layers / netutils / reactive / layer_netutils.py
1 from charmhelpers.core.hookenv import (
2 config,
3 status_set,
4 action_get,
5 action_set,
6 action_fail,
7 log,
8 )
9
10 from charms.reactive import (
11 when,
12 when_not,
13 set_state as set_flag,
14 remove_state as remove_flag,
15 )
16
17 import subprocess
18
19
20 @when_not('netutils.ready')
21 def ready():
22 status_set('active', 'Ready!')
23 set_flag('netutils.ready')
24
25 @when('actions.dig')
26 def dig():
27 err = ''
28 try:
29 nsserver = action_get('nsserver')
30 host = action_get('host')
31 nstype = action_get('type')
32 cmd = "dig"
33
34 if nsserver:
35 cmd += " @{}".format(nsserver)
36 if host:
37 cmd += " {}".format(host)
38 else:
39 action_fail('Hostname required.')
40 if nstype:
41 cmd += " -t {}".format(nstype)
42
43 result, err = _run(cmd)
44 except:
45 action_fail('dig command failed:' + err)
46 else:
47 action_set({'outout': result})
48 finally:
49 remove_flag('actions.dig')
50
51 @when('actions.nmap')
52 def nmap():
53 err = ''
54 try:
55 result, err = _run('nmap {}'.format(action_get('destination')))
56 except:
57 action_fail('nmap command failed:' + err)
58 else:
59 action_set({'outout': result})
60 finally:
61 remove_flag('actions.nmap')
62
63
64 @when('actions.ping')
65 def ping():
66 err = ''
67 try:
68 result, err = _run('ping -qc {} {}'.format(
69 action_get('count'), action_get('destination'))
70 )
71
72 except:
73 action_fail('ping command failed:' + err)
74 else:
75 # Here you can send results back from ping, if you had time to parse it
76 action_set({'output': result})
77 finally:
78 remove_flag('actions.ping')
79
80
81
82 @when('actions.traceroute')
83 def traceroute():
84 try:
85 result, err = _run('traceroute -m {} {}'.format(action_get('hops'), action_get('destination')))
86 except:
87 action_fail('traceroute command failed')
88 else:
89 # Here you can send results back from ping, if you had time to parse it
90 action_set({'output': result})
91 finally:
92 remove_flag('actions.traceroute')
93
94
95
96 def _run(cmd, env=None):
97 if isinstance(cmd, str):
98 cmd = cmd.split() if ' ' in cmd else [cmd]
99
100 log(cmd)
101 p = subprocess.Popen(cmd,
102 env=env,
103 stdout=subprocess.PIPE,
104 stderr=subprocess.PIPE)
105 stdout, stderr = p.communicate()
106 retcode = p.poll()
107 if retcode > 0:
108 raise subprocess.CalledProcessError(returncode=retcode,
109 cmd=cmd,
110 output=stderr.decode("utf-8").strip())
111 return (stdout.decode('utf-8'), stderr.decode('utf-8'))