diff --git a/inventory_provider/routes/testing.py b/inventory_provider/routes/testing.py index 744b9b2f3986b3bdd607a3380965c7adf05b43d7..d63cb3c2a1137640bf4e24959a7d38241d20801f 100644 --- a/inventory_provider/routes/testing.py +++ b/inventory_provider/routes/testing.py @@ -1,8 +1,10 @@ import json import os +from operator import itemgetter -from flask import Blueprint, Response, jsonify, current_app +from flask import Blueprint, Response, jsonify, current_app, request from lxml import etree +from tree_format import format_tree from inventory_provider import juniper from inventory_provider.routes import common @@ -108,3 +110,71 @@ def latch_db(): worker_common.latch_db(config) r = worker_common.get_current_redis(config) return jsonify(worker_common.get_latch(r)) + + +@routes.route("/circuit-tree/<path:root_identifier>", + methods=['GET', 'POST']) +def circuit_tree(root_identifier: str): + carriers = request.args.get('carriers', default='false', type=str) + interface_ = request.args.get('interface', default='false', type=str) + + if carriers: + children_prop = 'carrier-circuits' + else: + children_prop = 'sub-circuits' + + config = current_app.config["INVENTORY_PROVIDER_CONFIG"] + r = worker_common.get_current_redis(config) + + def _get_childcircuit_tree_local(circuit_id): + circuit = r.get(f'ims:circuit_hierarchy:{circuit_id}') + if not circuit: + return None + circuit = json.loads(circuit.decode('utf-8'))[0] + _tree = [ + f'{circuit["id"]} -- {circuit["name"]} -- ' + f'prod: {circuit["product"]} -- ' + f'spd: {circuit["speed"]} -- ' + f'status: {circuit["status"]}' + ] + + if circuit.get(children_prop, None): + + children = [] + for child_id in circuit[children_prop]: + v = _get_childcircuit_tree_local(child_id) + if v: + children.append(v) + _tree.append(children) + else: + _tree.append([]) + return _tree + + if interface_: + + if_services = r.get(f'ims:interface_services:{root_identifier}') + if if_services: + root_identifiers = [s['id'] for s in json.loads(if_services)] + children = [] + for id_ in root_identifiers: + children.append(_get_childcircuit_tree_local(id_)) + + tree = [root_identifier, children] + else: + return "Nothing found" + else: + try: + root_identifier = int(root_identifier) + except ValueError: + for k in r.scan_iter('ims:circuit_hierarchy:*', count=2000): + ch = r.get(k.decode('utf-8')) + details = json.loads(ch.decode('utf-8'))[0] + if root_identifier.lower() == details['name'].lower(): + root_identifier = details['id'] + break + else: + return f'No circuit found for: {root_identifier}' + + tree = _get_childcircuit_tree_local(root_identifier) + + return f'<pre>{format_tree(tree, format_node = itemgetter(0), get_children = itemgetter(1))}</pre>' diff --git a/requirements.txt b/requirements.txt index 251a3baed8a70211def8c5eed3a1bf1dac9ea2c3..dac8c3c31d676c037b165cb45c2f13b04f8815e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ junos-eznc==2.2.1 lxml requests netifaces +tree-format pytest pytest-mock diff --git a/setup.py b/setup.py index 438d238b28053bb0cbdf75d0dc8b1e213cf5f60b..acdcf1f0e57266b4f5e76c3ebc3d2b1436a3c60c 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,8 @@ setup( 'junos-eznc==2.2.1', 'lxml', 'requests', - 'netifaces' + 'netifaces', + 'tree-format' ], entry_points={ 'console_scripts': [