From c926393733b058a345b1a288ebca9f2852281129 Mon Sep 17 00:00:00 2001 From: Lluis Gifre <lluis.gifre@cttc.es> Date: Tue, 2 Aug 2022 14:47:24 +0000 Subject: [PATCH] Slice component: - refined create/update of slices - implemented delete of slices --- src/slice/requirements.in | 1 + src/slice/service/SliceServiceServicerImpl.py | 134 ++++++++++++------ 2 files changed, 89 insertions(+), 46 deletions(-) diff --git a/src/slice/requirements.in b/src/slice/requirements.in index e69de29bb..cbf07ecb7 100644 --- a/src/slice/requirements.in +++ b/src/slice/requirements.in @@ -0,0 +1 @@ +deepdiff==5.8.* diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py index 275a20114..8c70b5e5a 100644 --- a/src/slice/service/SliceServiceServicerImpl.py +++ b/src/slice/service/SliceServiceServicerImpl.py @@ -12,11 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, json, logging +import grpc, logging, deepdiff from common.proto.context_pb2 import ( - ConfigActionEnum, Empty, Service, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum) + Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum) from common.proto.slice_pb2_grpc import SliceServiceServicer from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method +from common.tools.grpc.ConfigRules import copy_config_rules +from common.tools.grpc.Constraints import copy_constraints +from common.tools.grpc.EndPointIds import copy_endpoint_ids +from common.tools.grpc.ServiceIds import update_service_ids +from common.tools.grpc.Tools import grpc_message_to_json from context.client.ContextClient import ContextClient from interdomain.client.InterdomainClient import InterdomainClient from service.client.ServiceClient import ServiceClient @@ -34,66 +39,69 @@ class SliceServiceServicerImpl(SliceServiceServicer): def create_update(self, request : Slice) -> SliceId: context_client = ContextClient() - - slice_id = context_client.SetSlice(request) - if len(request.slice_endpoint_ids) != 2: return slice_id + try: + _slice = context_client.GetSlice(request.slice_id) + json_current_slice = grpc_message_to_json(_slice) + except: + json_current_slice = {} + slice_request = Slice() + slice_request.slice_id.CopyFrom(request.slice_id) + slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED + context_client.SetSlice(slice_request) + _slice = context_client.GetSlice(request.slice_id) + slice_request = Slice() + slice_request.CopyFrom(_slice) + + LOGGER.info('json_current_slice = {:s}'.format(str(json_current_slice))) + json_updated_slice = grpc_message_to_json(request) + LOGGER.info('json_updated_slice = {:s}'.format(str(json_updated_slice))) + changes = deepdiff.DeepDiff(json_current_slice, json_updated_slice) + LOGGER.info('changes = {:s}'.format(str(changes))) domains = set() for slice_endpoint_id in request.slice_endpoint_ids: device_uuid = slice_endpoint_id.device_id.device_uuid.uuid - domains.add(device_uuid.split('@')[1]) + device_parts = device_uuid.split('@') + domain_uuid = '' if len(device_parts) == 1 else device_parts[1] + domains.add(domain_uuid) + LOGGER.info('domains = {:s}'.format(str(domains))) + is_multi_domain = len(domains) > 1 + LOGGER.info('is_multi_domain = {:s}'.format(str(is_multi_domain))) - is_multi_domain = len(domains) == 2 if is_multi_domain: interdomain_client = InterdomainClient() slice_id = interdomain_client.RequestSlice(request) else: - # pylint: disable=no-member - service_request = Service() - service_request.service_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid - service_request.service_id.service_uuid.uuid = request.slice_id.slice_uuid.uuid - service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM - service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED + service_id = ServiceId() + context_uuid = service_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid + slice_uuid = service_uuid = service_id.service_uuid.uuid = request.slice_id.slice_uuid.uuid service_client = ServiceClient() - service_reply = service_client.CreateService(service_request) - if service_reply != service_request.service_id: # pylint: disable=no-member - raise Exception('Service creation failed. Wrong Service Id was returned') - - config_rule = service_request.service_config.config_rules.add() - config_rule.action = ConfigActionEnum.CONFIGACTION_SET - config_rule.custom.resource_key = '/settings' - config_rule.custom.resource_value = json.dumps( - {'mtu': 1512, 'address_families': ['IPV4'], 'bgp_as': 65000, 'bgp_route_target': '65000:333'}, - sort_keys=True) - - for slice_endpoint_id in request.slice_endpoint_ids: - device_uuid = slice_endpoint_id.device_id.device_uuid.uuid - endpoint_uuid = slice_endpoint_id.endpoint_uuid.uuid - - endpoint_id = service_request.service_endpoint_ids.add() - endpoint_id.device_id.device_uuid.uuid = device_uuid - endpoint_id.endpoint_uuid.uuid = endpoint_uuid - - config_rule = service_request.service_config.config_rules.add() - config_rule.action = ConfigActionEnum.CONFIGACTION_SET - config_rule.custom.resource_key = '/device[{:s}]/endpoint[{:s}]/settings'.format( - device_uuid, endpoint_uuid) - config_rule.custom.resource_value = json.dumps( - {'router_id': '0.0.0.0', 'route_distinguisher': '0:0', 'sub_interface_index': 0, 'vlan_id': 0, - 'address_ip': '0.0.0.0', 'address_prefix': 0}, - sort_keys=True) + try: + _service = context_client.GetService(service_id) + except: + service_request = Service() + service_request.service_id.CopyFrom(service_id) + service_request.service_type = ServiceTypeEnum.SERVICETYPE_L2NM + service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED + service_reply = service_client.CreateService(service_request) + if service_reply != service_request.service_id: # pylint: disable=no-member + raise Exception('Service creation failed. Wrong Service Id was returned') + _service = context_client.GetService(service_id) + service_request = Service() + service_request.CopyFrom(_service) + + copy_endpoint_ids(request.slice_endpoint_ids, service_request.service_endpoint_ids) + copy_constraints(request.slice_constraints, service_request.service_constraints) + copy_config_rules(request.slice_config.config_rules, service_request.service_config.config_rules) service_reply = service_client.UpdateService(service_request) if service_reply != service_request.service_id: # pylint: disable=no-member raise Exception('Service update failed. Wrong Service Id was returned') - reply = Slice() - reply.CopyFrom(request) - slice_service_id = reply.slice_service_ids.add() - slice_service_id.CopyFrom(service_reply) - context_client.SetSlice(reply) - slice_id = reply.slice_id + update_service_ids(slice_request.slice_service_ids, context_uuid, service_uuid) + context_client.SetSlice(slice_request) + slice_id = slice_request.slice_id slice_ = context_client.GetSlice(slice_id) slice_active = Slice() @@ -132,4 +140,38 @@ class SliceServiceServicerImpl(SliceServiceServicer): @safe_and_metered_rpc_method(METRICS, LOGGER) def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty: + context_client = ContextClient() + try: + _slice = context_client.GetSlice(request.slice_id) + except: + return Empty() + + domains = set() + for slice_endpoint_id in _slice.slice_endpoint_ids: + device_uuid = slice_endpoint_id.device_id.device_uuid.uuid + device_parts = device_uuid.split('@') + domain_uuid = '' if len(device_parts) == 1 else device_parts[1] + domains.add(domain_uuid) + LOGGER.info('domains = {:s}'.format(str(domains))) + is_multi_domain = len(domains) > 1 + LOGGER.info('is_multi_domain = {:s}'.format(str(is_multi_domain))) + + if is_multi_domain: + interdomain_client = InterdomainClient() + #slice_id = interdomain_client.DeleteSlice(request) + raise NotImplementedError('Delete inter-domain slice') + else: + current_slice = Slice() + current_slice.CopyFrom(_slice) + current_slice.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_DEINIT + context_client.SetSlice(current_slice) + + service_client = ServiceClient() + for service_id in _slice.slice_service_ids: + try: + service_client.DeleteService(service_id) + except: + pass + + context_client.RemoveSlice(request.slice_id) return Empty() -- GitLab