From a649e62db2321a96c9da4ddbb1b8e4505d5e05b5 Mon Sep 17 00:00:00 2001 From: Robert Latta <robert.latta@geant.org> Date: Thu, 12 Nov 2020 11:15:29 +0000 Subject: [PATCH] refactored location and related_services retrieval --- inventory_provider/routes/ims_classifier.py | 169 ++++++++++++-------- 1 file changed, 103 insertions(+), 66 deletions(-) diff --git a/inventory_provider/routes/ims_classifier.py b/inventory_provider/routes/ims_classifier.py index 96b63a0f..fc0eea3a 100644 --- a/inventory_provider/routes/ims_classifier.py +++ b/inventory_provider/routes/ims_classifier.py @@ -21,6 +21,15 @@ def _LOCATION(equipment, name, abbreviation): } +def build_locations(loc_a, loc_b=None): + locations = None + if loc_a: + locations = {'a': loc_a} + if loc_b: + locations['b'] = loc_b + return locations + + def _remove_duplicates_from_list(all): """ removes duplicates from the input list @@ -32,8 +41,7 @@ def _remove_duplicates_from_list(all): return list(tmp_dict.values()) -def _locations_from_router(router_name): - r = common.get_current_redis() +def _locations_from_router(router_name, r): result = r.get(f'ims:location:{router_name}') if not result: logger.error(f'error looking up location for {router_name}') @@ -54,8 +62,30 @@ def _locations_from_router(router_name): # once the switchover is done then will refactor to get rid of # _locations_from_router -def _location_from_equipment(equipment_name): - return _locations_from_router(equipment_name) +def _location_from_equipment(equipment_name, r): + # return _locations_from_router(equipment_name, r) + result = r.get(f'ims:location:{equipment_name}') + if not result: + logger.error(f'error looking up location for {equipment_name}') + return None + + result = json.loads(result.decode('utf-8')) + if not result: + logger.error(f'sanity failure: empty list for location {equipment_name}') + return None + + return _LOCATION( + equipment=result[0]['equipment-name'], + name=result[0]['pop']['name'], + abbreviation=result[0]['pop']['abbreviation']) + + +def _location_from_services(services, r): + for s in services: + loc_a = _location_from_equipment(s['equipment'], r) + loc_b = _location_from_equipment(s['other_end_equipment'], r) \ + if s['other_end_equipment'] else None + yield build_locations(loc_a, loc_b) # def _location_from_service_dict(s): @@ -108,6 +138,17 @@ def after_request(resp): return common.after_request(resp) +def get_ims_equipment_name(equipment_name: str) -> str: + ims_equipment_name = equipment_name.upper() + if ims_equipment_name.startswith('MX'): + ims_equipment_name = ims_equipment_name.split('.GEANT.NET')[0] + return ims_equipment_name + + +def get_ims_interface(interface: str) -> str: + return interface.upper() + + def related_interfaces(hostname, interface): r = common.get_current_redis() prefix = f'netconf-interfaces:{hostname}:' @@ -143,15 +184,22 @@ def get_top_level_services(circuit_id, r): return list(tls.values()) -def get_ims_equipment_name(equipment_name: str) -> str: - ims_equipment_name = equipment_name.upper() - if ims_equipment_name.startswith('MX'): - ims_equipment_name = ims_equipment_name.split('.GEANT.NET')[0] - return ims_equipment_name - - -def get_ims_interface(interface: str) -> str: - return interface.upper() +def get_related_services(source_equipment, interface, r): + ims_source_equipment = get_ims_equipment_name(source_equipment) + ims_interface = get_ims_interface(interface) + if_services = r.get(f'ims:interface_services:{ims_source_equipment}:' + f'{ims_interface}') + if if_services: + for s in json.loads(if_services.decode('utf-8')): + yield from get_top_level_services(s['id'], r) + for related in related_interfaces(source_equipment, interface): + ims_interface = get_ims_interface(related) + logger.debug(f'Related Interface: {ims_interface}') + rif_services = r.get( + f'ims:interface_services:{ims_source_equipment}:{ims_interface}') + if rif_services: + for s in json.loads(rif_services.decode('utf-8')): + yield from get_top_level_services(s['id'], r) @routes.route("/juniper-link-info/<source_equipment>/<path:interface>", @@ -177,19 +225,6 @@ def get_juniper_link_info(source_equipment: str, interface: str): 'locations': [] } - top_level_services = [] - - services = r.get( - f'ims:interface_services:{ims_source_equipment}:{ims_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'], r)) - - result['locations'] += _location_from_equipment(s['equipment']) - result['locations'] += \ - _location_from_equipment(s['other_end_equipment']) - ifc_info = r.get(f'netconf-interfaces:{source_equipment}:{interface}') if ifc_info: result['interface'] = json.loads(ifc_info.decode('utf-8')) @@ -211,30 +246,22 @@ def get_juniper_link_info(source_equipment: str, interface: str): else: result['interface']['bundle_members'] = [] - def _related_services(): - for related in related_interfaces(source_equipment, interface): - logger.debug(f'Related Interface: {related}') - rs = r.get(f'ims:interface_services:{ims_source_equipment}:' - f'{related.upper()}') - if rs: - for s in json.loads(rs.decode('utf-8')): - top_level_services.extend( - get_top_level_services(s['id'], r)) - yield { - 'name': s['name'], - 'status': s['status'], - 'circuit_type': s['circuit_type'], - 'project': s['project'] - } - - related_services = list(_related_services()) - if related_services: - top_level_services.extend(related_services) - if top_level_services: - result['related-services'] = top_level_services - - if not result['locations']: - result['locations'] = _locations_from_router(ims_source_equipment) + # use a dict to get rid of duplicates + rs_dict = {r['id']: r for r in get_related_services( + source_equipment, interface, r)} + result['related-services'] = list(rs_dict.values()) + + if_services = r.get(f'ims:interface_services:{ims_source_equipment}:' + f'{ims_interface}') + if if_services: + if_services = json.loads(if_services.decode('utf-8')) + result['locations'] = list(_location_from_services(if_services, r)) + + if not result.get('locations'): + result['locations'] = [ + build_locations( + _location_from_equipment(ims_source_equipment, r)) + ] result['locations'] = _remove_duplicates_from_list(result['locations']) result = json.dumps(result) @@ -371,24 +398,32 @@ def peer_info(address): info = info.decode('utf-8') info = json.loads(info) result['ix-public-peer-info'] = ix_peering_info(info) - result['locations'] += _location_from_equipment(info['router']) + result['locations'].append(build_locations( + _location_from_equipment(info['router'], r))) info = r.get(f'vpn_rr_peer:{address}') if info: info = info.decode('utf-8') info = json.loads(info) result['vpn-rr-peer-info'] = info - result['locations'] += _location_from_equipment(info['router']) + result['locations'].append(build_locations( + _location_from_equipment(info['router'], r))) interfaces = list(find_interfaces_and_services(address)) if interfaces: result['interfaces'] = interfaces for i in interfaces: for s in i['services']: - result['locations'] += \ - _location_from_equipment(s['equipment']) - result['locations'] += \ - _location_from_equipment(s['other_end_equipment']) + result['locations'].append( + build_locations( + _location_from_equipment(s['router'], r), + _location_from_equipment( + s['other_end_equipment'], r)) + ) + # result['locations'] += \ + # _location_from_equipment(s['equipment'], r) + # result['locations'] += \ + # _location_from_equipment(s['other_end_equipment'], r) result['locations'] = _remove_duplicates_from_list(result['locations']) result = json.dumps(result) @@ -431,10 +466,15 @@ def get_trap_metadata(source_equipment, interface, circuit_id): if top_level_services: result['related-services'] = top_level_services for s in result['services']: - result['locations'] += \ - _location_from_equipment(s['equipment']) - result['locations'] += \ - _location_from_equipment(s['other_end_equipment']) + result['locations'].append( + build_locations( + _location_from_equipment(s['router'], r), + _location_from_equipment(s['other_end_equipment'], r)) + ) + # result['locations'] += \ + # _location_from_equipment(s['equipment'], r) + # result['locations'] += \ + # _location_from_equipment(s['other_end_equipment'], r) gls = {tls['id']: { 'id': tls['id'], 'name': tls['name'], @@ -503,8 +543,8 @@ def get_fiberlink_trap_metadata(ne_name_str, object_name_str): x[0]['df_route_id'] == x[1]['df_route_id']] if matches: match = matches[0] - locations_a = _location_from_equipment(equipment_a) - locations_b = _location_from_equipment(equipment_b) + locations_a = _location_from_equipment(equipment_a, r) + locations_b = _location_from_equipment(equipment_b, r) if locations_a: loc_a = locations_a[0]['a'] else: @@ -520,10 +560,7 @@ def get_fiberlink_trap_metadata(ne_name_str, object_name_str): # removed result = { 'locations': [ - { - 'a': loc_a, - 'b': loc_b - } + build_locations(loc_a, loc_b) ], 'ends': { 'a': { -- GitLab