diff --git a/inventory_provider/routes/poller.py b/inventory_provider/routes/poller.py index f606759e3d0bd09128270ba756c27946a8683b63..f7ef02d5d544e8895594598bbddb8b8e9dbc7b72 100644 --- a/inventory_provider/routes/poller.py +++ b/inventory_provider/routes/poller.py @@ -59,6 +59,26 @@ INTERFACE_LIST_SCHEMA = { 'items': {'$ref': '#/definitions/interface'} } +INTERFACE_SPEED_LIST_SCHEMA = { + '$schema': 'http://json-schema.org/draft-07/schema#', + + 'definitions': { + 'interface': { + 'type': 'object', + 'properties': { + 'router': {'type': 'string'}, + 'name': {'type': 'string'}, + 'speed': {'type': 'integer'} + }, + 'required': ['router', 'name', 'speed'], + 'additionalProperties': False + }, + }, + + 'type': 'array', + 'items': {'$ref': '#/definitions/interface'} +} + @routes.after_request def after_request(resp): @@ -228,3 +248,59 @@ def interfaces(hostname=None): r.set(cache_key, result.encode('utf-8')) return Response(result, mimetype="application/json") + + +@routes.route("/speeds", methods=['GET', 'POST']) +@routes.route('/speeds/<hostname>', methods=['GET', 'POST']) +@common.require_accepts_json +def interface_speeds(hostname=None): + """ + Handler for `/poller/speeds` and + `/poller/speeds/<hostname>` + which returns information for either all interfaces + or those on the requested hostname. + + The response is a list of speed information for all + known interfaces. + + .. asjson:: + inventory_provider.routes.poller.INTERFACE_SPEED_LIST_SCHEMA + + :param hostname: optional, if present should be a router hostname + :return: + """ + + cache_key = f'classifier-cache:poller-interface-speeds:{hostname}' \ + if hostname else 'classifier-cache:poller-interface-speeds:all' + + r = common.get_current_redis() + + result = r.get(cache_key) + if result: + result = result.decode('utf-8') + else: + + def _speed(ifc): + # TODO + return -1 + + def _result_ifc(ifc): + return { + 'router': ifc['router'], + 'name': ifc['name'], + 'speed': _speed(ifc) + } + + result = list(map(_result_ifc, _load_interfaces(hostname))) + + if not result: + return Response( + response='no interfaces found', + 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") diff --git a/test/per_router/test_poller_routes.py b/test/per_router/test_poller_routes.py index d7351c09dd899ab785cf73568a2039c8c96a0d10..bc304e5b7aca1fca9134dfceeba2c65e4de8d770 100644 --- a/test/per_router/test_poller_routes.py +++ b/test/per_router/test_poller_routes.py @@ -1,6 +1,7 @@ import json import jsonschema -from inventory_provider.routes.poller import INTERFACE_LIST_SCHEMA +from inventory_provider.routes.poller \ + import INTERFACE_LIST_SCHEMA, INTERFACE_SPEED_LIST_SCHEMA DEFAULT_REQUEST_HEADERS = { "Content-type": "application/json", @@ -19,3 +20,16 @@ def test_router_interfaces(router, client): assert response # at least shouldn't be empty response_routers = {ifc['router'] for ifc in response} assert response_routers == {router} + + +def test_router_interface_speeds(router, client): + rv = client.post( + f'/poller/speeds/{router}', + headers=DEFAULT_REQUEST_HEADERS) + + assert rv.status_code == 200 + response = json.loads(rv.data.decode("utf-8")) + jsonschema.validate(response, INTERFACE_SPEED_LIST_SCHEMA) + assert response # at least shouldn't be empty + response_routers = {ifc['router'] for ifc in response} + assert response_routers == {router}