diff --git a/inventory_provider/router_interfaces.py b/inventory_provider/router_interfaces.py index fb66ca4bfaa303fbeee70bf80423587e8da041d4..b52e936081f11469b73e24423ac7d66feaccdc74 100644 --- a/inventory_provider/router_interfaces.py +++ b/inventory_provider/router_interfaces.py @@ -1,5 +1,6 @@ import contextlib import json +import logging import re from multiprocessing import Pool, Process, Queue @@ -46,12 +47,8 @@ def walk(agent_hostname, community, base_oid): """ https://stackoverflow.com/a/45001921 http://snmplabs.com/pysnmp/docs/hlapi/asyncore/sync/manager/cmdgen/nextcmd.html - http://snmplabs.com/pysnmp/faq/pass-custom-mib-to-manager.html - https://github.com/etingof/pysnmp/blob/master/examples/v3arch/asyncore/manager/cmdgen/getnext-multiple-oids-and-resolve-with-mib.py - - http://snmplabs.com/pysnmp/examples/smi/manager/browsing-mib-tree.html :param agent_hostname: @@ -67,7 +64,7 @@ def walk(agent_hostname, community, base_oid): # Pre-load MIB modules we expect to work with mibBuilder.loadModules('SNMPv2-MIB', 'SNMP-COMMUNITY-MIB', 'RFC1213-MIB') - # print("walking %s: %s" % (agent_hostname, base_oid)) + # logging.debug("walking %s: %s" % (agent_hostname, base_oid)) for (engineErrorIndication, pduErrorIndication, errorIndex, @@ -89,8 +86,6 @@ def walk(agent_hostname, community, base_oid): # for x in varBinds] for oid, val in varBinds: yield {"oid": "." + str(oid), "value": val.prettyPrint()} - # print("\toid: '%s', val: '%s'" % ( - # oid.prettyPrint(), val.prettyPrint())) def _validate_config(ctx, param, value): @@ -128,7 +123,7 @@ def load_routers(config_file): for line in config_file: m = re.match(r'^([a-z\d]+\.[a-z\d]{3,4}\.[a-z\d]{2}\.(geant|eumedconnect)\d*\.net)\s*=([^,]+)\s*,(.*)\s*$', line) if not m: - print("malformed config file line: '%s'" + line.strip()) + logging.warning("malformed config file line: '%s'" + line.strip()) continue yield { "hostname": m.group(1), @@ -136,6 +131,7 @@ def load_routers(config_file): "address": m.group(4) } + @contextlib.contextmanager def connection(alarmsdb): cx = None @@ -145,7 +141,6 @@ def connection(alarmsdb): user=alarmsdb["username"], passwd=alarmsdb["password"], db=alarmsdb["dbname"]) - # print(cx) yield cx finally: if cx: @@ -165,11 +160,11 @@ def cursor(cnx): def _db_test(db, router): with cursor(db) as crs: - # print(router) + logging.debug("_db_test: %r" % router) query = "SELECT absid FROM routers WHERE hostname = %s" crs.execute(query, (router['hostname'],)) for (absid,) in crs: - print(absid) + logging.debug("absid: %r" % absid) def _v6address_oid2str(dotted_decimal): @@ -186,9 +181,7 @@ def get_router_interfaces(router): details = {} for name, oid in oid_map.items(): details[name] = walk(router["hostname"], router["community"], oid) - # print(name) details[name] = list(details[name]) - # print(details[name]) v4IfcNames = {} for v4IfcName in details["v4InterfaceName"]: @@ -252,35 +245,34 @@ def exec_router_commands_json(router, ssh_params, commands): assert stdout.channel.recv_exit_status() == 0 for c in commands: - print("command: '%s'" % (c + " | display json")) + logging.debug("command: '%s'" % (c + " | display json")) _, stdout, _ = ssh.exec_command(c + " | display json") assert stdout.channel.recv_exit_status() == 0 # TODO: error handling - # output = stdout.read() output = stdout.read() if output: - print("%r output: [%d] %r" % (router, len(output), output[:20])) + logging.debug("%r output: [%d] %r" % (router, len(output), output[:20])) yield json.loads(output) else: - print("%r output empty") + logging.debug("%r output empty") yield {} def get_router_interfaces_q(router, q): - print("[ENTER>>] get_router_interfaces_q: %r" % router) + logging.debug("[ENTER>>] get_router_interfaces_q: %r" % router) q.put(list(get_router_interfaces(router))) - print("[<<EXIT] get_router_interfaces_q: %r" % router) + logging.debug("[<<EXIT] get_router_interfaces_q: %r" % router) def exec_router_commands_json_q(router, ssh_params, commands, q): - print("[ENTER>>] exec_router_commands_q: %r" % router) + logging.debug("[ENTER>>] exec_router_commands_q: %r" % router) q.put(list(exec_router_commands_json(router, ssh_params, commands))) - print("[<<EXIT] exec_router_commands_q: %r" % router) + logging.debug("[<<EXIT] exec_router_commands_q: %r" % router) def get_router_details(router, params, q): - print("get_router_details: %r" % router) + logging.debug("get_router_details: %r" % router) commands = [ 'show configuration routing-instances IAS protocols bgp', @@ -300,33 +292,22 @@ def get_router_details(router, params, q): commands_proc = Process(target=exec_router_commands_json_q, args=(router, params["ssh"], commands, commands_proc_queue)) commands_proc.start() - result = {} - - print("waiting for commands result: %r" % router) + logging.debug("waiting for commands result: %r" % router) command_output = commands_proc_queue.get() assert len(command_output) == len(commands) result = dict(zip(["bgp", "vrr", "interfaces"], command_output)) commands_proc.join() - print("... got commands result & joined: %r" % router) + logging.debug("... got commands result & joined: %r" % router) - print("waiting for snmp ifc results: %r" % router) + logging.debug("waiting for snmp ifc results: %r" % router) result["snmp-interfaces"] = snmpifc_proc_queue.get() snmpifc_proc.join() - print("... got snmp ifc result & joined: %r" % router) + logging.debug("... got snmp ifc result & joined: %r" % router) q.put(result) -@click.command() -@click.option( - "--config", -# required=True, - type=click.File(), - help="Configuration filename", - - default=open("config.json"), - callback=_validate_config) -def cli(config): +def load_network_details(config): with open("routers_community.conf") as f: routers = list(load_routers(f)) @@ -339,43 +320,32 @@ def cli(config): result = {} for p in processes: - print("waiting for get_router_details result: %r" % p["router"]) + logging.debug("waiting for get_router_details result: %r" % p["router"]) result[p["router"]["hostname"]] = p["queue"].get() p["process"].join() - print("got result and joined get_router_details proc: %r" % p["router"]) + logging.debug("got result and joined get_router_details proc: %r" % p["router"]) + + return result + +@click.command() +@click.option( + "--config", +# required=True, + type=click.File(), + help="Configuration filename", + + default=open("config.json"), + callback=_validate_config) +def cli(config): + network_details = load_network_details(config) filename = "/tmp/router-info.json" + logging.debug("writing output to: " + filename) with open(filename, "w") as f: - f.write(json.dumps(result)) - - print("writing output to: " + filename) - - # for r, i in zip(routers, pool.map(get_router_details, args)): - # print(r) - # print(i) - # print("") - # break - # # i = get_router_interfaces(r) - # # print(r["hostname"]) - # # for ifc in i: - # # print("\t%r" % ifc) - # # break - # # # commands = [ - # # # 'show configuration routing-instances IAS protocols bgp | display set | match neighbor | match description | match "GEANT-IX | GEANT-IX-"', - # # # 'show configuration routing-instances IAS protocols bgp | display set | match neighbor | match description | match "GEANT-IXv6 | GEANT-IXv6-"', - # # # 'show configuration logical-systems VRR protocols bgp group VPN-RR-INTERNAL | match "neigh|desc"', - # # # 'show configuration logical-systems VRR protocols bgp group VPN-RR | match "neigh|desc"' - # # # ] - # # # for lines in exec_router_commands(r, config["ssh"], commands): - # # # print("-------------") - # # # print("".join(lines)) - # # break + f.write(json.dumps(network_details)) + if __name__ == "__main__": + logging.basicConfig(level=logging.DEBUG) cli() - # with open("oid_list.conf") as f: - # print(load_oids(f)) - # with open("routers_community.conf") as f: - # for r in load_routers(f): - # _db_test(r)