lg.py 3.26 KiB
import json
from flask import Blueprint, jsonify, Response, current_app
from inventory_provider.routes import common
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')
def _visible(router):
if access == ACCESS_INTERNAL:
return True
return router['type'] == 'CORE'
def _routers():
for doc in common.load_json_docs(
config_params=current_app.config['INVENTORY_PROVIDER_CONFIG'],
key_pattern='opsdb:lg:*'):
yield doc['value']
redis = common.get_current_redis()
cache_key = f'classifier-cache:lg:{access}'
result = redis.get(cache_key)
if result:
result = json.loads(result.decode('utf-8'))
else:
result = list(filter(_visible, _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)