From a96711562113de4161599fbadd8a5472cfea5ba8 Mon Sep 17 00:00:00 2001 From: Erik Reid <erik.reid@geant.org> Date: Thu, 13 Aug 2020 16:10:58 +0200 Subject: [PATCH] use load_json_docs for /data/interfaces, added router to response --- inventory_provider/routes/data.py | 44 ++++++++++++++++++++--------- test/per_router/test_data_routes.py | 3 +- test/test_general_data_routes.py | 39 +++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/inventory_provider/routes/data.py b/inventory_provider/routes/data.py index f5f780ce..f25bd80d 100644 --- a/inventory_provider/routes/data.py +++ b/inventory_provider/routes/data.py @@ -27,23 +27,41 @@ def routers(): return jsonify(result) +@routes.route("/interfaces", methods=['GET', 'POST']) @routes.route("/interfaces/<hostname>", methods=['GET', 'POST']) @common.require_accepts_json -def router_interfaces(hostname): - r = common.get_current_redis() - interfaces = [] - for k in r.keys('netconf-interfaces:%s:*' % hostname): - ifc = r.get(k.decode('utf-8')) - if ifc: - interfaces.append(json.loads(ifc.decode('utf-8'))) +def router_interfaces(hostname=None): - if not interfaces: - return Response( - response="no available interface info for '%s'" % hostname, - status=404, - mimetype="text/html") + cache_key = f'classifier-cache:netconf-interfaces:{hostname}' \ + if hostname else 'classifier-cache:netconf-interfaces:all' - return jsonify(interfaces) + r = common.get_current_redis() + result = r.get(cache_key) + if result: + result = result.decode('utf-8') + + else: + key_pattern = f'netconf-interfaces:{hostname}:*' \ + if hostname else 'netconf-interfaces:*' + config = current_app.config['INVENTORY_PROVIDER_CONFIG'] + + result = [] + for ifc in common.load_json_docs(config, key_pattern): + key_fields = ifc['key'].split(':') + ifc['value']['router'] = key_fields[1] + result.append(ifc['value']) + + if not result: + return Response( + response="no available interface info for '%s'" % hostname, + status=404, + mimetype="text/html") + + result = json.dumps(result) + # cache this data for the next call + r.set(cache_key, result.encode('utf-8')) + + return Response(result, mimetype="application/json") @routes.route("/pop/<equipment_name>", methods=['GET', 'POST']) diff --git a/test/per_router/test_data_routes.py b/test/per_router/test_data_routes.py index 063aa2a3..85fa9bae 100644 --- a/test/per_router/test_data_routes.py +++ b/test/per_router/test_data_routes.py @@ -18,6 +18,7 @@ def test_router_interfaces(router, client): "properties": { "name": {"type": "string"}, "description": {"type": "string"}, + "router": {"type": "string"}, "bundle": { "type": "array", "items": {"type": "string"} @@ -31,7 +32,7 @@ def test_router_interfaces(router, client): "items": {"type": "string"} } }, - "required": ["name", "description", "ipv4", "ipv6"], + "required": ["name", "description", "ipv4", "router", "ipv6"], "additionalProperties": False } } diff --git a/test/test_general_data_routes.py b/test/test_general_data_routes.py index fa8c385a..a618f8fb 100644 --- a/test/test_general_data_routes.py +++ b/test/test_general_data_routes.py @@ -75,3 +75,42 @@ def test_pop_not_found(client, mocker): headers=DEFAULT_REQUEST_HEADERS) assert rv.status_code == 404 + + +def test_router_interfaces_all(client): + + interfaces_list_schema = { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "description": {"type": "string"}, + "router": {"type": "string"}, + "bundle": { + "type": "array", + "items": {"type": "string"} + }, + "ipv4": { + "type": "array", + "items": {"type": "string"} + }, + "ipv6": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": ["name", "description", "ipv4", "router", "ipv6"], + "additionalProperties": False + } + } + + rv = client.post( + '/data/interfaces', + headers=DEFAULT_REQUEST_HEADERS) + + assert rv.status_code == 200 + response = json.loads(rv.data.decode("utf-8")) + jsonschema.validate(response, interfaces_list_schema) + assert response # at least shouldn't be empty -- GitLab