From a0d581cc6766fa8b82706d04a824a8196ff00ecb Mon Sep 17 00:00:00 2001 From: Erik Reid <erik.reid@geant.org> Date: Tue, 16 Feb 2021 13:05:54 +0100 Subject: [PATCH] added bgp group name list apis --- inventory_provider/routes/msr.py | 86 +++++++++++++++++++++++++++++++- test/test_msr_routes.py | 14 +++++- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/inventory_provider/routes/msr.py b/inventory_provider/routes/msr.py index 1f31d862..d1f24c34 100644 --- a/inventory_provider/routes/msr.py +++ b/inventory_provider/routes/msr.py @@ -38,6 +38,12 @@ ACCESS_SERVICES_LIST_SCHEMA = { "items": {"$ref": "#/definitions/service"} } +PEERING_GROUP_LIST_SCHEMA = { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "array", + "items": {"type": "string"} + +} PEERING_LIST_SCHEMA = { "$schema": "http://json-schema.org/draft-07/schema#", @@ -140,7 +146,7 @@ def _handle_peering_group_request(name, cache_key, group_key_base): r = common.get_current_redis() - def _get_all_ls_keys(): + def _get_all_subkeys(): keys = [] for k in r.scan_iter(f'{group_key_base}:*', count=1000): keys.append(k.decode('utf-8')) @@ -163,7 +169,7 @@ def _handle_peering_group_request(name, cache_key, group_key_base): if name: items = _load_list_items(f'{group_key_base}:{name}') else: - gen_list = list(map(_load_list_items, _get_all_ls_keys())) + gen_list = list(map(_load_list_items, _get_all_subkeys())) items = itertools.chain(*gen_list) items = list(items) @@ -214,3 +220,79 @@ def bgp_group_peerings(name=None): name=name, cache_key='classifier-cache:msr:group-peerings', group_key_base='juniper-peerings:group') + + +def _handle_peering_group_list_request(cache_key, group_key_base): + """ + Common method for used by + :meth:`inventory_provider.routes.msr.get_logical_systems` and + :meth:`inventory_provider.routes.msr.get_peering_groups`. + + This method will return a list of all immediate subkeys of + `group_key_base`. + + The response will be formatted according to the following schema: + + .. asjson:: + inventory_provider.routes.msr.PEERING_GROUP_LIST_SCHEMA + + :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() + + def _get_all_subkeys(): + for k in r.scan_iter(f'{group_key_base}:*', count=1000): + k = k.decode('utf-8') + yield k[len(group_key_base) + 1:] + + names = r.get(cache_key) + + if names: + names = json.loads(names.decode('utf-8')) + else: + names = list(_get_all_subkeys()) + if not names: + return Response( + response='no groups found', + status=404, + mimetype="text/html") + names = sorted(names) + + r.set(cache_key, json.dumps(names).encode('utf-8')) + + return jsonify(names) + + +@routes.route("/bgp/logical-systems", methods=['GET', 'POST']) +@common.require_accepts_json +def get_logical_systems(): + """ + Handler for `/msr/bgp/logical-systems` + + Returns a list of logical system names for which peering + information is available. + + :return: see :meth:`inventory_provider.routes.msr._handle_peering_group_list_request` + """ + return _handle_peering_group_list_request( + cache_key='classifier-cache:msr:logical-systems', + group_key_base='juniper-peerings:logical-system') + + +@routes.route("/bgp/groups", methods=['GET', 'POST']) +@common.require_accepts_json +def get_peering_groups(): + """ + Handler for `/msr/bgp/groups` + + Returns a list of group names for which peering + information is available. + + :return: see :meth:`inventory_provider.routes.msr._handle_peering_group_list_request` + """ + return _handle_peering_group_list_request( + cache_key='classifier-cache:msr:peering-groups', + group_key_base='juniper-peerings:group') diff --git a/test/test_msr_routes.py b/test/test_msr_routes.py index a30015f6..1a4ce292 100644 --- a/test/test_msr_routes.py +++ b/test/test_msr_routes.py @@ -3,8 +3,8 @@ import jsonschema import pytest -from inventory_provider.routes.msr \ - import ACCESS_SERVICES_LIST_SCHEMA, PEERING_LIST_SCHEMA +from inventory_provider.routes.msr import ACCESS_SERVICES_LIST_SCHEMA, \ + PEERING_LIST_SCHEMA, PEERING_GROUP_LIST_SCHEMA DEFAULT_REQUEST_HEADERS = { "Content-type": "application/json", @@ -99,4 +99,14 @@ def test_logical_system_peerings_404(client, name): assert rv.status_code == 404 +@pytest.mark.parametrize('uri', [ + '/msr/bgp/logical-systems', + '/msr/bgp/groups']) +def test_peerings_group_list(client, uri): + rv = client.get(uri, 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_GROUP_LIST_SCHEMA) + assert response_data # test data is non-empty -- GitLab