-
Mohammad Torkashvand authoredMohammad Torkashvand authored
neteng.py 3.58 KiB
"""
Neteng Support Endpoints
=========================
These endpoints are intended for use by neteng tools.
.. contents:: :local:
/neteng/location/equipment-name
---------------------------------
.. autofunction:: inventory_provider.routes.neteng.get_location
/neteng/pops
---------------------------------
.. autofunction:: inventory_provider.routes.neteng.get_pop_names
/neteng/pop/name
---------------------------------
.. autofunction:: inventory_provider.routes.neteng.get_pop_location
"""
import json
import logging
import re
import threading
from flask import Blueprint, Response, jsonify
from inventory_provider.routes import common
routes = Blueprint('neteng-query-routes', __name__)
logger = logging.getLogger(__name__)
_subnet_lookup_semaphore = threading.Semaphore()
STRING_LIST_SCHEMA = {
'$schema': 'https://json-schema.org/draft-07/schema#',
'type': 'array',
'items': {'type': 'string'}
}
@routes.after_request
def after_request(resp):
return common.after_request(resp)
@routes.route('/location/<equipment>', methods=['GET'])
@common.require_accepts_json
def get_location(equipment):
"""
Handler for `/neteng/location/<equipment-name>`
This method will return pop location information for the IMS node
with name = `equipment-name`.
404 is returned if the IMS node name is not known.
Otherwise the return value will be formatted as:
.. asjson::
inventory_provider.db.ims_data.NODE_LOCATION_SCHEMA
:return: as above
"""
r = common.get_current_redis()
value = r.get(f'ims:location:{equipment}')
if not value:
return Response(
response=f'no location information available for "{equipment}"',
status=404,
mimetype='text/html')
value = json.loads(value.decode('utf-8'))
if not value:
return Response(
response=f'unexpected empty cached data for "{equipment}"',
status=500,
mimetype='text/html')
return jsonify(value[0])
@routes.route('/pops', methods=['GET'])
@common.require_accepts_json
def get_pop_names():
"""
Handler for `/neteng/pops`
This method will return a list of defined pop
abbreviations. Elements from this list can be used
with `/neteng/pop`.
.. asjson::
inventory_provider.routes.neteng.STRING_LIST_SCHEMA
:return: as above
"""
def _pops():
r = common.get_current_redis()
for k in r.scan_iter('ims:site:*', count=1000):
k = k.decode('utf-8')
m = re.match('^ims:site:(.+)$', k)
yield m.group(1)
return jsonify(sorted(list(_pops())))
@routes.route('/pop/<abbreviation>', methods=['GET'])
@common.require_accepts_json
def get_pop_location(abbreviation):
"""
Handler for `/neteng/pop/<name>`
This method will return location information for the POP
with abbreviation = `abbreviation` in IMS.
404 is returned if the POP name is not known.
Otherwise the return value will be formatted as:
.. asjson::
inventory_provider.db.ims_data.POP_LOCATION_SCHEMA
:return: as above
"""
r = common.get_current_redis()
value = r.get(f'ims:site:{abbreviation}')
if not value:
return Response(
response=f'no location information available for "{abbreviation}"',
status=404,
mimetype='text/html')
value = json.loads(value.decode('utf-8'))
if not value:
return Response(
response=f'unexpected empty cached data for "{abbreviation}"',
status=500,
mimetype='text/html')
return jsonify(value)