diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index e2e144cf2f04fa6f7de3210f4608d5f74a98a810..3bc270c7c37c9624a7f51ed48b7c021ee6439cd7 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -243,6 +243,49 @@ def get_juniper_link_info(source_equipment, interface): return Response(result, mimetype='application/json') +def _asn_group_info(redis, address): + """ + :param redis: a redis db connection + :param address: the remote peer address + :return: + """ + + try: + address = ipaddress.ip_address(address).exploded + except ValueError: + raise ClassifierProcessingError( + f'unable to parse {address} as an ip address') + + all_peerings = redis.get(f'juniper-peerings:remote:{address}') + if not all_peerings: + return None + + all_peerings = json.loads(all_peerings.decode('utf-8')) + all_asn = {p['remote-asn'] for p in all_peerings if 'remote-asn' in p} + if not all_asn: + return None + + peer_asn = all_asn.pop() + if all_asn: + logger.error( + f'found multiple asn''s for {address}, ' + f'using {peer_asn} and ignoring {all_asn}') + + peerings_this_asn = redis.get(f'juniper-peerings:peer-asn:{peer_asn}') + if not peerings_this_asn: + logger.error( + f'internal data corruption, no peerings found for asn {peer_asn}') + return None + + peerings_this_asn = json.loads(peerings_this_asn.decode('utf-8')) + return { + 'asn': peer_asn, + 'peers': [ + {'router': p['hostname'], 'address': p['address']} + for p in peerings_this_asn + ] + } + def _vpn_rr_peering_info(redis, address): """ :param redis: a redis db connection @@ -457,6 +500,10 @@ def peer_info(address): result['locations'] += _locations_from_router( vpn_rr_peering_info['router']) + asn_group_info = _asn_group_info(r, address) + if asn_group_info: + result['asn']= asn_group_info + interfaces = list(find_interfaces_and_services(address)) if interfaces: result['interfaces'] = interfaces