diff --git a/inventory_provider/routes/msr.py b/inventory_provider/routes/msr.py index ef970a977d453388c87f8a22b713a9e11b78499f..78bc959d198fb1fcdddf7c57b3586a1bc213bea0 100644 --- a/inventory_provider/routes/msr.py +++ b/inventory_provider/routes/msr.py @@ -64,12 +64,19 @@ These endpoints are intended for use by MSR. .. autofunction:: inventory_provider.routes.msr.mdvpn + /msr/services -------------------------------------------- .. autofunction:: inventory_provider.routes.msr.get_system_correlation_services +/msr/vpn-proxy +-------------------------------------------- + +.. autofunction:: inventory_provider.routes.msr.vpn-proxy + + helpers ------------------------------------- @@ -327,7 +334,10 @@ VPN_PROXY_LIST_SCHEMA = { 'vpn_proxy_peering': { 'type': 'object', 'properties': { - # TODO: THIS + 'pop': {'type': 'string'}, + 'nren': {'type': 'string'}, + 'group': {'type': 'string'}, + 'v4': {'type': 'string'} }, 'additionalProperties': False } @@ -1086,17 +1096,42 @@ def mdvpn(): @routes.route('/vpn-proxy', methods=['GET', 'POST']) @common.require_accepts_json def vpn_proxy(): + """ + Handler for `/vpn-proxy` + + This method returns a list of all L3VPN related VPN proxy peerings. + + The response will be formatted according to the following schema: + + .. asjson:: + inventory_provider.routes.msr.VPN_PROXY_LIST_SCHEMA + + :return: + """ def _is_relevant(item): + """ + Determine if a given peering in the VPN-PROXY logical system is + relevant to this endpoint (whether it's related to L3VPN) + :param item: peering dict + :return: True if the peering is L3VPN relevant, False otherwise + """ desc = item.get("description") if desc is None: return False return "L3VPN" in desc def _look_up_city_from_hostname(hostname): + """ + Get the city name for a peering from a partial hostname match. + This uses a hardcoded lookup table. + :param hostname: hostname for the peering + :return: city name if found, "Unknown" otherwise + """ for snippet in DOMAIN_TO_POP_MAPPING: if snippet in hostname: return DOMAIN_TO_POP_MAPPING[snippet] + return "Unknown" def _extract_nren_from_description(desc, group): """ @@ -1116,6 +1151,12 @@ def vpn_proxy(): return 'CESNet' def _format_peerings(vpnproxy): + """ + Generator that iterates through a list of peering dicts, yielding + appropriately reformatted peerings if they are relevant to L3VPN. + :param vpnproxy: list of peering dicts taken from current redis + :return: generator of reformated peerings + """ for peering in vpnproxy: if _is_relevant(peering): desc = peering["description"] @@ -1135,7 +1176,8 @@ def vpn_proxy(): cache_key = 'classifier-cache:msr:vpn-proxy' response = _ignore_cache_or_retrieve(request, cache_key, r) if not response: - vpnproxy = json.loads(r.get('juniper-peerings:logical-system:VPN-PROXY').decode('utf-8')) + vpnproxy = json.loads( + r.get('juniper-peerings:logical-system:VPN-PROXY').decode('utf-8')) peerings = list(filter(None, _format_peerings(vpnproxy))) response = json.dumps(peerings) return Response(response, mimetype='application/json') diff --git a/test/test_msr_routes.py b/test/test_msr_routes.py index eda590d2613d9b45d0383cb660c0626ee96e7098..b47c09307be1458eb1c0706ca0476138cc75a9ac 100644 --- a/test/test_msr_routes.py +++ b/test/test_msr_routes.py @@ -6,7 +6,7 @@ import pytest from inventory_provider.routes.msr import PEERING_LIST_SCHEMA, \ PEERING_GROUP_LIST_SCHEMA, PEERING_ADDRESS_SERVICES_LIST, \ SYSTEM_CORRELATION_SERVICES_LIST_SCHEMA, _get_services_for_address, \ - MDVPN_LIST_SCHEMA + MDVPN_LIST_SCHEMA, VPN_PROXY_LIST_SCHEMA from inventory_provider.routes.poller import SERVICES_LIST_SCHEMA from inventory_provider.tasks.common import _get_redis @@ -334,3 +334,15 @@ def test_get_mdvpn_peerings(client, mocked_redis): response_data = json.loads(rv.data.decode('utf-8')) jsonschema.validate(response_data, MDVPN_LIST_SCHEMA) assert response_data # test data is non-empty + + +def test_get_vpn_proxy_peerings(client, mocked_redis): + rv = client.get( + '/msr/vpn-proxy', + 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, VPN_PROXY_LIST_SCHEMA) + assert response_data # test data is non-empty