Skip to content
Snippets Groups Projects
Commit f03319b6 authored by Robert Latta's avatar Robert Latta
Browse files

added fiberlink classification; refactored location and tls functionality#

parent a34dbc43
No related branches found
No related tags found
No related merge requests found
import ipaddress
import itertools
import json
import logging
import re
......@@ -12,9 +13,6 @@ routes = Blueprint("ims-inventory-data-classifier-support-routes", __name__)
logger = logging.getLogger(__name__)
def _LOCATION(equipment, name, abbreviation):
return {
'equipment': equipment,
......@@ -54,24 +52,30 @@ def _locations_from_router(router_name):
}]
def _location_from_service_dict(s):
location = {
'a': _LOCATION(
equipment=s['equipment'],
name=s['pop_name'],
abbreviation=s['pop_abbreviation'])
}
if all(s[n] for n in (
'other_end_equipment',
'other_end_pop_name',
'other_end_pop_abbreviation')):
location['b'] = _LOCATION(
equipment=s['other_end_equipment'],
name=s['other_end_pop_name'],
abbreviation=s['other_end_pop_abbreviation'])
return location
# 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_service_dict(s):
# location = {
# 'a': _LOCATION(
# equipment=s['equipment'],
# name=s['pop_name'],
# abbreviation=s['pop_abbreviation'])
# }
#
# if all(s[n] for n in (
# 'other_end_equipment',
# 'other_end_pop_name',
# 'other_end_pop_abbreviation')):
# location['b'] = _LOCATION(
# equipment=s['other_end_equipment'],
# name=s['other_end_pop_name'],
# abbreviation=s['other_end_pop_abbreviation'])
#
# return location
class ClassifierRequestError(Exception):
......@@ -115,23 +119,28 @@ def related_interfaces(hostname, interface):
def get_top_level_services(circuit_id, r):
tls = []
results = r.get("ims:services:children:{}".format(circuit_id))
tls = {}
key = "ims:circuit_hierarchy:{}".format(circuit_id)
results = r.get(key)
if results:
results = json.loads(results.decode('utf-8'))
# should only ever be one, may refactor this
for c in results:
temp_parents = \
get_top_level_services(c['parent_circuit_id'], r)
if not temp_parents:
tls.append(
{'name': c['parent_circuit'],
'status': c['parent_circuit_status'],
'circuit_type': c['parent_circuit_type'].lower(),
'project': c['parent_project']
})
tls.extend(temp_parents)
return tls
if c['sub-circuits']:
for sub in c['sub-circuits']:
temp_parents = \
get_top_level_services(sub, r)
tls.update({t['id']: t for t in temp_parents})
else:
tls[c['id']] = {
'id': c['id'],
'name': c['name'],
'status': c['status'],
'circuit_type': c['product'].lower(),
'project': c['project']
}
return list(tls.values())
def get_ims_equipment_name(equipment_name: str) -> str:
......@@ -176,8 +185,10 @@ def get_juniper_link_info(source_equipment: str, interface: str):
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_service_dict(s) for s in result['services']]
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:
......@@ -342,7 +353,7 @@ def peer_info(address):
r = common.get_current_redis()
cache_key = f'classifier-cache:peer:{address}'
cache_key = f'ims-classifier-cache:peer:{address}'
# result = r.get(cache_key)
result = False
......@@ -360,21 +371,24 @@ def peer_info(address):
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'])
result['locations'] += _location_from_equipment(info['router'])
info = r.get('vpn_rr_peer:%s' % 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'])
result['locations'] += _location_from_equipment(info['router'])
interfaces = list(find_interfaces_and_services(address))
if interfaces:
result['interfaces'] = interfaces
for i in interfaces:
result['locations'] += [
_location_from_service_dict(s) for s in i['services']]
for s in i['services']:
result['locations'] += \
_location_from_equipment(s['equipment'])
result['locations'] += \
_location_from_equipment(s['other_end_equipment'])
result['locations'] = _remove_duplicates_from_list(result['locations'])
result = json.dumps(result)
......@@ -382,3 +396,97 @@ def peer_info(address):
r.set(cache_key, result.encode('utf-8'))
return Response(result, mimetype="application/json")
@routes.route("/infinera-fiberlink-info/<ne_name_str>/<object_name_str>",
methods=['GET', 'POST'])
@common.require_accepts_json
def get_fiberlink_trap_metadata(ne_name_str, object_name_str):
objects = object_name_str.split('_')
shelves = [x.split('-')[0] for x in objects]
p = r'([a-zA-Z\d]+?-(OLA|DTNX)\d+(-\d)?)'
matches = re.findall(p, ne_name_str)
if len(matches) != 2 or len(shelves) != 2:
raise ClassifierProcessingError(
f'unable to parse {ne_name_str} {object_name_str } '
'into two elements')
r = common.get_current_redis()
# double check that we only need to check the two nodes and not the objects
cache_key = f'ims-classifier-cache:fiberlink:{ne_name_str}:{object_name_str}'
# result = r.get(cache_key)
result = False
if result:
result = result.decode('utf-8')
else:
equipment_a = matches[0][0]
equipment_b = matches[1][0]
nes_a = f'{equipment_a}-{shelves[0]}'
nes_b = f'{equipment_b}-{shelves[1]}'
result = []
df_a = r.get(f'ims:ne_fibre_spans:{nes_a}')
df_b = r.get(f'ims:ne_fibre_spans:{nes_b}')
if df_a and df_b:
a = json.loads(df_a.decode('utf-8'))
b = json.loads(df_b.decode('utf-8'))
matches = [x for x in itertools.product(a, b) if
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)
if locations_a:
loc_a = locations_a[0]['a']
else:
loc_a = _LOCATION(equipment_a, '', '')
if locations_b:
loc_b = locations_b[0]['a']
else:
loc_b = _LOCATION(equipment_b, '', '')
# added locations in preparation for refactoring to be in-line
# with other location data. Once Dashboard has been altered to
# use this for fiberlink alarms the 'ends' attribute can be
# removed
result = {
'locations': [
{
'a': loc_a,
'b': loc_b
}
],
'ends': {
'a': {
'pop': loc_a['name'],
'pop_abbreviation': loc_a['abbreviation'],
'equipment': loc_a['equipment']
},
'b': {
'pop': loc_b['name'],
'pop_abbreviation': loc_b['abbreviation'],
'equipment': loc_b['equipment']
},
},
'df_route': {
'id': match[0]['df_route_id'],
'name': match[0]['df_route'],
'status': match[0]['df_status'],
},
'related-services':
get_top_level_services(match[0]['df_route_id'], r)
}
result = json.dumps(result)
r.set(cache_key, result)
if not result:
return Response(
response="no available info for "
f"{ne_name_str} {object_name_str}",
status=404,
mimetype="text/html")
return Response(result, mimetype="application/json")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment