Loading src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py +10 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ from common.tools.object_factory.Device import json_device_id from common.tools.object_factory.EndPoint import json_endpoint_id from common.type_checkers.Checkers import chk_string, chk_type from device.service.driver_api._Driver import _Driver, RESOURCE_ENDPOINTS, RESOURCE_SERVICES from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum, get_import_topology from device.service.drivers.ietf_l2vpn.TfsDebugApiClient import TfsDebugApiClient from .Tools import connection_point, wim_mapping from .WimconnectorIETFL2VPN import WimconnectorIETFL2VPN Loading Loading @@ -59,6 +60,14 @@ class IetfL2VpnDriver(_Driver): self.wim = WimconnectorIETFL2VPN(wim, wim_account, config=config) self.conn_info = {} # internal database emulating OSM storage provided to WIM Connectors # Options are: # disabled --> just import endpoints as usual # devices --> imports sub-devices but not links connecting them. # (a remotely-controlled transport domain might exist between them) # topology --> imports sub-devices and links connecting them. # (not supported by XR driver) self.__import_topology = get_import_topology(self.settings, default=ImportTopologyEnum.DEVICES) def Connect(self) -> bool: with self.__lock: try: Loading Loading @@ -93,7 +102,7 @@ class IetfL2VpnDriver(_Driver): chk_string(str_resource_name, resource_key, allow_empty=False) if resource_key == RESOURCE_ENDPOINTS: # return endpoints through debug-api and list-devices method results.extend(self.dac.get_devices_endpoints()) results.extend(self.dac.get_devices_endpoints(self.__import_topology)) elif resource_key == RESOURCE_SERVICES: # return all services through reply = self.wim.get_all_active_connectivity_services() Loading src/device/service/drivers/ietf_l2vpn/TfsDebugApiClient.py +39 −4 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ import logging, requests from requests.auth import HTTPBasicAuth from typing import Dict, List, Optional from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum GET_DEVICES_URL = '{:s}://{:s}:{:d}/restconf/debug-api/devices' GET_LINKS_URL = '{:s}://{:s}:{:d}/restconf/debug-api/links' TIMEOUT = 30 HTTP_OK_CODES = { Loading @@ -41,6 +43,7 @@ MAPPING_DRIVER = { 'DEVICEDRIVER_ONF_TR_352' : 5, 'DEVICEDRIVER_XR' : 6, 'DEVICEDRIVER_IETF_L2VPN' : 7, 'DEVICEDRIVER_GNMI_OPENCONFIG' : 8, } MSG_ERROR = 'Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}' Loading @@ -52,16 +55,23 @@ class TfsDebugApiClient: self, address : str, port : int, scheme : str = 'http', username : Optional[str] = None, password : Optional[str] = None ) -> None: self._url = GET_DEVICES_URL.format(scheme, address, port) self._devices_url = GET_DEVICES_URL.format(scheme, address, port) self._links_url = GET_LINKS_URL.format(scheme, address, port) self._auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None def get_devices_endpoints(self) -> List[Dict]: reply = requests.get(self._url, timeout=TIMEOUT, verify=False, auth=self._auth) def get_devices_endpoints(self, import_topology : ImportTopologyEnum = ImportTopologyEnum.DEVICES) -> List[Dict]: LOGGER.debug('[get_devices_endpoints] begin') LOGGER.debug('[get_devices_endpoints] import_topology={:s}'.format(str(import_topology))) reply = requests.get(self._devices_url, timeout=TIMEOUT, verify=False, auth=self._auth) if reply.status_code not in HTTP_OK_CODES: msg = MSG_ERROR.format(str(self._url), str(reply.status_code), str(reply)) msg = MSG_ERROR.format(str(self._devices_url), str(reply.status_code), str(reply)) LOGGER.error(msg) raise Exception(msg) if import_topology == ImportTopologyEnum.DISABLED: raise Exception('Unsupported import_topology mode: {:s}'.format(str(import_topology))) result = list() for json_device in reply.json()['devices']: device_uuid : str = json_device['device_id']['device_uuid']['uuid'] Loading Loading @@ -89,4 +99,29 @@ class TfsDebugApiClient: } result.append((endpoint_url, endpoint_data)) if import_topology == ImportTopologyEnum.DEVICES: LOGGER.debug('[get_devices_endpoints] devices only; returning') return result reply = requests.get(self._links_url, timeout=TIMEOUT, verify=False, auth=self._auth) if reply.status_code not in HTTP_OK_CODES: msg = MSG_ERROR.format(str(self._links_url), str(reply.status_code), str(reply)) LOGGER.error(msg) raise Exception(msg) for json_link in reply.json()['links']: link_uuid : str = json_link['link_id']['link_uuid']['uuid'] link_url = '/links/link[{:s}]'.format(link_uuid) link_endpoint_ids = [ (json_endpoint_id['device_id']['device_uuid']['uuid'], json_endpoint_id['endpoint_uuid']['uuid']) for json_endpoint_id in json_link['link_endpoint_ids'] ] link_data = { 'uuid': json_link['link_id']['link_uuid']['uuid'], 'name': json_link['name'], 'endpoints': link_endpoint_ids, } result.append((link_url, link_data)) LOGGER.debug('[get_devices_endpoints] topology; returning') return result Loading
src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py +10 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ from common.tools.object_factory.Device import json_device_id from common.tools.object_factory.EndPoint import json_endpoint_id from common.type_checkers.Checkers import chk_string, chk_type from device.service.driver_api._Driver import _Driver, RESOURCE_ENDPOINTS, RESOURCE_SERVICES from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum, get_import_topology from device.service.drivers.ietf_l2vpn.TfsDebugApiClient import TfsDebugApiClient from .Tools import connection_point, wim_mapping from .WimconnectorIETFL2VPN import WimconnectorIETFL2VPN Loading Loading @@ -59,6 +60,14 @@ class IetfL2VpnDriver(_Driver): self.wim = WimconnectorIETFL2VPN(wim, wim_account, config=config) self.conn_info = {} # internal database emulating OSM storage provided to WIM Connectors # Options are: # disabled --> just import endpoints as usual # devices --> imports sub-devices but not links connecting them. # (a remotely-controlled transport domain might exist between them) # topology --> imports sub-devices and links connecting them. # (not supported by XR driver) self.__import_topology = get_import_topology(self.settings, default=ImportTopologyEnum.DEVICES) def Connect(self) -> bool: with self.__lock: try: Loading Loading @@ -93,7 +102,7 @@ class IetfL2VpnDriver(_Driver): chk_string(str_resource_name, resource_key, allow_empty=False) if resource_key == RESOURCE_ENDPOINTS: # return endpoints through debug-api and list-devices method results.extend(self.dac.get_devices_endpoints()) results.extend(self.dac.get_devices_endpoints(self.__import_topology)) elif resource_key == RESOURCE_SERVICES: # return all services through reply = self.wim.get_all_active_connectivity_services() Loading
src/device/service/drivers/ietf_l2vpn/TfsDebugApiClient.py +39 −4 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ import logging, requests from requests.auth import HTTPBasicAuth from typing import Dict, List, Optional from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum GET_DEVICES_URL = '{:s}://{:s}:{:d}/restconf/debug-api/devices' GET_LINKS_URL = '{:s}://{:s}:{:d}/restconf/debug-api/links' TIMEOUT = 30 HTTP_OK_CODES = { Loading @@ -41,6 +43,7 @@ MAPPING_DRIVER = { 'DEVICEDRIVER_ONF_TR_352' : 5, 'DEVICEDRIVER_XR' : 6, 'DEVICEDRIVER_IETF_L2VPN' : 7, 'DEVICEDRIVER_GNMI_OPENCONFIG' : 8, } MSG_ERROR = 'Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}' Loading @@ -52,16 +55,23 @@ class TfsDebugApiClient: self, address : str, port : int, scheme : str = 'http', username : Optional[str] = None, password : Optional[str] = None ) -> None: self._url = GET_DEVICES_URL.format(scheme, address, port) self._devices_url = GET_DEVICES_URL.format(scheme, address, port) self._links_url = GET_LINKS_URL.format(scheme, address, port) self._auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None def get_devices_endpoints(self) -> List[Dict]: reply = requests.get(self._url, timeout=TIMEOUT, verify=False, auth=self._auth) def get_devices_endpoints(self, import_topology : ImportTopologyEnum = ImportTopologyEnum.DEVICES) -> List[Dict]: LOGGER.debug('[get_devices_endpoints] begin') LOGGER.debug('[get_devices_endpoints] import_topology={:s}'.format(str(import_topology))) reply = requests.get(self._devices_url, timeout=TIMEOUT, verify=False, auth=self._auth) if reply.status_code not in HTTP_OK_CODES: msg = MSG_ERROR.format(str(self._url), str(reply.status_code), str(reply)) msg = MSG_ERROR.format(str(self._devices_url), str(reply.status_code), str(reply)) LOGGER.error(msg) raise Exception(msg) if import_topology == ImportTopologyEnum.DISABLED: raise Exception('Unsupported import_topology mode: {:s}'.format(str(import_topology))) result = list() for json_device in reply.json()['devices']: device_uuid : str = json_device['device_id']['device_uuid']['uuid'] Loading Loading @@ -89,4 +99,29 @@ class TfsDebugApiClient: } result.append((endpoint_url, endpoint_data)) if import_topology == ImportTopologyEnum.DEVICES: LOGGER.debug('[get_devices_endpoints] devices only; returning') return result reply = requests.get(self._links_url, timeout=TIMEOUT, verify=False, auth=self._auth) if reply.status_code not in HTTP_OK_CODES: msg = MSG_ERROR.format(str(self._links_url), str(reply.status_code), str(reply)) LOGGER.error(msg) raise Exception(msg) for json_link in reply.json()['links']: link_uuid : str = json_link['link_id']['link_uuid']['uuid'] link_url = '/links/link[{:s}]'.format(link_uuid) link_endpoint_ids = [ (json_endpoint_id['device_id']['device_uuid']['uuid'], json_endpoint_id['endpoint_uuid']['uuid']) for json_endpoint_id in json_link['link_endpoint_ids'] ] link_data = { 'uuid': json_link['link_id']['link_uuid']['uuid'], 'name': json_link['name'], 'endpoints': link_endpoint_ids, } result.append((link_url, link_data)) LOGGER.debug('[get_devices_endpoints] topology; returning') return result