Skip to content
Snippets Groups Projects
Commit 39cf7005 authored by Erik Reid's avatar Erik Reid
Browse files

Finished feature more-ix-peer-info.

parents a567caef 509ce5e7
No related branches found
No related tags found
No related merge requests found
......@@ -379,7 +379,7 @@ Any non-empty responses are JSON formatted messages.
The response will be formatted according to the following syntax:
```json
{
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
......@@ -428,10 +428,20 @@ Any non-empty responses are JSON formatted messages.
"required": ["name", "description", "as"],
"additionalProperties": False
},
"ix-public-peer-group": {
"ix-public-peer-list": {
"type": "array",
"items": {"$ref": "#/definitions/ip-address"}
},
"ix-public-peer-info": {
"type": "object",
"properties": {
"peer": {"$ref": "#/definitions/ix-public-peer"},
"group": {"$ref": "#/definitions/ix-public-peer-list"},
"router": {"$ref": "#/definitions/ix-public-peer-list"}
},
"required": ["peer", "group", "router"],
"additionalProperties": False
},
"interface-info": {
"type": "object",
"properties": {
......@@ -462,9 +472,7 @@ Any non-empty responses are JSON formatted messages.
"type": "object",
"properties": {
"ix-public-peer-info": {"$ref": "#/definitions/ix-public-peer"},
"ix-public-peer-group": {
"$ref": "#/definitions/ix-public-peer-group"},
"ix-public-peer-info": {"$ref": "#/definitions/ix-public-peer-info"},
"vpn-rr-peer-info": {"$ref": "#/definitions/vpn-rr-peer"},
"interfaces": {
"type": "array",
......
......@@ -24,6 +24,6 @@
classifier metadata api
read snmp community string from netconf
derive active router list from junosspace
cache ix public & vpn rr peers
read most live info from netconf
precompute cached list of ix public & vpn rr peers
use external logging config file
added utilities for the test environment
......@@ -8,6 +8,31 @@ from inventory_provider.routes import common
routes = Blueprint("inventory-data-classifier-support-routes", __name__)
class ClassifierRequestError(Exception):
status_code = 500
def __init__(self):
super().__init__()
self.message = "Unclassified Internal Error"
class ClassifierProcessingError(ClassifierRequestError):
status_code = 422
def __init__(self, message, status_code=None):
super().__init__()
self.message = str(message)
if status_code is not None:
self.status_code = status_code
@routes.errorhandler(ClassifierRequestError)
def handle_request_error(error):
return Response(
response=error.message,
status=error.status_code)
@routes.route("/trap-metadata/<source_equipment>/<path:interface>",
methods=['GET', 'POST'])
@common.require_accepts_json
......@@ -46,29 +71,50 @@ def get_trap_metadata(source_equipment, interface):
return Response(result, mimetype="application/json")
def ix_peering_group(address, description):
def ix_peering_info(peer_info):
"""
TODO: this is probably the least efficient way of doing this
(if it's a problem, pre-compute these lists)
:param ix_public_peer_info: ix public peer info loaded for address
:param peer_info: an element from ix_public_peer:address
:return:
"""
result = {
'peer': peer_info,
'group': [],
'router': []
}
try:
address = ipaddress.ip_address(peer_info['name'])
except ValueError:
raise ClassifierProcessingError(
'unable to parse %r as an ip address' % address)
description = peer_info['description']
assert description is not None # sanity
protocol = type(address).__name__
keyword = description.split(' ')[0] # regex needed??? (e.g. tabs???)
r = common.get_redis()
for k in r.keys('ix_public_peer:*'):
peer = r.get(k.decode('utf-8')).decode('utf-8')
peer = json.loads(peer)
assert peer['description'] is not None # sanity: as above...
if not peer['description'].startswith(keyword):
other = r.get(k.decode('utf-8')).decode('utf-8')
other = json.loads(other)
if other['router'] == peer_info['router']:
result['router'].append(other['name'])
assert other['description'] is not None # sanity: as above...
if not other['description'].startswith(keyword):
continue
peer_address = ipaddress.ip_address(peer['name'])
peer_address = ipaddress.ip_address(other['name'])
if protocol == type(peer_address).__name__:
yield peer['name']
result['group'].append(other['name'])
return result
def find_interfaces(address):
......@@ -88,12 +134,19 @@ def find_interfaces(address):
yield info
def find_interfaces_and_services(address):
def find_interfaces_and_services(address_str):
"""
:param address: an ipaddress object
:param address_str: an ipaddress object
:return:
"""
try:
address = ipaddress.ip_address(address_str)
except ValueError:
raise ClassifierProcessingError(
'unable to parse %r as an ip address' % address_str)
r = common.get_redis()
for interface in find_interfaces(address):
......@@ -124,31 +177,20 @@ def peer_info(address):
if result:
result = result.decode('utf-8')
else:
try:
address_obj = ipaddress.ip_address(address)
except ValueError:
return Response(
response='unable to parse %r as an ip address' % address,
status=422,
mimetype="text/html")
result = {}
info = r.get('ix_public_peer:%s' % address)
if info:
info = info.decode('utf-8')
result['ix-public-peer-info'] = json.loads(info)
description = result['ix-public-peer-info']['description']
assert description is not None # sanity
result['ix-public-peer-group'] = list(
ix_peering_group(address_obj, description))
result['ix-public-peer-info'] = ix_peering_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)
interfaces = list(find_interfaces_and_services(address_obj))
interfaces = list(find_interfaces_and_services(address))
if interfaces:
result['interfaces'] = interfaces
......
......@@ -23,8 +23,7 @@ def test_trap_metadata(client_with_mocked_data):
VPN_RR_PEER_INFO_KEYS = {'vpn-rr-peer-info'}
IX_PUBLIC_PEER_INFO_KEYS = {
'ix-public-peer-info', 'ix-public-peer-group', 'interfaces'}
IX_PUBLIC_PEER_INFO_KEYS = {'ix-public-peer-info', 'interfaces'}
@pytest.mark.parametrize('peer_address,expected_response_keys', [
......@@ -85,10 +84,20 @@ def test_peer_info(
"required": ["name", "description", "as"],
"additionalProperties": False
},
"ix-public-peer-group": {
"ix-public-peer-list": {
"type": "array",
"items": {"$ref": "#/definitions/ip-address"}
},
"ix-public-peer-info": {
"type": "object",
"properties": {
"peer": {"$ref": "#/definitions/ix-public-peer"},
"group": {"$ref": "#/definitions/ix-public-peer-list"},
"router": {"$ref": "#/definitions/ix-public-peer-list"}
},
"required": ["peer", "group", "router"],
"additionalProperties": False
},
"interface-info": {
"type": "object",
"properties": {
......@@ -119,9 +128,8 @@ def test_peer_info(
"type": "object",
"properties": {
"ix-public-peer-info": {"$ref": "#/definitions/ix-public-peer"},
"ix-public-peer-group": {
"$ref": "#/definitions/ix-public-peer-group"},
"ix-public-peer-info": {
"$ref": "#/definitions/ix-public-peer-info"},
"vpn-rr-peer-info": {"$ref": "#/definitions/vpn-rr-peer"},
"interfaces": {
"type": "array",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment