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

added group peering list api

parent e184a1c5
Branches
Tags
No related merge requests found
...@@ -39,7 +39,7 @@ ACCESS_SERVICES_LIST_SCHEMA = { ...@@ -39,7 +39,7 @@ ACCESS_SERVICES_LIST_SCHEMA = {
} }
LOGICAL_SYSTEM_PEERING_LIST_SCHEMA = { PEERING_LIST_SCHEMA = {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"definitions": { "definitions": {
"peering-instance": { "peering-instance": {
...@@ -50,13 +50,16 @@ LOGICAL_SYSTEM_PEERING_LIST_SCHEMA = { ...@@ -50,13 +50,16 @@ LOGICAL_SYSTEM_PEERING_LIST_SCHEMA = {
"logical-system": {"type": "string"}, "logical-system": {"type": "string"},
"group": {"type": "string"}, "group": {"type": "string"},
"hostname": {"type": "string"}, "hostname": {"type": "string"},
"remote-asn": {"type": "integer"} "remote-asn": {"type": "integer"},
"local-asn": {"type": "integer"},
"instance": {"type": "string"}
}, },
# only vrr peerings have remote-asn # only vrr peerings have remote-asn
# only group peerings have local-asn or instance
# not all group peerings have 'description'
# and only vrr or vpn-proxy peerings are within a logical system
"required": [ "required": [
"address", "address",
"description",
"logical-system",
"group", "group",
"hostname"], "hostname"],
"additionalProperties": False "additionalProperties": False
...@@ -114,30 +117,32 @@ def access_services(): ...@@ -114,30 +117,32 @@ def access_services():
return jsonify(result) return jsonify(result)
@routes.route("/logical-system-peerings", methods=['GET', 'POST']) def _handle_peering_group_request(name, cache_key, group_key_base):
@routes.route("/logical-system-peerings/<name>", methods=['GET', 'POST'])
@common.require_accepts_json
def logical_system_peerings(name=None):
""" """
Handler for `/msr/logical-system-peerings` Common method for used by
:meth:`inventory_provider.routes.msr.logical_system_peerings` and
:meth:`inventory_provider.routes.msr.bgp_group_peerings`.
This method will return a list of all peerings configured This method will return a list of all peerings configured
for the requested logical-system name on any router, or for any for the specified group `name on any router,
logical system if no parameter is given. or for all group names if `name` None.
The response will be formatted according to the following schema: The response will be formatted according to the following schema:
.. asjson:: .. asjson::
inventory_provider.routes.msr.LOGICAL_SYSTEM_PEERING_LIST_SCHEMA inventory_provider.routes.msr.PEERING_LIST_SCHEMA
:return: :param name: group/logical-system name, nor None
:param cache_key: base cache key for this type of request
:param group_key_base: key above which the peerings are grouped
:return: a json list, formatted as above
""" """
r = common.get_current_redis() r = common.get_current_redis()
def _get_all_ls_keys(): def _get_all_ls_keys():
keys = [] keys = []
for k in r.scan_iter('juniper-peerings:logical-system:*', count=1000): for k in r.scan_iter(f'{group_key_base}:*', count=1000):
keys.append(k.decode('utf-8')) keys.append(k.decode('utf-8'))
return keys return keys
...@@ -146,7 +151,7 @@ def logical_system_peerings(name=None): ...@@ -146,7 +151,7 @@ def logical_system_peerings(name=None):
if value: if value:
yield from json.loads(value.decode('utf-8')) yield from json.loads(value.decode('utf-8'))
cache_key = 'classifier-cache:msr:logical-system-peerings'
if name: if name:
cache_key = f'{cache_key}:{name}' cache_key = f'{cache_key}:{name}'
...@@ -156,7 +161,7 @@ def logical_system_peerings(name=None): ...@@ -156,7 +161,7 @@ def logical_system_peerings(name=None):
items = json.loads(items.decode('utf-8')) items = json.loads(items.decode('utf-8'))
else: else:
if name: if name:
items = _load_list_items(f'juniper-peerings:logical-system:{name}') items = _load_list_items(f'{group_key_base}:{name}')
else: else:
gen_list = list(map(_load_list_items, _get_all_ls_keys())) gen_list = list(map(_load_list_items, _get_all_ls_keys()))
items = itertools.chain(*gen_list) items = itertools.chain(*gen_list)
...@@ -171,3 +176,41 @@ def logical_system_peerings(name=None): ...@@ -171,3 +176,41 @@ def logical_system_peerings(name=None):
r.set(cache_key, json.dumps(items).encode('utf-8')) r.set(cache_key, json.dumps(items).encode('utf-8'))
return jsonify(items) return jsonify(items)
@routes.route("/bgp/logical-system-peerings", methods=['GET', 'POST'])
@routes.route("/bgp/logical-system-peerings/<name>", methods=['GET', 'POST'])
@common.require_accepts_json
def logical_system_peerings(name=None):
"""
Handler for `/msr/bgp/logical-system-peerings`
This method will return a list of all peerings configured
for the requested logical-system name on any router, or for any
logical system if no parameter is given.
:return: see :meth:`inventory_provider.routes.msr._handle_peering_group_request`
"""
return _handle_peering_group_request(
name=name,
cache_key='classifier-cache:msr:logical-system-peerings',
group_key_base='juniper-peerings:logical-system')
@routes.route("/bgp/group-peerings", methods=['GET', 'POST'])
@routes.route("/bgp/group-peerings/<name>", methods=['GET', 'POST'])
@common.require_accepts_json
def bgp_group_peerings(name=None):
"""
Handler for `/msr/bgp/group-peerings`
This method will return a list of all peerings configured
for the requested logical-system name on any router, or for any
logical system if no parameter is given.
:return: see :meth:`inventory_provider.routes.msr._handle_peering_group_request`
"""
return _handle_peering_group_request(
name=name,
cache_key='classifier-cache:msr:group-peerings',
group_key_base='juniper-peerings:group')
...@@ -4,7 +4,7 @@ import jsonschema ...@@ -4,7 +4,7 @@ import jsonschema
import pytest import pytest
from inventory_provider.routes.msr \ from inventory_provider.routes.msr \
import ACCESS_SERVICES_LIST_SCHEMA, LOGICAL_SYSTEM_PEERING_LIST_SCHEMA import ACCESS_SERVICES_LIST_SCHEMA, PEERING_LIST_SCHEMA
DEFAULT_REQUEST_HEADERS = { DEFAULT_REQUEST_HEADERS = {
"Content-type": "application/json", "Content-type": "application/json",
...@@ -26,25 +26,26 @@ def test_access_services(client): ...@@ -26,25 +26,26 @@ def test_access_services(client):
def test_logical_system_peerings_all(client): def test_logical_system_peerings_all(client):
rv = client.get( rv = client.get(
'/msr/logical-system-peerings', '/msr/bgp/logical-system-peerings',
headers=DEFAULT_REQUEST_HEADERS) headers=DEFAULT_REQUEST_HEADERS)
assert rv.status_code == 200 assert rv.status_code == 200
assert rv.is_json assert rv.is_json
response_data = json.loads(rv.data.decode('utf-8')) response_data = json.loads(rv.data.decode('utf-8'))
jsonschema.validate(response_data, LOGICAL_SYSTEM_PEERING_LIST_SCHEMA) jsonschema.validate(response_data, PEERING_LIST_SCHEMA)
assert response_data # test data is non-empty assert response_data # test data is non-empty
assert all('logical-system' in p for p in response_data)
@pytest.mark.parametrize('name', ['VRR', 'VPN-PROXY']) @pytest.mark.parametrize('name', ['VRR', 'VPN-PROXY'])
def test_logical_system_peerings_specific(client, name): def test_logical_system_peerings_specific(client, name):
rv = client.get( rv = client.get(
f'/msr/logical-system-peerings/{name}', f'/msr/bgp/logical-system-peerings/{name}',
headers=DEFAULT_REQUEST_HEADERS) headers=DEFAULT_REQUEST_HEADERS)
assert rv.status_code == 200 assert rv.status_code == 200
assert rv.is_json assert rv.is_json
response_data = json.loads(rv.data.decode('utf-8')) response_data = json.loads(rv.data.decode('utf-8'))
jsonschema.validate(response_data, LOGICAL_SYSTEM_PEERING_LIST_SCHEMA) jsonschema.validate(response_data, PEERING_LIST_SCHEMA)
assert response_data # test data is non-empty assert response_data # test data is non-empty
assert all(p['logical-system'] == name for p in response_data) assert all(p['logical-system'] == name for p in response_data)
...@@ -59,6 +60,43 @@ def test_logical_system_peerings_specific(client, name): ...@@ -59,6 +60,43 @@ def test_logical_system_peerings_specific(client, name):
]) ])
def test_logical_system_peerings_404(client, name): def test_logical_system_peerings_404(client, name):
rv = client.get( rv = client.get(
f'/msr/logical-system-peerings/{name}', f'/msr/bgp/logical-system-peerings/{name}',
headers=DEFAULT_REQUEST_HEADERS) headers=DEFAULT_REQUEST_HEADERS)
assert rv.status_code == 404 assert rv.status_code == 404
def test_group_peerings_all(client):
rv = client.get(
f'/msr/bgp/group-peerings',
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, PEERING_LIST_SCHEMA)
assert response_data # test data is non-empty
@pytest.mark.parametrize('name', ['BGPLU', 'eGEANT', 'eGEANT-mcast'])
def test_group_peerings_specific(client, name):
rv = client.get(
f'/msr/bgp/group-peerings/{name}',
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, PEERING_LIST_SCHEMA)
assert response_data # test data is non-empty
assert all(p['group'] == name for p in response_data)
@pytest.mark.parametrize('name', ['EGEANT', 'eGEANT mcast'])
def test_logical_system_peerings_404(client, name):
rv = client.get(
f'/msr/bgp/logical-system-peerings/{name}',
headers=DEFAULT_REQUEST_HEADERS)
assert rv.status_code == 404
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment