source: genesis/tools/check-batch-cmd@ 11947

Last change on this file since 11947 was 11730, checked in by rick, 12 years ago

Handle the infamous airLive case.

  • Property svn:executable set to *
File size: 6.5 KB
Line 
1#!/usr/bin/env python
2# vim:ts=2:et:sw=2:ai
3#
4# Check configs with remote addresses
5#
6# Rick van der Zwet <info@rickvanderzwet.nl>
7#
8import argparse
9import gformat
10import getpass
11import os
12import paramiko
13import subprocess
14import socket
15import sys
16import time
17import logging
18
19logging.basicConfig(level=logging.INFO)
20logger = logging.getLogger(__name__)
21logging.getLogger("paramiko").setLevel(logging.WARNING)
22
23SSHPASS = None
24import netsnmp
25
26class CmdError(Exception):
27 pass
28
29class ConnectError(Exception):
30 pass
31
32
33
34def host_ssh_cmd(hostname, cmd):
35 try:
36 ssh = paramiko.SSHClient()
37 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
38 ssh.connect(hostname, username='root', password=SSHPASS,timeout=3)
39 stdin, stdout, stderr = ssh.exec_command(cmd)
40 stdout = stdout.readlines()
41 stderr = stderr.readlines()
42 ssh.close()
43 if stderr:
44 raise CmdError((stderr, stdout))
45 return stdout
46 except (socket.error, paramiko.AuthenticationException) as e:
47 raise ConnectError(e)
48
49def parse_ini(lines):
50 return dict(map(lambda x: x.strip().split('='),lines))
51
52def ubnt_probe(hostname):
53 items = parse_ini(host_ssh_cmd(hostname, 'cat /etc/board.info'))
54 print items
55
56
57def get_bridge_type(host):
58 """ Both NS and NS Mx uses a slighly different OID"""
59 var_list = netsnmp.VarList(
60 *map(lambda x: netsnmp.Varbind(x),
61 ['.1.2.840.10036.3.1.2.1.3.5', '.1.2.840.10036.3.1.2.1.3.6', '.1.2.840.10036.3.1.2.1.3.7','.1.3.6.1.2.1.1.5.0']))
62
63 sess = netsnmp.Session(Version=1, DestHost=host, Community='public', Timeout=2 * 100000, Retries=1)
64 retval = sess.get(var_list)
65 if sess.ErrorInd < 0:
66 raise CmdError('SNMP Failed -- [%(ErrorInd)s] %(ErrorStr)s (%(DestHost)s)' % vars(sess))
67 if not filter(None, retval):
68 return None
69 else:
70 return filter(None, retval)[0]
71
72
73
74def node_check(host):
75 """ Using multiple connect methods to do some basic health checking as well"""
76
77 print "# Processing host", host
78 datadump = gformat.get_yaml(host)
79 output = host_ssh_cmd(datadump['autogen_fqdn'], 'cat /var/run/dmesg.boot')
80
81 # Get board Type
82 for line in [x.strip() for x in output]:
83 if line.startswith('CPU:'):
84 print line
85 elif line.startswith('Geode LX:'):
86 datadump['board'] = 'ALIX2'
87 print line
88 elif line.startswith('real memory'):
89 print line
90 elif line.startswith('Elan-mmcr'):
91 datadump['board'] = 'net45xx'
92 for iface_key in datadump['autogen_iface_keys']:
93 ifacedump = datadump[iface_key]
94 if ifacedump.has_key('ns_ip') and ifacedump['ns_ip']:
95 addr = ifacedump['ns_ip'].split('/')[0]
96 print "## Bridge IP: %(ns_ip)s at %(autogen_ifname)s" % ifacedump
97 try:
98 socket.create_connection((addr,80),2)
99 bridge_type = get_bridge_type(addr)
100 datadump[iface_key]['bridge_type'] = bridge_type
101 except (socket.timeout, socket.error) as e:
102 print "### %s (%s)" % (e, addr)
103 except paramiko.AuthenticationException:
104 print "### Conection failed (invalid username/password)"
105 except CmdError, e:
106 print "### Command error: %s" % e
107
108 try:
109 wl_release = subprocess.check_output(['snmpget', '-Oq', '-Ov', '-c', 'public', '-v2c',
110 datadump['autogen_fqdn'], 'UCD-SNMP-MIB::ucdavis.84.4.1.2.6.119.108.45.118.101.114.1'])
111 datadump['wl_release'] = int(wl_release.replace('"',''))
112 except subprocess.CalledProcessError, ValueError:
113 pass
114 gformat.store_yaml(datadump)
115
116
117def make_output(stdout, stderr):
118 def p(prefix, lines):
119 return ''.join(["#%s: %s" % (prefix, line) for line in lines])
120 output = p('STDOUT', stdout)
121 output += p('STDERR', stderr)
122 return output
123
124def ubnt_snmp(hostname):
125 lines = """\
126snmp.community=public
127snmp.contact=beheer@lijst.wirelessleiden.nl
128snmp.location=WL
129snmp.status=enabled\
130"""
131 cmd = 'mca-config get /tmp/get.cfg && grep -v snmp /tmp/get.cfg > /tmp/new.cfg && echo "%s" >> /tmp/new.cfg \
132 && mca-config activate /tmp/new.cfg 1>/dev/null 2>/dev/null && echo "ALL DONE"' % lines
133 ssh = paramiko.SSHClient()
134 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
135 ssh.connect(hostname, username='root', password=SSHPASS,timeout=3)
136 stdin, stdout, stderr = ssh.exec_command(cmd)
137 stdout = stdout.readlines()
138 stderr = stderr.readlines()
139 print make_output(stdout, stderr)
140 ssh.close()
141
142def ubnt_keys(hostname):
143 keys = open(os.path.join(gformat.NODE_DIR,'global_keys'),'r').read()
144 ssh = paramiko.SSHClient()
145 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
146 ssh.connect(hostname, username='root', password=SSHPASS,timeout=3)
147 cmd = 'test -d .ssh || mkdir .ssh;\
148 cat > .ssh/authorized_keys && \
149 chmod 0700 .ssh && \
150 chmod 0755 . && cfgmtd -p /etc -w'
151 stdin, stdout, stderr = ssh.exec_command(cmd)
152 stdin.write(keys)
153 stdin.flush()
154 stdin.channel.shutdown_write()
155 stdout = stdout.readlines()
156 stderr = stderr.readlines()
157 print make_output(stdout, stderr)
158 ssh.close()
159
160if __name__ == '__main__':
161 # create the top-level parser
162 parser = argparse.ArgumentParser(prog='Various WL management tools')
163 parser.add_argument('--ask-pass', dest="ask_pass", action='store_true', help='Ask password if SSHPASS is not found')
164 parser.add_argument('--filter', dest="use_filter", action='store_true', help='Thread the host definition as an filter')
165 subparsers = parser.add_subparsers(help='sub-command help')
166
167 parser_snmp = subparsers.add_parser('bridge', help='UBNT Bridge Management')
168 parser_snmp.add_argument('action', type=str, choices=['keys', 'snmp', 'probe'])
169 parser_snmp.add_argument('host',type=str)
170 parser_snmp.set_defaults(func='bridge')
171
172 parser_node = subparsers.add_parser('node', help='Proxy/Node/Hybrid Management')
173 parser_node.add_argument('action', type=str, choices=['check',])
174 parser_node.add_argument('host', type=str)
175 parser_node.set_defaults(func='node')
176
177 args = parser.parse_args()
178
179 try:
180 SSHPASS = os.environ['SSHPASS']
181 except KeyError:
182 print "#WARN: SSHPASS environ variable not found"
183 if args.ask_pass:
184 SSHPASS = getpass.getpass("WL root password: ")
185
186
187 if args.use_filter:
188 hosts = []
189 for host in gformat.get_hostlist():
190 if args.host in host:
191 hosts.append(host)
192 else:
193 hosts = [args.host]
194
195
196 for host in hosts:
197 try:
198 if args.func == 'bridge':
199 if args.action == 'keys':
200 ubnt_keys(host)
201 elif args.action == 'snmp':
202 ubnt_snmp(host)
203 elif args.action == 'probe':
204 ubnt_probe(host)
205 elif args.func == 'node':
206 if args.action == 'check':
207 node_check(host)
208 except ConnectError:
209 print "#ERR: Connection failed to host %s" % host
Note: See TracBrowser for help on using the repository browser.