Skip to content
Snippets Groups Projects
Commit 43680e1e authored by Erik Reid's avatar Erik Reid
Browse files

use new redis schema to construct peer-info rsp

parent b62914d1
Branches
Tags
No related merge requests found
......@@ -243,46 +243,129 @@ def get_juniper_link_info(source_equipment, interface):
return Response(result, mimetype='application/json')
def ix_peering_info(peer_info):
def _vpn_rr_peering_info(redis, address):
"""
TODO: this is probably the least efficient way of doing this
(if it's a problem, pre-compute these lists)
:param peer_info: an element from ix_public_peer:address
:param redis: a redis db connection
:param address: the remote peer address
:return:
"""
def _is_rr(peering_info):
if peering_info.get('logical-system', '') != 'VRR':
return False
group = peering_info.get('group', '')
if group not in ('VPN-RR', 'VPN-RR-INTERNAL'):
return False
if 'description' not in peering_info:
logger.error('internal data error, looks like vpn rr peering'
f'but description is missing: {peering_info}')
return False
return True
result = {
'peer': peer_info,
'group': [],
'router': []
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'))
rr_peerings = list(filter(_is_rr, all_peerings))
if not rr_peerings:
return None
if len(rr_peerings) > 1:
logger.warning(
f'using the first of multiple vpn rr peer matches: {rr_peerings}')
return_value = {
'name': address,
'description': rr_peerings[0]['description'],
'router': rr_peerings[0]['hostname']
}
if 'remote-asn' in rr_peerings[0]:
return_value['peer-as'] = rr_peerings[0]['remote-asn']
return return_value
def _ix_peering_info(redis, address):
"""
:param redis: a redis db connection
:param address: the remote peer address
:return:
"""
def _is_ix(peering_info):
if peering_info.get('instance', '') != 'IAS':
return False
if not peering_info.get('group', '').startswith('GEANT-IX'):
return False
expected_keys = ('description', 'local-asn', 'remote-asn')
if any(peering_info.get(x, None) is None for x in expected_keys):
logger.error('internal data error, looks like ix peering but'
f'some expected keys are missing: {peering_info}')
return False
return True
try:
address = ipaddress.ip_address(peer_info['name'])
address = ipaddress.ip_address(address).exploded
except ValueError:
raise ClassifierProcessingError(
'unable to parse %r as an ip address' % address)
description = peer_info['description']
assert description is not None # sanity
f'unable to parse {address} as an ip address')
keyword = description.split(' ')[0] # regex needed??? (e.g. tabs???)
all_peerings = redis.get(f'juniper-peerings:remote:{address}')
if not all_peerings:
return None
all_peerings = json.loads(all_peerings.decode('utf-8'))
ix_peerings = list(filter(_is_ix, all_peerings))
if not ix_peerings:
return None
if len(ix_peerings) > 1:
logger.warning(
f'using the first of multiple ix peer matches: {ix_peerings}')
peer_info = {
'name': address,
'description': ix_peerings[0]['description'],
'as': {
'local': ix_peerings[0]['local-asn'],
'peer': ix_peerings[0]['remote-asn']
},
'router': ix_peerings[0]['hostname']
}
for doc in common.load_json_docs(
config_params=current_app.config['INVENTORY_PROVIDER_CONFIG'],
key_pattern='ix_public_peer:*',
num_threads=10):
return_value = {
'peer': peer_info,
'group': [],
'router': []
}
other = doc['value']
if other['router'] == peer_info['router']:
result['router'].append(other['name'])
# load the other peers in the same group
# regex needed??? (e.g. tabs???)
peering_group_name = peer_info['description'].split(' ')[0]
peering_group = redis.get(
f'juniper-peerings:ix-groups:{peering_group_name}')
if peering_group:
peering_group = peering_group.decode('utf-8')
return_value['group'] = sorted(json.loads(peering_group))
assert other['description'] is not None # sanity: as above...
if other['description'].startswith(keyword):
result['group'].append(other['name'])
# load the other ix peers from the same router
router_peerings = redis.get(
f'juniper-peerings:hosts:{peer_info["router"]}')
router_peerings = json.loads(router_peerings.decode('utf-8'))
router_ix_peers = list(filter(_is_ix, router_peerings))
if router_ix_peers:
addresses = {p['address'] for p in router_ix_peers}
return_value['router'] = sorted(list(addresses))
return result
return return_value
def find_interfaces(address):
......@@ -362,19 +445,17 @@ def peer_info(address):
'locations': []
}
info = r.get(f'ix_public_peer:{address}')
if info:
info = info.decode('utf-8')
info = json.loads(info)
result['ix-public-peer-info'] = ix_peering_info(info)
result['locations'] += _locations_from_router(info['router'])
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'] += _locations_from_router(info['router'])
ix_peering_info = _ix_peering_info(r, address)
if ix_peering_info:
result['ix-public-peer-info'] = ix_peering_info
result['locations'] += _locations_from_router(
ix_peering_info['router'])
vpn_rr_peering_info = _vpn_rr_peering_info(r, address)
if vpn_rr_peering_info:
result['vpn-rr-peer-info'] = vpn_rr_peering_info
result['locations'] += _locations_from_router(
vpn_rr_peering_info['router'])
interfaces = list(find_interfaces_and_services(address))
if interfaces:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment