#!/usr/bin/env python # vim:ts=2:et:sw=2:ai # # Check configs with remote addresses # # Rick van der Zwet # import argparse import gformat import getpass import netsnmp import os import paramiko import socket import sys import time SSHPASS = None netsnmp.verbose = 0 class CmdError(Exception): pass def check_host(hostname): cmd = "cat /etc/board.info" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname, username='root', password=SSHPASS,timeout=3) stdin, stdout, stderr = ssh.exec_command(cmd) stdout = stdout.readlines() stderr = stderr.readlines() ssh.close() if stderr: raise CmdError(stderr) return dict(map(lambda x: x.strip().split('='),stdout)) def get_bridge_type(host): """ Both NS and NS Mx uses a slighly different OID""" var_list = netsnmp.VarList( *map(lambda x: netsnmp.Varbind(x), ['.1.2.840.10036.3.1.2.1.3.6', '.1.2.840.10036.3.1.2.1.3.7'])) sess = netsnmp.Session(Version=1, DestHost=host, Community='public', Timeout=2 * 100000, Retries=1) retval = sess.get(var_list) if sess.ErrorInd < 0: raise CmdError('SNMP Failed -- [%(ErrorInd)s] %(ErrorStr)s (%(DestHost)s)' % vars(sess)) return filter(None, retval)[0] def update_hosts(filters=[]): for host in gformat.get_hostlist(): if filters and not any([f.lower() in host.lower() for f in filters]): continue print "# Processing host", host datadump = gformat.get_yaml(host) for iface_key in datadump['autogen_iface_keys']: ifacedump = datadump[iface_key] if ifacedump.has_key('ns_ip') and ifacedump['ns_ip']: addr = ifacedump['ns_ip'].split('/')[0] print "## Bridge IP: %(ns_ip)s at %(interface)s" % ifacedump try: socket.create_connection((addr,80),2) bridge_type = get_bridge_type(addr) datadump[iface_key]['bridge_type'] = bridge_type except (socket.timeout, socket.error) as e: print "### %s (%s)" % (e, addr) except paramiko.AuthenticationException: print "### Conection failed (invalid username/password)" except CmdError, e: print "### Command error: %s" % e gformat.store_yaml(datadump) def make_output(stdout, stderr): def p(prefix, lines): return ''.join(["#%s: %s" % (prefix, line) for line in lines]) output = p('STDOUT', stdout) output += p('STDERR', stderr) return output def ubnt_snmp(hostname): lines = """\ snmp.community=public snmp.contact=beheer@lijst.wirelessleiden.nl snmp.location=WL snmp.status=enabled\ """ cmd = 'mca-config get /tmp/get.cfg && grep -v snmp /tmp/get.cfg > /tmp/new.cfg && echo "%s" >> /tmp/new.cfg \ && mca-config activate /tmp/new.cfg 1>/dev/null 2>/dev/null && echo "ALL DONE"' % lines ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname, username='root', password=SSHPASS,timeout=3) stdin, stdout, stderr = ssh.exec_command(cmd) stdout = stdout.readlines() stderr = stderr.readlines() print make_output(stdout, stderr) ssh.close() def ubnt_keys(hostname): keys = open(os.path.join(gformat.NODE_DIR,'global_keys'),'r').read() ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname, username='root', password=SSHPASS,timeout=3) cmd = 'test -d .ssh || mkdir .ssh;\ cat > .ssh/authorized_keys && \ chmod 0700 .ssh && \ chmod 0755 . && cfgmtd -p /etc -w' stdin, stdout, stderr = ssh.exec_command(cmd) stdin.write(keys) stdin.flush() stdin.channel.shutdown_write() stdout = stdout.readlines() stderr = stderr.readlines() print make_output(stdout, stderr) ssh.close() if __name__ == '__main__': # create the top-level parser parser = argparse.ArgumentParser(prog='Various WL management tools') parser.add_argument('--ask-pass', dest="ask_pass", action='store_true', help='Ask password if SSHPASS is not found') subparsers = parser.add_subparsers(help='sub-command help') parser_snmp = subparsers.add_parser('snmp', help='enable SNMP on UBNT') parser_snmp.add_argument('host',type=str) parser_snmp.set_defaults(func='snmp') parser_keys = subparsers.add_parser('keys', help='add ssh keys on UBNT') parser_keys.add_argument('host', type=str) parser_keys.set_defaults(func='keys') parser_update = subparsers.add_parser('update', help='process all UBNT') parser_update.add_argument('filters', default=None, nargs='*', type=str) parser_update.set_defaults(func='update') args = parser.parse_args() try: SSHPASS = os.environ['SSHPASS'] except KeyError: print "#WARN: SSHPASS environ variable not found" if args.ask_pass: SSHPASS = getpass.getpass("WL root password: ") if args.func == 'keys': ubnt_keys(args.host) elif args.func == 'snmp': ubnt_snmp(args.host) elif args.func == 'update': update_hosts(args.filters)