diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index 5f984cec14036cbb2a7ec13d464c3388a6d8bc56..9f8f6915cb2fcf5141757131d2a8d0867c416724 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -1,6 +1,6 @@ import json -from flask import Blueprint, Response +from flask import Blueprint, Response, jsonify from inventory_provider.routes import common @@ -43,3 +43,29 @@ def get_trap_metadata(source_equipment, interface): r.set(cache_key, result.encode('utf-8')) return Response(result, mimetype="application/json") + +@routes.route("/peer-info/<address>", methods=['GET', 'POST']) +@common.require_accepts_json +def peer_info(address): + + r = common.get_redis() + + result = {} + + info = r.get('ix_public_peer:%s' % address) + if info: + info = info.decode('utf-8') + result['ix-public-peer-info'] = json.loads(info) + + info = r.get('vpn_rr_peer:%s' % address) + if info: + info = info.decode('utf-8') + result['vpn-rr-peer-info'] = json.loads(info) + + if not result: + return Response( + response='no peering info found for %s' % address, + status=404, + mimetype="text/html") + + return jsonify(result) diff --git a/test/test_classifier_routes.py b/test/test_classifier_routes.py index 6b68221d42e1805c373990ea12cbdc8950bb57db..d2a16e04bf1b9dad9e5f71f1c9966011c0de82ee 100644 --- a/test/test_classifier_routes.py +++ b/test/test_classifier_routes.py @@ -1,5 +1,6 @@ import json import jsonschema +import pytest DEFAULT_REQUEST_HEADERS = { "Content-type": "application/json", @@ -19,3 +20,78 @@ def test_trap_metadata(client_with_mocked_data): assert rv.is_json response_data = json.loads(rv.data.decode('utf-8')) jsonschema.validate(response_data, response_schema) + + +@pytest.mark.parametrize("peer_address,peer_type", [ + ('109.105.110.54', 'vpn-rr-peer-info'), + ('2001:07f8:001c:024a:0000:0000:316e:0001', 'ix-public-peer-info'), + ('2001:07f8:000b:0100:01d1:a5d1:0310:0029', 'ix-public-peer-info'), + ('195.66.224.238', 'ix-public-peer-info'), +] +) +def test_peer_info(client_with_mocked_data, peer_address, peer_type): + response_schema = { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + + "definitions": { + "ip-address": { + "type": "string", + "oneOf": [ + {"pattern": r'^(\d+\.){3}\d+$'}, + {"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'} + ] + }, + "vpn-rr-peer": { + "type": "object", + "properties": { + "name": {"$ref": "#/definitions/ip-address"}, + "description": {"type": "string"}, + "peer-as": {"type": "integer"}, + "router": {"type": "string"} + }, + "required": ["name", "description"], + "additionalProperties": False + }, + + "ix-public-peer": { + "type": "object", + "properties": { + "name": {"$ref": "#/definitions/ip-address"}, + "description": {"type": "string"}, + "router": {"type": "string"}, + "as": { + "type": "object", + "properties": { + "local": {"type": "integer"}, + "peer": {"type": "integer"}, + }, + "required": ["local", "peer"], + "additionalProperties": False + } + }, + "required": ["name", "description", "as"], + "additionalProperties": False + } + }, + + "type": "object", + "properties": { + "ix-public-peer-info": {"$ref": "#/definitions/ix-public-peer"}, + "vpn-rr-peer-info": {"$ref": "#/definitions/vpn-rr-peer"} + }, + "additionalProperties": False + } + + rv = client_with_mocked_data.get( + '/classifier/peer-info/%s' % peer_address, + 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, response_schema) + + assert len(response_data) == 1, \ + "peer should be only vpn-rr or ix-public, not both" + + assert peer_type in response_data