diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index 863f1f0cbb2c50fc44d7b8685631b2f18b5e3115..e5576d489b44e467a12f213a7d14d0920b8da7e4 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -43,16 +43,10 @@ def after_request(resp): return common.after_request(resp) -def base_interface_name(interface): - m = re.match(r'(.*?)(\.\d+)?$', interface) - assert m # sanity: anything should match - return m.group(1) - - def related_interfaces(hostname, interface): r = common.get_current_redis() prefix = 'netconf-interfaces:%s:' % hostname - for k in r.keys(prefix + base_interface_name(interface) + '.*'): + for k in r.keys(prefix + interface + '.*'): k = k.decode('utf-8') assert k.startswith(prefix) # sanity assert len(k) > len(prefix) # sanity (contains at least an interface) @@ -68,11 +62,11 @@ def get_top_level_services(circuit_id, r): for c in results: temp_parents = \ get_top_level_services(c['parent_circuit_id'], r) - if not temp_parents and \ - c['parent_circuit_type'].lower() == 'service': + if not temp_parents: tls.append( {'name': c['parent_circuit'], - 'status': c['parent_circuit_status']}) + 'status': c['parent_circuit_status'], + 'circuit_type': c['parent_circuit_type'].lower()}) tls.extend(temp_parents) return tls @@ -93,33 +87,12 @@ def get_juniper_link_info(source_equipment, interface): result = {} top_level_services = [] - def _get_top_level_services(circuit_id): - tls = [] - results = r.get("opsdb:services:children:{}".format(circuit_id)) - if results: - results = json.loads(results.decode('utf-8')) - - for c in results: - if circuit_id == c['child_circuit_id']: - tls.append( - {'name': c['parent_circuit'], - 'status': c['parent_circuit_status']}) - else: - temp_parents = \ - _get_top_level_services(c['child_circuit_id']) - if not temp_parents: - tls.append( - {'name': c['parent_circuit'], - 'status': c['parent_circuit_status']}) - tls.extend(temp_parents) - return tls - services = r.get( 'opsdb:interface_services:%s:%s' % (source_equipment, interface)) if services: result['services'] = json.loads(services.decode('utf=8')) for s in result['services']: - top_level_services.extend(_get_top_level_services(s['id'])) + top_level_services.extend(get_top_level_services(s['id'], r)) ifc_info = r.get( 'netconf-interfaces:%s:%s' % (source_equipment, interface)) @@ -140,25 +113,24 @@ def get_juniper_link_info(source_equipment, interface): for related in related_interfaces(source_equipment, interface): rs = r.get('opsdb:interface_services:%s:%s' % (source_equipment, related)) + all_rs = [] if rs: for s in json.loads(rs.decode('utf-8')): top_level_services.extend( - _get_top_level_services(s['id'])) - yield {'name': s['name'], 'status': s['status']} - - related_services = list(_related_services()) + get_top_level_services(s['id'], r)) + all_rs.append( + { + 'name': s['name'], + 'status': s['status'], + 'circuit_type': s['circuit_type'] + }) + return all_rs + + related_services = _related_services() if related_services: - related_services.extend(top_level_services) - result['related-services'] = related_services - - # no longer possible, now that at least 'interface' is - # returned for unknown interfaces - # if not result: - # return Response( - # response="no available info for {} {}".format( - # source_equipment, interface), - # status=404, - # mimetype="text/html") + top_level_services.extend(related_services) + if top_level_services: + result['related-services'] = top_level_services result = json.dumps(result) # cache this data for the next call @@ -265,6 +237,14 @@ def find_interfaces_and_services(address_str): @common.require_accepts_json def peer_info(address): + # canonicalize the input address first ... + try: + obj = ipaddress.ip_address(address) + address = obj.exploded + except ValueError: + raise ClassifierProcessingError( + 'unable to parse %r as an ip address' % address) + r = common.get_current_redis() cache_key = 'classifier-cache:peer:%s' % address @@ -290,12 +270,6 @@ def peer_info(address): if interfaces: result['interfaces'] = interfaces - # if not result: - # return Response( - # response='no peering info found for %s' % address, - # status=404, - # mimetype="text/html") - result = json.dumps(result) # cache this data for the next call r.set(cache_key, result.encode('utf-8')) diff --git a/setup.py b/setup.py index ee7cc91c69fb3439fc4e02b17c82a778ed0169d5..3050666fce8c90092d340c843ff3d6151d99a296 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='inventory-provider', - version="0.30", + version="0.31", author='GEANT', author_email='swd@geant.org', description='Dashboard inventory provider', diff --git a/test/test_classifier_utilities.py b/test/test_classifier_utilities.py index 4075e69054aa9fe0f30b00eb7f614211223c0bda..80308e574c64f570849372b5d8168a461a161d46 100644 --- a/test/test_classifier_utilities.py +++ b/test/test_classifier_utilities.py @@ -1,29 +1,7 @@ -import pytest -from inventory_provider.routes import classifier from inventory_provider.routes.classifier import get_top_level_services from inventory_provider.tasks import common -@pytest.mark.parametrize('interface_name,base_name', [ - ('ae0', 'ae0'), - ('ae0.0', 'ae0'), - ('ae1.0', 'ae1'), - ('ae10.2603', 'ae10'), - ('et-3/1/2', 'et-3/1/2'), - ('et-3/1/2.100', 'et-3/1/2'), - ('xe-2/1/0', 'xe-2/1/0'), - ('xe-2/1/0.933', 'xe-2/1/0'), - - # degenerate cases ... check expected regex behavior - ('xe-2/1/0.933.933', 'xe-2/1/0.933'), - (' sss.333.aaa ', ' sss.333.aaa '), - (' sss.333.aaa .999', ' sss.333.aaa ') -] -) -def test_base_interface_name(interface_name, base_name): - assert classifier.base_interface_name(interface_name) == base_name - - # todo - not too keen on this as it relies on the extracted opsdb data, which # could change and lead to this test failing def test_get_top_level_circuits(mocked_redis):