diff --git a/docs/source/protocol/index.rst b/docs/source/protocol/index.rst index 0ec3dbb58ae1dd95b59fc4093a1ae47b4e794309..370ec063c4bf9dc13791577bc6a37c8bc81070ab 100644 --- a/docs/source/protocol/index.rst +++ b/docs/source/protocol/index.rst @@ -29,9 +29,10 @@ API modules :caption: Contents: classifier - poller lg data jobs msr - lnetd \ No newline at end of file + lnetd + +.. automodule:: inventory_provider.routes.poller diff --git a/docs/source/protocol/poller.rst b/docs/source/protocol/poller.rst deleted file mode 100644 index 7b9040ad8e720f1e4f431652df76642a25520a65..0000000000000000000000000000000000000000 --- a/docs/source/protocol/poller.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. poller endpoint docs - - -BRIAN support Endpoints -========================= - -These endpoints are intended for use by BRIAN. - -.. contents:: :local: - -/poller/interfaces</hostname> ---------------------------------- - -.. autofunction:: inventory_provider.routes.poller.interfaces - - -/poller/speeds</hostname> ---------------------------------- - -.. autofunction:: inventory_provider.routes.poller.interface_speeds - - -/poller/eumetsat-multicast ---------------------------------- - -.. autofunction:: inventory_provider.routes.poller.eumetsat_multicast diff --git a/inventory_provider/routes/poller.py b/inventory_provider/routes/poller.py index 900fd11c08c439bab616242296fe4360b2c6f660..97c4fb3ba0938e6ed69c0a85a9b425d9cfc92307 100644 --- a/inventory_provider/routes/poller.py +++ b/inventory_provider/routes/poller.py @@ -1,8 +1,40 @@ +""" +BRIAN support Endpoints +========================= + +These endpoints are intended for use by BRIAN. + +.. contents:: :local: + +/poller/interfaces</hostname> +--------------------------------- + +.. autofunction:: inventory_provider.routes.poller.interfaces + + +/poller/speeds</hostname> +--------------------------------- + +.. autofunction:: inventory_provider.routes.poller.interface_speeds + + +/poller/eumetsat-multicast +--------------------------------- + +.. autofunction:: inventory_provider.routes.poller.eumetsat_multicast + + +/poller/gws/direct +--------------------------------- + +.. autofunction:: inventory_provider.routes.poller.gws_direct + +""" import json import logging import re -from flask import Blueprint, Response, current_app, request +from flask import Blueprint, Response, current_app, request, jsonify from lxml import etree from inventory_provider import juniper @@ -117,6 +149,60 @@ MULTICAST_SUBSCRIPTION_LIST_SCHEMA = { 'items': {'$ref': '#/definitions/subscription'} } +GWS_DIRECT_DATA_SCHEMA = { + '$schema': 'http://json-schema.org/draft-07/schema#', + + 'definitions': { + 'snmp-counter': { + 'type': 'object', + 'properties': { + 'hostname': {'type': 'string'}, + 'community': {'type': 'string'}, + 'oid': { + 'type': 'string', + 'pattern': r'^(\d+\.)*\d+$' + } + }, + 'required': ['hostname', 'community', 'oid'], + 'additionalProperties': False + }, + 'snmp-counter-list': { + 'type': 'array', + 'items': {'$ref': '#/definitions/snmp-counter'}, + 'minItems': 1 + }, + 'isp-counters': { + 'type': 'object', + 'properties': { + 'traffic_in': {'$ref': '#/definitions/snmp-counter-list'}, + 'traffic_out': {'$ref': '#/definitions/snmp-counter-list'}, + 'discards_in': {'$ref': '#/definitions/snmp-counter-list'}, + 'discards_out': {'$ref': '#/definitions/snmp-counter-list'}, + 'errors_in': {'$ref': '#/definitions/snmp-counter-list'}, + 'errors_out': {'$ref': '#/definitions/snmp-counter-list'} + }, + 'required': ['traffic_in', 'traffic_out'], + 'additionalProperties': False + }, + 'nren-isp-direct-counters': { + 'type': 'object', + 'properties': { + 'nren': {'type': 'string'}, + 'isp': { + 'type': 'string', + 'enum': ['Cogent', 'Telia', 'Century Link'] + }, + 'counters': {'$ref': '#/definitions/isp-counters'}, + }, + 'required': ['nren', 'isp', 'counters'], + 'additionalProperties': False + } + }, + + 'type': 'array', + 'items': {'$ref': '#/definitions/nren-isp-direct-counters'} +} + @routes.after_request def after_request(resp): @@ -522,3 +608,367 @@ def eumetsat_multicast(hostname=None): r.set(cache_key, result.encode('utf-8')) return Response(result, mimetype="application/json") + + +@routes.route("/gws/direct", methods=['GET', 'POST']) +@common.require_accepts_json +def gws_direct(): + """ + Handler for `/poller/gws/direct` which returns required for polling + customer equipment counters for ISP connetions. + + The response is a list of nren/isp/counter structures that must be + polled. + + .. asjson:: + inventory_provider.routes.poller.GWS_DIRECT_DATA_SCHEMA + + This method returns essentially hard-coded data, + based on the information in POL1-422. + + TODO: this hard-coded data should be in the config file + + :return: + """ + data = [ + { + "nren": "ARNES", + "isp": "Cogent", + "counters": { + "discards_in": [ + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.2.2.1.13.533" + } + ], + "discards_out": [ + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.2.2.1.19.533" + } + ], + "errors_in": [ + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.2.2.1.14.533" + } + ], + "errors_out": [ + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.2.2.1.20.533" + } + ], + "traffic_in": [ + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.6.531" + }, + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.6.525" + }, + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.6.553" + }, + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.6.563" + } + ], + "traffic_out": [ + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.10.531" + }, + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.10.525" + }, + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.10.553" + }, + { + "hostname": "88.200.0.63", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.10.563" + } + ] + } + }, + { + "nren": "ARNES", + "isp": "Telia", + "counters": { + "traffic_in": [ + { + "hostname": "62.40.124.6", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.6.611" + }, + { + "hostname": "62.40.124.6", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.6.589" + } + ], + "traffic_out": [ + { + "hostname": "62.40.124.6", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.10.611" + }, + { + "hostname": "62.40.124.6", + "community": "gn2nocT3st", + "oid": "1.3.6.1.2.1.31.1.1.1.10.589" + } + ] + } + }, + { + "nren": "CARNET", + "isp": "Cogent", + "counters": { + "traffic_in": [ + { + "hostname": "62.40.124.10", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.35" + } + ], + "traffic_out": [ + { + "hostname": "62.40.124.10", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.35" + } + ] + } + }, + { + "nren": "CARNET", + "isp": "Telia", + "counters": { + "traffic_in": [ + { + "hostname": "62.40.125.150", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.48" + } + ], + "traffic_out": [ + { + "hostname": "62.40.125.150", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.48" + } + ] + } + }, + { + "nren": "KIFU", + "isp": "Cogent", + "counters": { + "traffic_in": [ + { + "hostname": "195.111.97.108", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.155" + } + ], + "traffic_out": [ + { + "hostname": "195.111.97.108", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.155" + } + ] + } + }, + { + "nren": "KIFU", + "isp": "Telia", + "counters": { + "traffic_in": [ + { + "hostname": "195.111.97.108", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.148" + } + ], + "traffic_out": [ + { + "hostname": "195.111.97.108", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.148" + } + ] + } + }, + { + "nren": "RedIRIS", + "isp": "Telia", + "counters": { + "traffic_in": [ + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.1487" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.1488" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.1489" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.760" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.796" + } + ], + "traffic_out": [ + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.1487" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.1488" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.1489" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.760" + }, + { + "hostname": "130.206.206.250", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.796" + } + ] + } + }, + { + "nren": "RoEduNet", + "isp": "Cogent", + "counters": { + "traffic_in": [ + { + "hostname": "149.6.50.10", + "community": "dante", + "oid": "1.3.6.1.2.1.31.1.1.1.6.531" + } + ], + "traffic_out": [ + { + "hostname": "149.6.50.10", + "community": "dante", + "oid": "1.3.6.1.2.1.31.1.1.1.10.531" + } + ] + } + }, + { + "nren": "RoEduNet", + "isp": "Century Link", + "counters": { + "traffic_in": [ + { + "hostname": "212.162.45.194", + "community": "dante", + "oid": "1.3.6.1.2.1.31.1.1.1.6.9" + } + ], + "traffic_out": [ + { + "hostname": "212.162.45.194", + "community": "dante", + "oid": "1.3.6.1.2.1.31.1.1.1.10.9" + } + ] + } + }, + { + "nren": "EENet", + "isp": "Telia", + "counters": { + "traffic_in": [ + { + "hostname": "193.40.133.2", + "community": "geant-mon-telia", + "oid": "1.3.6.1.2.1.31.1.1.1.6.263" + } + ], + "traffic_out": [ + { + "hostname": "193.40.133.2", + "community": "geant-mon-telia", + "oid": "1.3.6.1.2.1.31.1.1.1.10.263" + } + ] + } + }, + { + "nren": "PSNC", + "isp": "Century Link", + "counters": { + "traffic_in": [ + { + "hostname": "212.191.126.6", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.675" + }, + { + "hostname": "212.191.126.7", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.6.677" + } + ], + "traffic_out": [ + { + "hostname": "212.191.126.6", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.675" + }, + { + "hostname": "212.191.126.7", + "community": "atlas1453", + "oid": "1.3.6.1.2.1.31.1.1.1.10.677" + } + ] + } + } + ] + + return jsonify(data) diff --git a/test/test_general_poller_routes.py b/test/test_general_poller_routes.py index 756446610cfcf062031dab534a0a84900ddb8563..73b6d81c0389a2cc8997b7810ee4b620e3fe08ae 100644 --- a/test/test_general_poller_routes.py +++ b/test/test_general_poller_routes.py @@ -50,3 +50,16 @@ def test_eumetsat_multicast(mocker, client): jsonschema.validate( response_data, poller.MULTICAST_SUBSCRIPTION_LIST_SCHEMA) assert response_data, "the subscription list shouldn't be empty" + + +def test_gws_direct(client): + + rv = client.get( + '/poller/gws/direct', + headers=DEFAULT_REQUEST_HEADERS) + assert rv.status_code == 200 + assert rv.is_json + response_data = json.loads(rv.data.decode('utf-8')) + jsonschema.validate( + response_data, poller.GWS_DIRECT_DATA_SCHEMA) + assert response_data, "the subscription list shouldn't be empty"