-
Robert Latta authoredRobert Latta authored
lg.py 3.38 KiB
import json
import logging
from flask import Blueprint, jsonify, Response, request
from inventory_provider.routes import common
from inventory_provider.routes.common import _ignore_cache_or_retrieve
logger = logging.getLogger(__name__)
routes = Blueprint("lg-query-routes", __name__)
ACCESS_PUBLIC = 'public'
ACCESS_INTERNAL = 'all'
LG_ROUTERS_SCHEMA = {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"pop-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"abbreviation": {"type": "string"},
"country": {"type": "string"},
"country code": {"type": "string"},
"city": {"type": "string"},
"longitude": {"type": "number"},
"latitude": {"type": "number"}
},
"required": [
"name",
"abbreviation",
"country",
"country code",
"city",
"longitude",
"latitude"
],
"additionalProperties": False
},
"router": {
"type": "object",
"properties": {
"equipment name": {"type": "string"},
"type": {
"type": "string",
"enum": ["INTERNAL", "CORE"]
},
"pop": {"$ref": "#/definitions/pop-info"}
},
"required": ["equipment name", "type", "pop"],
"additionalProperties": False
}
},
"type": "array",
"items": {"$ref": "#/definitions/router"}
}
@routes.after_request
def after_request(resp):
return common.after_request(resp)
@routes.route("/routers/<string:access>", methods=['GET', 'POST'])
@common.require_accepts_json
def routers(access):
"""
Handler for `/lg/routers/[access]` that returns a list of
router information for use by LG.
Endpoints `/lg/routers/public` and `/lg/routers/all`
are supported, and only publicly accessible routers
or all routers, respectively, are returned.
The response will be formatted according to the following schema:
.. asjson::
inventory_provider.routes.lg.LG_ROUTERS_SCHEMA
:param access: one of `public` or `all`
:return:
"""
if access not in {ACCESS_INTERNAL, ACCESS_PUBLIC}:
return Response(
response='unknown access level',
status=404,
mimetype='text/html')
redis = common.get_current_redis()
def _visible(router):
if access == ACCESS_INTERNAL:
return True
return router['type'] == 'CORE'
def _routers():
i = 0
for k in redis.scan_iter('ims:lg:*'):
rtr = redis.get(k.decode('utf-8')).decode('utf-8')
rtr = json.loads(rtr)
i += 1
if _visible(rtr):
yield rtr
cache_key = f'classifier-cache:ims-lg:{access}'
result = _ignore_cache_or_retrieve(request, cache_key, redis)
if not result:
result = list(_routers())
# cache this data for the next call
redis.set(cache_key, json.dumps(result).encode('utf-8'))
if not result:
return Response(
response=f'no routers found for access level {access}',
status=404,
mimetype="text/html")
return jsonify(result)