diff --git a/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py b/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py index 3823f569be2d408f81431d1381c5942bb51bc604..6092219632359fa8fe5d906cdc3ebda30dafa94b 100644 --- a/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py +++ b/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py @@ -12,17 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, requests, threading -from requests.auth import HTTPBasicAuth +import logging, threading from typing import Any, Iterator, List, Optional, Tuple, Union from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.type_checkers.Checkers import chk_string, chk_type -from device.service.driver_api._Driver import _Driver -from . import ALL_RESOURCE_KEYS -from .Tools import create_connectivity_service, find_key, config_getter, delete_connectivity_service +from device.service.driver_api._Driver import _Driver, RESOURCE_ENDPOINTS, RESOURCE_SERVICES +from .Tools import find_key +from .WimconnectorIETFL2VPN import WimconnectorIETFL2VPN LOGGER = logging.getLogger(__name__) +ALL_RESOURCE_KEYS = [ + RESOURCE_ENDPOINTS, + RESOURCE_SERVICES, +] + METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'ietf_l2vpn'}) class IetfL2VpnDriver(_Driver): @@ -32,20 +36,17 @@ class IetfL2VpnDriver(_Driver): self.__terminate = threading.Event() username = settings.get('username') password = settings.get('password') - self.__auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None scheme = settings.get('scheme', 'http') - self.__tapi_root = '{:s}://{:s}:{:d}'.format(scheme, address, int(port)) - self.__timeout = int(settings.get('timeout', 120)) + wim = {'wim_url': '{:s}://{:s}:{:d}'.format(scheme, address, int(port))} + wim_account = {'user': username, 'password': password} + config = {'mapping_not_needed': False, 'service_endpoint_mapping': mapping} + self.wim = WimconnectorIETFL2VPN(wim, wim_account, config=config) + self.conn_info = {} # internal database emulating OSM storage provided to WIM Connectors def Connect(self) -> bool: - url = self.__tapi_root + '/restconf/data/tapi-common:context' with self.__lock: - if self.__started.is_set(): return True try: - requests.get(url, timeout=self.__timeout, verify=False, auth=self.__auth) - except requests.exceptions.Timeout: - LOGGER.exception('Timeout connecting {:s}'.format(str(self.__tapi_root))) - return False + self.wim.check_credentials() except Exception: # pylint: disable=broad-except LOGGER.exception('Exception connecting {:s}'.format(str(self.__tapi_root))) return False @@ -68,36 +69,53 @@ class IetfL2VpnDriver(_Driver): chk_type('resources', resource_keys, list) results = [] with self.__lock: + self.wim.check_credentials() if len(resource_keys) == 0: resource_keys = ALL_RESOURCE_KEYS for i, resource_key in enumerate(resource_keys): str_resource_name = 'resource_key[#{:d}]'.format(i) chk_string(str_resource_name, resource_key, allow_empty=False) - results.extend(config_getter( - self.__tapi_root, resource_key, timeout=self.__timeout, auth=self.__auth)) + + if resource_key == RESOURCE_ENDPOINTS: + # return endpoints through debug-api and list-devices method + endpoints = self.debug_api.get_endpoints() + for endpoint in endpoints: results.append(process_endpoint(endpoint)) + elif resource_key == RESOURCE_SERVICES: + # return all services through + services = self.wim.get_all_active_connectivity_services() + for service in services: results.append(process_service(service)) + else: + # assume single-service retrieval + service = self.wim.get_connectivity_service() + results.append(process_service(service)) return results @metered_subclass_method(METRICS_POOL) def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: results = [] - if len(resources) == 0: - return results + if len(resources) == 0: return results with self.__lock: + self.wim.check_credentials() for resource in resources: LOGGER.info('resource = {:s}'.format(str(resource))) - input_sip = find_key(resource, 'input_sip') - output_sip = find_key(resource, 'output_sip') uuid = find_key(resource, 'uuid') - capacity_value = find_key(resource, 'capacity_value') - capacity_unit = find_key(resource, 'capacity_unit') - layer_protocol_name = find_key(resource, 'layer_protocol_name') - layer_protocol_qualifier = find_key(resource, 'layer_protocol_qualifier') - direction = find_key(resource, 'direction') - - data = create_connectivity_service( - self.__tapi_root, uuid, input_sip, output_sip, direction, capacity_value, capacity_unit, - layer_protocol_name, layer_protocol_qualifier, timeout=self.__timeout, auth=self.__auth) - results.extend(data) + #input_sip = find_key(resource, 'input_sip') + #output_sip = find_key(resource, 'output_sip') + #capacity_value = find_key(resource, 'capacity_value') + #capacity_unit = find_key(resource, 'capacity_unit') + #layer_protocol_name = find_key(resource, 'layer_protocol_name') + #layer_protocol_qualifier = find_key(resource, 'layer_protocol_qualifier') + #direction = find_key(resource, 'direction') + + result = self.wim.get_connectivity_service_status( + service_uuid, conn_info=conn_info) + if service_exists(result): + result = self.wim.create_connectivity_service( + service_type, connection_points) + else: + result = self.wim.edit_connectivity_service( + service_uuid, conn_info=conn_info, connection_points=connection_points) + results.extend(process_result(result)) return results @metered_subclass_method(METRICS_POOL) @@ -105,25 +123,33 @@ class IetfL2VpnDriver(_Driver): results = [] if len(resources) == 0: return results with self.__lock: + self.wim.check_credentials() for resource in resources: LOGGER.info('resource = {:s}'.format(str(resource))) uuid = find_key(resource, 'uuid') - results.extend(delete_connectivity_service( - self.__tapi_root, uuid, timeout=self.__timeout, auth=self.__auth)) + + result = self.wim.get_connectivity_service_status( + service_uuid, conn_info=conn_info) + if service_exists(result): + result = self.wim.delete_connectivity_service( + service_uuid, conn_info=conn_info) + else: + result = False + results.append(process_result(result)) return results @metered_subclass_method(METRICS_POOL) def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: - # TODO: TAPI does not support monitoring by now + # TODO: IETF L2VPN does not support monitoring by now return [False for _ in subscriptions] @metered_subclass_method(METRICS_POOL) def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: - # TODO: TAPI does not support monitoring by now + # TODO: IETF L2VPN does not support monitoring by now return [False for _ in subscriptions] def GetState( self, blocking=False, terminate : Optional[threading.Event] = None ) -> Iterator[Tuple[float, str, Any]]: - # TODO: TAPI does not support monitoring by now + # TODO: IETF L2VPN does not support monitoring by now return [] diff --git a/src/device/service/drivers/ietf_l2vpn/MockOSM.py b/src/device/service/drivers/ietf_l2vpn/MockOSM.py deleted file mode 100644 index 338db0e19becc8a9dd277beec7f3b4ceb2e765a3..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/ietf_l2vpn/MockOSM.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -from .WimconnectorIETFL2VPN import WimconnectorIETFL2VPN - -LOGGER = logging.getLogger(__name__) - -class MockOSM: - def __init__(self, url, mapping, username, password): - wim = {'wim_url': url} - wim_account = {'user': username, 'password': password} - config = {'mapping_not_needed': False, 'service_endpoint_mapping': mapping} - self.wim = WimconnectorIETFL2VPN(wim, wim_account, config=config) - self.conn_info = {} # internal database emulating OSM storage provided to WIM Connectors - - def create_connectivity_service(self, service_type, connection_points): - LOGGER.info('[create_connectivity_service] service_type={:s}'.format(str(service_type))) - LOGGER.info('[create_connectivity_service] connection_points={:s}'.format(str(connection_points))) - self.wim.check_credentials() - result = self.wim.create_connectivity_service(service_type, connection_points) - LOGGER.info('[create_connectivity_service] result={:s}'.format(str(result))) - service_uuid, conn_info = result - self.conn_info[service_uuid] = conn_info - return service_uuid - - def get_connectivity_service_status(self, service_uuid): - LOGGER.info('[get_connectivity_service] service_uuid={:s}'.format(str(service_uuid))) - conn_info = self.conn_info.get(service_uuid) - if conn_info is None: raise Exception('ServiceId({:s}) not found'.format(str(service_uuid))) - LOGGER.info('[get_connectivity_service] conn_info={:s}'.format(str(conn_info))) - self.wim.check_credentials() - result = self.wim.get_connectivity_service_status(service_uuid, conn_info=conn_info) - LOGGER.info('[get_connectivity_service] result={:s}'.format(str(result))) - return result - - def edit_connectivity_service(self, service_uuid, connection_points): - LOGGER.info('[edit_connectivity_service] service_uuid={:s}'.format(str(service_uuid))) - LOGGER.info('[edit_connectivity_service] connection_points={:s}'.format(str(connection_points))) - conn_info = self.conn_info.get(service_uuid) - if conn_info is None: raise Exception('ServiceId({:s}) not found'.format(str(service_uuid))) - LOGGER.info('[edit_connectivity_service] conn_info={:s}'.format(str(conn_info))) - self.wim.edit_connectivity_service(service_uuid, conn_info=conn_info, connection_points=connection_points) - - def delete_connectivity_service(self, service_uuid): - LOGGER.info('[delete_connectivity_service] service_uuid={:s}'.format(str(service_uuid))) - conn_info = self.conn_info.get(service_uuid) - if conn_info is None: raise Exception('ServiceId({:s}) not found'.format(str(service_uuid))) - LOGGER.info('[delete_connectivity_service] conn_info={:s}'.format(str(conn_info))) - self.wim.check_credentials() - self.wim.delete_connectivity_service(service_uuid, conn_info=conn_info) diff --git a/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py b/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py index aa4ca045f41ffdc69d2ebf2fcd9b5db99ce45dbe..b3721b2d5249e2468225f95a1428d8c83da588ed 100644 --- a/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py +++ b/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py @@ -55,9 +55,9 @@ class WimconnectorIETFL2VPN(SdnConnectorBase): m["service_endpoint_id"]: m for m in self.service_endpoint_mapping } self.user = wim_account.get("user") - self.passwd = wim_account.get("password") # replace "passwordd" -> "password" + self.passwd = wim_account.get("password") - if self.user and self.passwd is not None: + if self.user is not None and self.passwd is not None: self.auth = (self.user, self.passwd) else: self.auth = None diff --git a/src/device/service/drivers/ietf_l2vpn/__init__.py b/src/device/service/drivers/ietf_l2vpn/__init__.py index 2d3f6df3276f063cd9b414f47bba41b656682049..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/device/service/drivers/ietf_l2vpn/__init__.py +++ b/src/device/service/drivers/ietf_l2vpn/__init__.py @@ -11,17 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES - -ALL_RESOURCE_KEYS = [ - RESOURCE_ENDPOINTS, - RESOURCE_INTERFACES, - RESOURCE_NETWORK_INSTANCES, -] - -RESOURCE_KEY_MAPPINGS = { - RESOURCE_ENDPOINTS : 'component', - RESOURCE_INTERFACES : 'interface', - RESOURCE_NETWORK_INSTANCES: 'network_instance', -}