diff --git a/src/service/service/service_handler_api/ServiceHandlerFactory.py b/src/service/service/service_handler_api/ServiceHandlerFactory.py index 6aa21b49920254383fad5f28aa234b6ec0cad5a3..64ea204a2600a71b08c8c373a15640f5e2134787 100644 --- a/src/service/service/service_handler_api/ServiceHandlerFactory.py +++ b/src/service/service/service_handler_api/ServiceHandlerFactory.py @@ -73,6 +73,9 @@ class ServiceHandlerFactory: if field_indice is None: continue if not isinstance(field_values, Iterable) or isinstance(field_values, str): field_values = [field_values] + if len(field_values) == 0: + # do not allow empty fields; might cause wrong selection + raise UnsatisfiedFilterException(filter_fields) field_enum_values = FILTER_FIELD_ALLOWED_VALUES.get(field_name) diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py index 9b4e442e5adfed8f23c6b4d8d0f5ec3cfdcb0bae..fa215af2f996dcb0238f6177b2ef43861d873842 100644 --- a/src/service/service/service_handlers/__init__.py +++ b/src/service/service/service_handlers/__init__.py @@ -57,7 +57,7 @@ SERVICE_HANDLERS = [ (MicrowaveServiceHandler, [ { FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_L2NM, - FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, + FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352], } ]), (P4ServiceHandler, [ diff --git a/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py index c2ea6e213ee8d18b4507089fb2762c913e03039a..84467dd2dd5dbf9d782700e65fad88730c7a7379 100644 --- a/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py +++ b/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py @@ -21,10 +21,13 @@ def setup_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] - mtu = json_settings.get('mtu', 1450 ) # 1512 + #json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value + + #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 #bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333 @@ -80,8 +83,11 @@ def teardown_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: - #json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + #json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] diff --git a/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py b/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py index 1f5817fe873d3d2c926e955410555305cda145f0..f84c8c824b1e2d05b2ee483195d1306958d81411 100644 --- a/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py +++ b/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py @@ -47,34 +47,28 @@ class L2NM_IETFL2VPN_ServiceHandler(_ServiceHandler): service_uuid = self.__service.service_id.service_uuid.uuid settings = self.__settings_handler.get('/settings') json_settings : Dict = {} if settings is None else settings.value - capacity_value = json_settings.get('capacity_value', 50.0) - capacity_unit = json_settings.get('capacity_unit', 'GHz') - layer_proto_name = json_settings.get('layer_proto_name', 'PHOTONIC_MEDIA') - layer_proto_qual = json_settings.get('layer_proto_qual', 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC') - direction = json_settings.get('direction', 'UNIDIRECTIONAL') + encap_type = json_settings.get('encapsulation_type', '') + vlan_id = json_settings.get('vlan_id', 100) results = [] try: - device_uuid_src, endpoint_uuid_src = get_device_endpoint_uuids(endpoints[0]) - device_uuid_dst, endpoint_uuid_dst = get_device_endpoint_uuids(endpoints[1]) + src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0]) + dst_device_uuid, dst_endpoint_uuid = get_device_endpoint_uuids(endpoints[1]) - if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') - device_uuid = device_uuid_src + if src_device_uuid != dst_device_uuid: + raise Exception('Different Src-Dst devices not supported by now') + device_uuid = src_device_uuid device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - endpoint_name_src = get_endpoint_matching(device_obj, endpoint_uuid_src).name - endpoint_name_dst = get_endpoint_matching(device_obj, endpoint_uuid_dst).name json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { - 'uuid' : service_uuid, - 'input_sip' : endpoint_name_src, - 'output_sip' : endpoint_name_dst, - 'capacity_unit' : capacity_unit, - 'capacity_value' : capacity_value, - 'layer_protocol_name' : layer_proto_name, - 'layer_protocol_qualifier': layer_proto_qual, - 'direction' : direction, + 'uuid' : service_uuid, + 'src_device_uuid' : src_device_uuid, + 'src_endpoint_uuid' : src_endpoint_uuid, + 'dst_device_uuid' : dst_device_uuid, + 'dst_endpoint_uuid' : dst_endpoint_uuid, + 'encapsulation_type': encap_type, + 'vlan_id' : vlan_id, }) del device_obj.device_config.config_rules[:] device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) @@ -102,7 +96,7 @@ class L2NM_IETFL2VPN_ServiceHandler(_ServiceHandler): device_uuid_dst, _ = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) diff --git a/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py b/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py index bbd91df93b15c669878dce092d415a678beafa8a..58071f28a40175c10d3d9fa43ad7ca2b5b3b90b6 100644 --- a/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py +++ b/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py @@ -24,12 +24,9 @@ def setup_config_rules( if service_settings is None: return [] if endpoint_settings is None: return [] - json_settings : Dict = service_settings.value + #json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value - #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 @@ -41,16 +38,15 @@ def setup_config_rules( vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400 #address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1' #address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30 - remote_router = json_endpoint_settings.get('remote_router', '5.5.5.5') # '5.5.5.5' - circuit_id = json_endpoint_settings.get('circuit_id', '111' ) # '111' - + remote_router = json_endpoint_settings.get('remote_router', '0.0.0.0') # '5.5.5.5' + circuit_id = json_endpoint_settings.get('circuit_id', '000' ) # '111' if_cirid_name = '{:s}.{:s}'.format(endpoint_name, str(circuit_id)) network_instance_name = 'ELAN-AC:{:s}'.format(str(circuit_id)) connection_point_id = 'VC-1' json_config_rules = [ - + json_config_rule_set( '/network_instance[{:s}]'.format(network_instance_name), {'name': network_instance_name, @@ -86,8 +82,11 @@ def teardown_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: - #json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + #json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] diff --git a/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py index 903ad8cd5ae442a03d54fb49083f3837a3c8187c..f4a46112e778bd01aa76322384d8adee942aaa5b 100644 --- a/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py +++ b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py @@ -21,8 +21,11 @@ def setup_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value service_short_uuid = service_uuid.split('-')[-1] network_instance_name = '{:s}-NetInst'.format(service_short_uuid) @@ -142,8 +145,11 @@ def teardown_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] diff --git a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py index 351efe5a5f32db99c36846ad2fd96e2c8567148e..4984fd77cf41f7cff4b13c6e6ee16a1bcba6093a 100644 --- a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py +++ b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py @@ -187,8 +187,8 @@ def teardown_config_rules( if service_settings is None: return [] if endpoint_settings is None: return [] - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value service_short_uuid = service_uuid.split('-')[-1] network_instance_name = '{:s}-NetInst'.format(service_short_uuid) diff --git a/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py b/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py index ee64d2fa4ff0110aea9ee4beee97fa83915ab57d..40c87eeee2c8dd1ddd5a39162f8ff7f117344e3b 100644 --- a/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py +++ b/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py @@ -61,7 +61,7 @@ class MicrowaveServiceHandler(_ServiceHandler): device_uuid_dst, endpoint_uuid_dst = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) @@ -106,7 +106,7 @@ class MicrowaveServiceHandler(_ServiceHandler): device_uuid_dst, _ = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) diff --git a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py index 8abd12b2a24c49a6c5e50cebe7a2d65dc7ce4eb1..dd9ff092ac049054571c661b4a7dd969fba407a9 100644 --- a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py +++ b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py @@ -19,7 +19,7 @@ from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type -from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching +from service.service.service_handler_api.Tools import get_device_endpoint_uuids from service.service.service_handler_api._ServiceHandler import _ServiceHandler from service.service.service_handler_api.SettingsHandler import SettingsHandler from service.service.task_scheduler.TaskExecutor import TaskExecutor @@ -59,17 +59,15 @@ class TapiServiceHandler(_ServiceHandler): device_uuid_dst, endpoint_uuid_dst = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - endpoint_name_src = get_endpoint_matching(device_obj, endpoint_uuid_src).name - endpoint_name_dst = get_endpoint_matching(device_obj, endpoint_uuid_dst).name json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { 'uuid' : service_uuid, - 'input_sip' : endpoint_name_src, - 'output_sip' : endpoint_name_dst, + 'input_sip' : endpoint_uuid_src, + 'output_sip' : endpoint_uuid_dst, 'capacity_unit' : capacity_unit, 'capacity_value' : capacity_value, 'layer_protocol_name' : layer_proto_name, @@ -102,7 +100,7 @@ class TapiServiceHandler(_ServiceHandler): device_uuid_dst, _ = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 932c56e2b1934e12e7849a60c22d3ca1be7f8093..e475f29c65b898895838901ca86636bbd5b9ea88 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -12,10 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Optional, Union from common.method_wrappers.ServiceExceptions import NotFoundException from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceId, Service, ServiceId +from common.tools.object_factory.Device import json_device_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory, get_service_handler_class @@ -103,13 +105,32 @@ class TaskExecutor: self._device_client.ConfigureDevice(device) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) - def get_devices_from_connection(self, connection : Connection) -> Dict[str, Device]: + def get_devices_from_connection( + self, connection : Connection, exclude_managed : bool = False + ) -> Dict[str, Device]: devices = dict() for endpoint_id in connection.path_hops_endpoint_ids: device = self.get_device(endpoint_id.device_id) device_uuid = endpoint_id.device_id.device_uuid.uuid if device is None: raise Exception('Device({:s}) not found'.format(str(device_uuid))) - devices[device_uuid] = device + + manager = None + for config_rule in device.device_config.config_rules: + if config_rule.WhichOneof('config_rule') != 'custom': continue + if config_rule.custom.resource_key != '_manager': continue + manager = json.loads(config_rule.custom.resource_value) + break + + if manager is not None: + if not exclude_managed: + devices[device_uuid] = device + manager_uuid = manager['uuid'] + manager = self.get_device(DeviceId(**json_device_id(manager_uuid))) + manager_uuid = manager.device_id.device_uuid.uuid + if manager is None: raise Exception('Device({:s}) not found'.format(str(manager_uuid))) + devices[manager_uuid] = manager + else: + devices[device_uuid] = device return devices # ----- Service-related methods ------------------------------------------------------------------------------------ @@ -139,6 +160,6 @@ class TaskExecutor: def get_service_handler( self, connection : Connection, service : Service, **service_handler_settings ) -> '_ServiceHandler': - connection_devices = self.get_devices_from_connection(connection) + connection_devices = self.get_devices_from_connection(connection, exclude_managed=True) service_handler_class = get_service_handler_class(self._service_handler_factory, service, connection_devices) return service_handler_class(service, self, **service_handler_settings) diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py index 5a47005b304836050dd8c0882214dd9cebd5d8b5..4367ffdee4d6d5b9edfc9fd30d0d6b6f48da8a75 100644 --- a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py +++ b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py @@ -32,7 +32,7 @@ class Task_ConnectionConfigure(_Task): def connection_id(self) -> ConnectionId: return self._connection_id @staticmethod - def build_key(connection_id : ConnectionId) -> str: + def build_key(connection_id : ConnectionId) -> str: # pylint: disable=arguments-differ str_connection_id = get_connection_key(connection_id) return KEY_TEMPLATE.format(connection_id=str_connection_id) diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py index 5736054febd2fb9e8a36b5a2235ca3f412e0e174..70f41566ef5e69605a527cc0392b77acb866ec2c 100644 --- a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py +++ b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py @@ -32,7 +32,7 @@ class Task_ConnectionDeconfigure(_Task): def connection_id(self) -> ConnectionId: return self._connection_id @staticmethod - def build_key(connection_id : ConnectionId) -> str: + def build_key(connection_id : ConnectionId) -> str: # pylint: disable=arguments-differ str_connection_id = get_connection_key(connection_id) return KEY_TEMPLATE.format(connection_id=str_connection_id) diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py index 6a4e11b540cd9b85028d92cf86899ee098056c36..0f021b6ca65da1c6b5e44d8577bf9dd6875eb17a 100644 --- a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py +++ b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py @@ -28,7 +28,7 @@ class Task_ServiceDelete(_Task): def service_id(self) -> ServiceId: return self._service_id @staticmethod - def build_key(service_id : ServiceId) -> str: + def build_key(service_id : ServiceId) -> str: # pylint: disable=arguments-differ str_service_id = get_service_key(service_id) return KEY_TEMPLATE.format(service_id=str_service_id) diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py index 815cb33c3d540755704153b661e889fc2660d268..d5360fe85eae68085298406fc0ed19dd105f187e 100644 --- a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py +++ b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py @@ -32,7 +32,7 @@ class Task_ServiceSetStatus(_Task): def new_status(self) -> ServiceStatusEnum: return self._new_status @staticmethod - def build_key(service_id : ServiceId, new_status : ServiceStatusEnum) -> str: + def build_key(service_id : ServiceId, new_status : ServiceStatusEnum) -> str: # pylint: disable=arguments-differ str_service_id = get_service_key(service_id) str_new_status = ServiceStatusEnum.Name(new_status) return KEY_TEMPLATE.format(service_id=str_service_id, new_status=str_new_status)