diff --git a/inventory_provider/juniper.py b/inventory_provider/juniper.py deleted file mode 100644 index b63adf50d0a93167deb0d17f39a899033c5aaf86..0000000000000000000000000000000000000000 --- a/inventory_provider/juniper.py +++ /dev/null @@ -1,151 +0,0 @@ -import contextlib -import json -import logging -import re - -import paramiko - -from inventory_provider.constants import JUNIPER_LOGGER_NAME - - -def neighbors( - parsed_json_output, - routing_instances=["IAS"], - group_expression=r'^GEANT-IX(v6)?[\s-].*$'): - - for config in parsed_json_output["configuration"]: - for ri in config["routing-instances"]: - for inst in ri["instance"]: - if inst["name"]["data"] not in routing_instances: - continue - for prot in inst["protocols"]: - for bgp in prot.get("bgp", []): - for g in bgp.get("group", []): - if group_expression and not \ - re.match( - group_expression, - g["name"]["data"]): - continue - for n in g["neighbor"]: - yield n - - -def interfaces(parsed_json_output): - for ifc_info in parsed_json_output["interface-information"]: - for ifc_list in ifc_info["logical-interface"]: - for ifc in ifc_list: - yield { - "name": ifc["name"][0]["data"], - "status": "%s/%s" % ( - ifc["admin-status"][0]["data"], - ifc["oper-status"][0]["data"]), - "description": ifc["description"][0]["data"], - "type": "logical" - } - - -@contextlib.contextmanager -def ssh_connection(hostname, ssh_params): - # TODO: remove this relative path logic!! - import os - key_filename = os.path.join( - os.path.dirname(__file__), - ssh_params["private-key"]) - known_hosts = os.path.join( - os.path.dirname(__file__), - ssh_params["known-hosts"]) - k = paramiko.DSSKey.from_private_key_file(key_filename) - - with paramiko.SSHClient() as ssh: - ssh.load_host_keys(known_hosts) - ssh.connect( - hostname=hostname, - username=ssh_params['username'], - pkey=k) - yield ssh - - -def ssh_exec_commands(hostname, ssh_params, commands): - juniper_logger = logging.getLogger(JUNIPER_LOGGER_NAME) - with ssh_connection(hostname, ssh_params) as ssh: - - _, stdout, _ = ssh.exec_command("set cli screen-length 0") - assert stdout.channel.recv_exit_status() == 0 - - for c in commands: - juniper_logger.debug("command: '%s'" % c) - _, stdout, _ = ssh.exec_command(c) - assert stdout.channel.recv_exit_status() == 0 - # TODO: error handling - yield stdout.read().decode("utf-8") - - -def _loads(s, **args): - """ - the json text contains raw backslashes - :param s: - :param args: - :return: - """ - return json.loads(s.replace("\\", "\\\\"), **args) - - -_DISABLE_PAGING_COMMAND = r'set cli screen-length 0' - - -def fetch_bgp_config(hostname, ssh_params, **args): - - commands = [ - _DISABLE_PAGING_COMMAND, - ('show configuration routing-instances' - ' IAS protocols bgp | display json') - ] - - output = list(ssh_exec_commands(hostname, ssh_params, commands)) - assert len(output) == len(commands) - - if output[1]: - return list(neighbors(_loads(output[1]), **args)) - else: - return {} - - -def fetch_vrr_config(hostname, ssh_params): - - commands = [ - _DISABLE_PAGING_COMMAND, - ('show configuration logical-systems ' - 'VRR protocols bgp | display json') - ] - - output = list(ssh_exec_commands(hostname, ssh_params, commands)) - assert len(output) == len(commands) - - return _loads(output[1]) if output[1] else {} - - -def fetch_interfaces(hostname, ssh_params): - - def _dups_to_list(pairs): - counter_map = {} - for k, v in pairs: - counter_map.setdefault(k, []).append(v) - result = {} - for k, v in counter_map.items(): - if len(v) == 1: - result[k] = v[0] - else: - result[k] = v - return result - - commands = [ - _DISABLE_PAGING_COMMAND, - 'show interfaces descriptions | display json' - ] - - output = list(ssh_exec_commands(hostname, ssh_params, commands)) - assert len(output) == len(commands) - - return _loads( - output[1], - object_pairs_hook=_dups_to_list) if output[1] else {} diff --git a/test/data/update_test_data.py b/test/data/update_test_data.py deleted file mode 100644 index 393877a7af32a6967532d0a126390bf56fb36be3..0000000000000000000000000000000000000000 --- a/test/data/update_test_data.py +++ /dev/null @@ -1,119 +0,0 @@ -""" -this utility runs the juniper shell commands from dashboard -v1 and v3 on all routers and saves them to local files as -reusable unit test data -""" -import logging -import os -import multiprocessing - -from inventory_provider import juniper - -OUTPUT_DIR = os.path.dirname(__file__) -SSH_DIR = os.path.join( - os.path.dirname(__file__), - "..", - "..", - "inventory_provider", - "ssh") - -SSH_PARAMS = { - 'username': 'Monit0r', - 'private-key': os.path.join(SSH_DIR, 'monitor_dsa'), - 'known-hosts': os.path.join(SSH_DIR, 'monitor_known_hosts') -} - -SHELL_COMMANDS = [] -for c in juniper.shell_commands(): - SHELL_COMMANDS.append({"key": c["key"], "command": c["command"]}) - -SHELL_COMMANDS.append({ - "key": "bgpv4", - "command": (r'show configuration routing-instances IAS ' - r'protocols bgp | display set | match neighbor' - r' | match description' - r' | match "GEANT-IX | GEANT-IX-"') -}) - -SHELL_COMMANDS.append({ - "key": "bgpv6", - "command": (r'show configuration routing-instances IAS' - r' protocols bgp | display set | match neighbor' - r' | match description' - r' | match "GEANT-IXv6 | GEANT-IXv6-"') -}) - - -ROUTER_HOSTNAMES = [ - 'mx2.ath.gr.geant.net', - 'mx1.tal.ee.geant.net', - 'mx2.tal.ee.geant.net', - 'mx2.rig.lv.geant.net', - 'mx1.kau.lt.geant.net', - 'mx2.kau.lt.geant.net', - 'mx2.zag.hr.geant.net', - 'mx2.lju.si.geant.net', - 'mx1.bud.hu.geant.net', - 'mx1.pra.cz.geant.net', - 'mx2.bra.sk.geant.net', - 'mx1.lon.uk.geant.net', - 'mx1.vie.at.geant.net', - 'mx2.bru.be.geant.net', - 'mx1.poz.pl.geant.net', - 'mx1.ams.nl.geant.net', - 'mx1.fra.de.geant.net', - 'mx1.par.fr.geant.net', - 'mx1.gen.ch.geant.net', - 'mx1.mil2.it.geant.net', - 'mx1.lis.pt.geant.net', - 'mx2.lis.pt.geant.net', - 'mx1.mad.es.geant.net', - 'mx1.sof.bg.geant.net', - 'mx1.buc.ro.geant.net', - 'mx1.ham.de.geant.net', - 'mx1.dub.ie.geant.net', - 'mx1.dub2.ie.geant.net', - 'mx1.mar.fr.geant.net', - 'mx1.lon2.uk.geant.net', - 'mx1.ath2.gr.geant.net', -] - - -def ssh_exec_commands(hostname, ssh_params, commands, q): - logging.debug("[ENTER>>] ssh_exec_comands: %r" % hostname) - q.put(list(juniper.ssh_exec_commands(hostname, ssh_params, commands))) - logging.debug("[EXIT>>] ssh_exec_comands: %r" % hostname) - - -def main(): - processes = [] - for hostname in ROUTER_HOSTNAMES: - q = multiprocessing.Queue() - p = multiprocessing.Process( - target=ssh_exec_commands, - args=( - hostname, - SSH_PARAMS, - [c["command"] for c in SHELL_COMMANDS], - q)) - p.start() - processes.append({"hostname": hostname, "process": p, "queue": q}) - - for p in processes: - logging.debug("waiting for shell results from %r" % p["hostname"]) - for c, o in zip(SHELL_COMMANDS, p["queue"].get()): - if not c["key"]: - continue - filename = os.path.join( - OUTPUT_DIR, - "%s-%s.output" % (p["hostname"], c["key"])) - with open(filename, "w") as f: - f.write(o) - - p["process"].join() - logging.debug("saved shell results from %r" % p["hostname"]) - - -if __name__ == "__main__": - logging.basicConfig(level=logging.DEBUG) - main()