diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml index 171394f7c43b2447e898902c78d5276fe1bcbc7c..46c7557d9178d1bb2bc36eda13a088606f56cede 100644 --- a/manifests/deviceservice.yaml +++ b/manifests/deviceservice.yaml @@ -34,7 +34,7 @@ spec: - containerPort: 2020 env: - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:2020"] diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index 75832b94fa2a6ba97617641e7b249157508614bf..efe43fe229a7f7ba862b10a04d44c6e9de06b5fb 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -34,7 +34,7 @@ spec: - containerPort: 3030 env: - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:3030"] diff --git a/my_deploy.sh b/my_deploy.sh index 48df05c34440ff5b10a9c54d4aa47bb01ad4d9aa..8291ab29b7ae078241396d415ea1ac53f38fd257 100644 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -1,5 +1,14 @@ export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" -export TFS_COMPONENTS="context device automation service compute monitoring webui l3_attackmitigator l3_centralizedattackdetector" + +# Set the list of components, separated by spaces, you want to build images for, and deploy. +# Supported components are: +# context device automation policy service compute monitoring webui +# interdomain slice pathcomp dlt +# dbscanserving opticalattackmitigator opticalattackdetector +# l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector +export TFS_COMPONENTS="context device automation pathcomp service slice compute monitoring webui l3_attackmitigator l3_centralizedattackdetector" + +# Set the tag you want to use for your images. export TFS_IMAGE_TAG="dev" export TFS_K8S_NAMESPACE="tfs" export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" diff --git a/src/compute/service/__main__.py b/src/compute/service/__main__.py index 345b2fdd6950ecda802e8bd1c86e1421b5c60d84..e80681e177f0f0def3dbe75d76e7e65ceaca1e87 100644 --- a/src/compute/service/__main__.py +++ b/src/compute/service/__main__.py @@ -39,6 +39,8 @@ def main(): wait_for_environment_variables([ get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST ), get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_HOST ), + get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC), ]) signal.signal(signal.SIGINT, signal_handler) diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py index daa9f4fe3a170874fcbb58d875626e3009a95d3c..45724e968c95e5e66c7ff398cc61f7ea9dc3cbf0 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py @@ -21,46 +21,47 @@ DEFAULT_BGP_ROUTE_TARGET = '{:d}:{:d}'.format(DEFAULT_BGP_AS, 333) # Bearer mappings: # device_uuid:endpoint_uuid => ( -# device_uuid, endpoint_uuid, router_id, route_distinguisher, sub_if_index, address_ip, address_prefix) +# device_uuid, endpoint_uuid, router_id, route_dist, sub_if_index, +# address_ip, address_prefix, remote_router, circuit_id) + BEARER_MAPPINGS = { # OFC'22 - #'R1-EMU:13/2/1': ('R1-EMU', '13/2/1', '10.10.10.1', '65000:100', 400, '3.3.2.1', 24), - #'R2-EMU:13/2/1': ('R2-EMU', '13/2/1', '12.12.12.1', '65000:120', 450, '3.4.2.1', 24), - #'R3-EMU:13/2/1': ('R3-EMU', '13/2/1', '20.20.20.1', '65000:200', 500, '3.3.1.1', 24), - #'R4-EMU:13/2/1': ('R4-EMU', '13/2/1', '22.22.22.1', '65000:220', 550, '3.4.1.1', 24), + 'R1-EMU:13/1/2': ('R1-EMU', '13/1/2', '10.10.10.1', '65000:100', 400, '3.3.2.1', 24, None, None), + 'R2-EMU:13/1/2': ('R2-EMU', '13/1/2', '12.12.12.1', '65000:120', 450, '3.4.2.1', 24, None, None), + 'R3-EMU:13/1/2': ('R3-EMU', '13/1/2', '20.20.20.1', '65000:200', 500, '3.3.1.1', 24, None, None), + 'R4-EMU:13/1/2': ('R4-EMU', '13/1/2', '22.22.22.1', '65000:220', 550, '3.4.1.1', 24, None, None), # OECC/PSC'22 - domain 1 - #'R1@D1:3/1': ('R1@D1', '3/1', '10.0.1.1', '65001:101', 100, '1.1.3.1', 24), - #'R1@D1:3/2': ('R1@D1', '3/2', '10.0.1.1', '65001:101', 100, '1.1.3.2', 24), - #'R1@D1:3/3': ('R1@D1', '3/3', '10.0.1.1', '65001:101', 100, '1.1.3.3', 24), - #'R2@D1:3/1': ('R2@D1', '3/1', '10.0.1.2', '65001:102', 100, '1.2.3.1', 24), - #'R2@D1:3/2': ('R2@D1', '3/2', '10.0.1.2', '65001:102', 100, '1.2.3.2', 24), - #'R2@D1:3/3': ('R2@D1', '3/3', '10.0.1.2', '65001:102', 100, '1.2.3.3', 24), - #'R3@D1:3/1': ('R3@D1', '3/1', '10.0.1.3', '65001:103', 100, '1.3.3.1', 24), - #'R3@D1:3/2': ('R3@D1', '3/2', '10.0.1.3', '65001:103', 100, '1.3.3.2', 24), - #'R3@D1:3/3': ('R3@D1', '3/3', '10.0.1.3', '65001:103', 100, '1.3.3.3', 24), - #'R4@D1:3/1': ('R4@D1', '3/1', '10.0.1.4', '65001:104', 100, '1.4.3.1', 24), - #'R4@D1:3/2': ('R4@D1', '3/2', '10.0.1.4', '65001:104', 100, '1.4.3.2', 24), - #'R4@D1:3/3': ('R4@D1', '3/3', '10.0.1.4', '65001:104', 100, '1.4.3.3', 24), + 'R1@D1:3/1' : ('R1@D1', '3/1', '10.0.1.1', '65001:101', 100, '1.1.3.1', 24, None, None), + 'R1@D1:3/2' : ('R1@D1', '3/2', '10.0.1.1', '65001:101', 100, '1.1.3.2', 24, None, None), + 'R1@D1:3/3' : ('R1@D1', '3/3', '10.0.1.1', '65001:101', 100, '1.1.3.3', 24, None, None), + 'R2@D1:3/1' : ('R2@D1', '3/1', '10.0.1.2', '65001:102', 100, '1.2.3.1', 24, None, None), + 'R2@D1:3/2' : ('R2@D1', '3/2', '10.0.1.2', '65001:102', 100, '1.2.3.2', 24, None, None), + 'R2@D1:3/3' : ('R2@D1', '3/3', '10.0.1.2', '65001:102', 100, '1.2.3.3', 24, None, None), + 'R3@D1:3/1' : ('R3@D1', '3/1', '10.0.1.3', '65001:103', 100, '1.3.3.1', 24, None, None), + 'R3@D1:3/2' : ('R3@D1', '3/2', '10.0.1.3', '65001:103', 100, '1.3.3.2', 24, None, None), + 'R3@D1:3/3' : ('R3@D1', '3/3', '10.0.1.3', '65001:103', 100, '1.3.3.3', 24, None, None), + 'R4@D1:3/1' : ('R4@D1', '3/1', '10.0.1.4', '65001:104', 100, '1.4.3.1', 24, None, None), + 'R4@D1:3/2' : ('R4@D1', '3/2', '10.0.1.4', '65001:104', 100, '1.4.3.2', 24, None, None), + 'R4@D1:3/3' : ('R4@D1', '3/3', '10.0.1.4', '65001:104', 100, '1.4.3.3', 24, None, None), # OECC/PSC'22 - domain 2 - #'R1@D2:3/1': ('R1@D2', '3/1', '10.0.2.1', '65002:101', 100, '2.1.3.1', 24), - #'R1@D2:3/2': ('R1@D2', '3/2', '10.0.2.1', '65002:101', 100, '2.1.3.2', 24), - #'R1@D2:3/3': ('R1@D2', '3/3', '10.0.2.1', '65002:101', 100, '2.1.3.3', 24), - #'R2@D2:3/1': ('R2@D2', '3/1', '10.0.2.2', '65002:102', 100, '2.2.3.1', 24), - #'R2@D2:3/2': ('R2@D2', '3/2', '10.0.2.2', '65002:102', 100, '2.2.3.2', 24), - #'R2@D2:3/3': ('R2@D2', '3/3', '10.0.2.2', '65002:102', 100, '2.2.3.3', 24), - #'R3@D2:3/1': ('R3@D2', '3/1', '10.0.2.3', '65002:103', 100, '2.3.3.1', 24), - #'R3@D2:3/2': ('R3@D2', '3/2', '10.0.2.3', '65002:103', 100, '2.3.3.2', 24), - #'R3@D2:3/3': ('R3@D2', '3/3', '10.0.2.3', '65002:103', 100, '2.3.3.3', 24), - #'R4@D2:3/1': ('R4@D2', '3/1', '10.0.2.4', '65002:104', 100, '2.4.3.1', 24), - #'R4@D2:3/2': ('R4@D2', '3/2', '10.0.2.4', '65002:104', 100, '2.4.3.2', 24), - #'R4@D2:3/3': ('R4@D2', '3/3', '10.0.2.4', '65002:104', 100, '2.4.3.3', 24), + 'R1@D2:3/1' : ('R1@D2', '3/1', '10.0.2.1', '65002:101', 100, '2.1.3.1', 24, None, None), + 'R1@D2:3/2' : ('R1@D2', '3/2', '10.0.2.1', '65002:101', 100, '2.1.3.2', 24, None, None), + 'R1@D2:3/3' : ('R1@D2', '3/3', '10.0.2.1', '65002:101', 100, '2.1.3.3', 24, None, None), + 'R2@D2:3/1' : ('R2@D2', '3/1', '10.0.2.2', '65002:102', 100, '2.2.3.1', 24, None, None), + 'R2@D2:3/2' : ('R2@D2', '3/2', '10.0.2.2', '65002:102', 100, '2.2.3.2', 24, None, None), + 'R2@D2:3/3' : ('R2@D2', '3/3', '10.0.2.2', '65002:102', 100, '2.2.3.3', 24, None, None), + 'R3@D2:3/1' : ('R3@D2', '3/1', '10.0.2.3', '65002:103', 100, '2.3.3.1', 24, None, None), + 'R3@D2:3/2' : ('R3@D2', '3/2', '10.0.2.3', '65002:103', 100, '2.3.3.2', 24, None, None), + 'R3@D2:3/3' : ('R3@D2', '3/3', '10.0.2.3', '65002:103', 100, '2.3.3.3', 24, None, None), + 'R4@D2:3/1' : ('R4@D2', '3/1', '10.0.2.4', '65002:104', 100, '2.4.3.1', 24, None, None), + 'R4@D2:3/2' : ('R4@D2', '3/2', '10.0.2.4', '65002:104', 100, '2.4.3.2', 24, None, None), + 'R4@D2:3/3' : ('R4@D2', '3/3', '10.0.2.4', '65002:104', 100, '2.4.3.3', 24, None, None), # ECOC'22 - # bearer_ref => device_uuid, endpoint_uuid, sub_if_index, router_id, remote_router, circuit_id - 'DC1-GW:CS1-GW1': ('CS1-GW1', '10/1', 0, '5.5.1.1', '5.5.2.1', 111), - 'DC1-GW:CS1-GW2': ('CS1-GW2', '10/1', 0, '5.5.1.2', '5.5.2.2', 222), - 'DC2-GW:CS2-GW1': ('CS2-GW1', '10/1', 0, '5.5.2.1', '5.5.1.1', 111), - 'DC2-GW:CS2-GW2': ('CS2-GW2', '10/1', 0, '5.5.2.2', '5.5.1.2', 222), + 'DC1-GW:CS1-GW1': ('CS1-GW1', '10/1', '5.5.1.1', None, 0, None, None, '5.5.2.1', 111), + 'DC1-GW:CS1-GW2': ('CS1-GW2', '10/1', '5.5.1.2', None, 0, None, None, '5.5.2.2', 222), + 'DC2-GW:CS2-GW1': ('CS2-GW1', '10/1', '5.5.2.1', None, 0, None, None, '5.5.1.1', 111), + 'DC2-GW:CS2-GW2': ('CS2-GW2', '10/1', '5.5.2.2', None, 0, None, None, '5.5.1.2', 222), } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py index 224ebf094243fccf56367c14a15831edcc975f07..7e050289f19b93dc710185c2b29b326bbfd156d2 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py @@ -16,13 +16,11 @@ import logging from flask import request from flask.json import jsonify from flask_restful import Resource -from common.Constants import DEFAULT_CONTEXT_UUID -from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, SliceStatusEnum +from common.proto.context_pb2 import SliceStatusEnum from context.client.ContextClient import ContextClient -from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient from .tools.Authentication import HTTP_AUTH -from .tools.ContextMethods import get_service, get_slice +from .tools.ContextMethods import get_slice from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR LOGGER = logging.getLogger(__name__) @@ -37,26 +35,16 @@ class L2VPN_Service(Resource): context_client = ContextClient() target = get_slice(context_client, vpn_id) - if target is not None: - if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member - raise Exception('Slice retrieval failed. Wrong Slice Id was returned') - slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE - slice_status = target.slice_status.slice_status # pylint: disable=no-member - response = jsonify({}) - response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT - return response + if target is None: + raise Exception('VPN({:s}) not found in database'.format(str(vpn_id))) - target = get_service(context_client, vpn_id) - if target is not None: - if target.service_id.service_uuid.uuid != vpn_id: # pylint: disable=no-member - raise Exception('Service retrieval failed. Wrong Service Id was returned') - service_ready_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE - service_status = target.service_status.service_status # pylint: disable=no-member - response = jsonify({}) - response.status_code = HTTP_OK if service_status == service_ready_status else HTTP_GATEWAYTIMEOUT - return response + if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member + raise Exception('Slice retrieval failed. Wrong Slice Id was returned') - raise Exception('VPN({:s}) not found in database'.format(str(vpn_id))) + slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE + slice_status = target.slice_status.slice_status # pylint: disable=no-member + response = jsonify({}) + response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT except Exception as e: # pylint: disable=broad-except LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(vpn_id))) response = jsonify({'error': str(e)}) @@ -72,29 +60,15 @@ class L2VPN_Service(Resource): context_client = ContextClient() target = get_slice(context_client, vpn_id) - if target is not None: + if target is None: + LOGGER.warning('VPN({:s}) not found in database. Nothing done.'.format(str(vpn_id))) + else: if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member raise Exception('Slice retrieval failed. Wrong Slice Id was returned') slice_client = SliceClient() slice_client.DeleteSlice(target.slice_id) - response = jsonify({}) - response.status_code = HTTP_NOCONTENT - return response - - target = get_service(context_client, vpn_id) - if target is not None: - if target.service_id.service_uuid.uuid != vpn_id: # pylint: disable=no-member - raise Exception('Service retrieval failed. Wrong Service Id was returned') - service_client = ServiceClient() - service_client.DeleteService(target.service_id) - response = jsonify({}) - response.status_code = HTTP_NOCONTENT - return response - - LOGGER.warning('VPN({:s}) not found in database. Nothing done.'.format(str(vpn_id))) response = jsonify({}) response.status_code = HTTP_NOCONTENT - return response except Exception as e: # pylint: disable=broad-except LOGGER.exception('Something went wrong Deleting VPN({:s})'.format(str(vpn_id))) response = jsonify({'error': str(e)}) diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py index 50b1c2abbb2b49ed9b8cb84a3a0933df55d3bd8f..f27d852f017a08cb8b854cc19568280b9de14470 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py @@ -19,8 +19,7 @@ from flask.json import jsonify from flask_restful import Resource from werkzeug.exceptions import UnsupportedMediaType from common.Constants import DEFAULT_CONTEXT_UUID -from common.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum, SliceStatusEnum, Slice -from service.client.ServiceClient import ServiceClient +from common.proto.context_pb2 import SliceStatusEnum, Slice from slice.client.SliceClient import SliceClient from .schemas.vpn_service import SCHEMA_VPN_SERVICE from .tools.Authentication import HTTP_AUTH @@ -44,34 +43,16 @@ class L2VPN_Services(Resource): vpn_services : List[Dict] = request_data['ietf-l2vpn-svc:vpn-service'] for vpn_service in vpn_services: try: - # By now, assume requests from OSM always need transport slices - # TODO: think how to differentiate - #vpn_service_type = vpn_service['vpn-svc-type'] - vpn_service_type = 'vpls' - - if vpn_service_type == 'vpws': - # pylint: disable=no-member - service_request = Service() - service_request.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID - service_request.service_id.service_uuid.uuid = vpn_service['vpn-id'] - service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM - service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED - - 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') - elif vpn_service_type == 'vpls': - # pylint: disable=no-member - slice_request = Slice() - slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID - slice_request.slice_id.slice_uuid.uuid = vpn_service['vpn-id'] - slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED - - slice_client = SliceClient() - slice_reply = slice_client.CreateSlice(slice_request) - if slice_reply != slice_request.slice_id: # pylint: disable=no-member - raise Exception('Slice creation failed. Wrong Slice Id was returned') + # pylint: disable=no-member + slice_request = Slice() + slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID + slice_request.slice_id.slice_uuid.uuid = vpn_service['vpn-id'] + slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED + + slice_client = SliceClient() + slice_reply = slice_client.CreateSlice(slice_request) + if slice_reply != slice_request.slice_id: # pylint: disable=no-member + raise Exception('Slice creation failed. Wrong Slice Id was returned') response = jsonify({}) response.status_code = HTTP_CREATED diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py index 0dea176972ab06156dbcee875e7b857a0b4f8c95..83691ff9ba604bdafff87134414319385472451d 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py @@ -13,13 +13,13 @@ # limitations under the License. import logging -from typing import Dict, Optional, Union +from typing import Dict, Optional from flask import request from flask.json import jsonify from flask.wrappers import Response from flask_restful import Resource from werkzeug.exceptions import UnsupportedMediaType -from common.proto.context_pb2 import Service, Slice +from common.proto.context_pb2 import Slice from common.tools.grpc.ConfigRules import update_config_rule_custom from common.tools.grpc.Constraints import ( update_constraint_custom, update_constraint_endpoint_location, update_constraint_endpoint_priority, @@ -27,11 +27,10 @@ from common.tools.grpc.Constraints import ( from common.tools.grpc.EndPointIds import update_endpoint_ids from common.tools.grpc.Tools import grpc_message_to_json_string from context.client.ContextClient import ContextClient -from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient from .schemas.site_network_access import SCHEMA_SITE_NETWORK_ACCESS from .tools.Authentication import HTTP_AUTH -from .tools.ContextMethods import get_service, get_slice +from .tools.ContextMethods import get_slice from .tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR from .tools.Validator import validate_message from .Constants import ( @@ -39,7 +38,7 @@ from .Constants import ( LOGGER = logging.getLogger(__name__) -def process_site_network_access(context_client : ContextClient, site_id : str, site_network_access : Dict) -> Service: +def process_site_network_access(context_client : ContextClient, site_id : str, site_network_access : Dict) -> Slice: vpn_id = site_network_access['vpn-attachment']['vpn-id'] encapsulation_type = site_network_access['connection']['encapsulation-type'] cvlan_id = site_network_access['connection']['tagged-interface'][encapsulation_type]['cvlan-id'] @@ -65,34 +64,26 @@ def process_site_network_access(context_client : ContextClient, site_id : str, s if mapping is None: msg = 'Specified Bearer({:s}) is not configured.' raise Exception(msg.format(str(bearer_reference))) - #device_uuid,endpoint_uuid,router_id,route_dist,sub_if_index,address_ip,address_prefix = mapping - route_dist, address_ip, address_prefix = None, None, None - device_uuid, endpoint_uuid, sub_if_index, router_id, remote_router, circuit_id = mapping + ( + device_uuid, endpoint_uuid, router_id, route_dist, sub_if_index, + address_ip, address_prefix, remote_router, circuit_id + ) = mapping - target : Union[Service, Slice, None] = None - if target is None: target = get_slice (context_client, vpn_id) - if target is None: target = get_service(context_client, vpn_id) + target = get_slice(context_client, vpn_id) if target is None: raise Exception('VPN({:s}) not found in database'.format(str(vpn_id))) - if isinstance(target, Service): - endpoint_ids = target.service_endpoint_ids # pylint: disable=no-member - config_rules = target.service_config.config_rules # pylint: disable=no-member - constraints = target.service_constraints # pylint: disable=no-member - elif isinstance(target, Slice): - endpoint_ids = target.slice_endpoint_ids # pylint: disable=no-member - config_rules = target.slice_config.config_rules # pylint: disable=no-member - constraints = target.slice_constraints # pylint: disable=no-member - else: - raise Exception('Target({:s}) not supported'.format(str(target.__class__.__name__))) + endpoint_ids = target.slice_endpoint_ids # pylint: disable=no-member + config_rules = target.slice_config.config_rules # pylint: disable=no-member + constraints = target.slice_constraints # pylint: disable=no-member endpoint_id = update_endpoint_ids(endpoint_ids, device_uuid, endpoint_uuid) service_settings_key = '/settings' update_config_rule_custom(config_rules, service_settings_key, { 'mtu' : (DEFAULT_MTU, True), - #'address_families': (DEFAULT_ADDRESS_FAMILIES, True), - #'bgp_as' : (DEFAULT_BGP_AS, True), - #'bgp_route_target': (DEFAULT_BGP_ROUTE_TARGET, True), + 'address_families': (DEFAULT_ADDRESS_FAMILIES, True), + 'bgp_as' : (DEFAULT_BGP_AS, True), + 'bgp_route_target': (DEFAULT_BGP_ROUTE_TARGET, True), }) endpoint_settings_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid) @@ -129,8 +120,7 @@ def process_site_network_access(context_client : ContextClient, site_id : str, s return target def process_list_site_network_access( - context_client : ContextClient, service_client : ServiceClient, slice_client : SliceClient, site_id : str, - request_data : Dict + context_client : ContextClient, slice_client : SliceClient, site_id : str, request_data : Dict ) -> Response: LOGGER.debug('Request: {:s}'.format(str(request_data))) @@ -141,16 +131,9 @@ def process_list_site_network_access( sna_request = process_site_network_access(context_client, site_id, site_network_access) LOGGER.debug('sna_request = {:s}'.format(grpc_message_to_json_string(sna_request))) try: - if isinstance(sna_request, Service): - sna_reply = service_client.UpdateService(sna_request) - if sna_reply != sna_request.service_id: # pylint: disable=no-member - raise Exception('Service update failed. Wrong Service Id was returned') - elif isinstance(sna_request, Slice): - sna_reply = slice_client.UpdateSlice(sna_request) - if sna_reply != sna_request.slice_id: # pylint: disable=no-member - raise Exception('Slice update failed. Wrong Slice Id was returned') - else: - raise NotImplementedError('Support for Class({:s}) not implemented'.format(str(type(sna_request)))) + sna_reply = slice_client.UpdateSlice(sna_request) + if sna_reply != sna_request.slice_id: # pylint: disable=no-member + raise Exception('Slice update failed. Wrong Slice Id was returned') except Exception as e: # pylint: disable=broad-except msg = 'Something went wrong Updating VPN {:s}' LOGGER.exception(msg.format(grpc_message_to_json_string(sna_request))) @@ -166,15 +149,13 @@ class L2VPN_SiteNetworkAccesses(Resource): if not request.is_json: raise UnsupportedMediaType('JSON payload is required') LOGGER.debug('Site_Id: {:s}'.format(str(site_id))) context_client = ContextClient() - service_client = ServiceClient() slice_client = SliceClient() - return process_list_site_network_access(context_client, service_client, slice_client, site_id, request.json) + return process_list_site_network_access(context_client, slice_client, site_id, request.json) @HTTP_AUTH.login_required def put(self, site_id : str): if not request.is_json: raise UnsupportedMediaType('JSON payload is required') LOGGER.debug('Site_Id: {:s}'.format(str(site_id))) context_client = ContextClient() - service_client = ServiceClient() slice_client = SliceClient() - return process_list_site_network_access(context_client, service_client, slice_client, site_id, request.json) + return process_list_site_network_access(context_client, slice_client, site_id, request.json) diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py index 7745043318a46649b26d24ae99abaed0577d6171..c1977cedb9b341fbb767a5fb8c829cd5f633884c 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py @@ -72,6 +72,10 @@ def compose_constraint(constraint : Constraint) -> Dict: LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint)) return None constraint_type = constraint.custom.constraint_type + if constraint_type in {'diversity'}: + str_constraint = grpc_message_to_json_string(constraint) + LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint)) + return None constraint_value = constraint.custom.constraint_value return {'constraint_type': constraint_type, 'constraint_value': constraint_value} @@ -129,6 +133,12 @@ def compose_service(grpc_service : Service) -> Dict: for service_constraint in grpc_service.service_constraints ])) + constraint_types = {constraint['constraint_type'] for constraint in constraints} + if 'bandwidth[gbps]' not in constraint_types: + constraints.append({'constraint_type': 'bandwidth[gbps]', 'constraint_value': '20.0'}) + if 'latency[ms]' not in constraint_types: + constraints.append({'constraint_type': 'latency[ms]', 'constraint_value': '20.0'}) + return { 'serviceId': service_id, 'serviceType': service_type, diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py index 30c2310b0136674ce3fa23c26b3c0812bbf3448a..53875f0e6ae7c8e3e7d5ac9dad7501a2136844c4 100644 --- a/src/slice/service/SliceServiceServicerImpl.py +++ b/src/slice/service/SliceServiceServicerImpl.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging #, deepdiff +import grpc, json, logging #, deepdiff from common.proto.context_pb2 import ( Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum) from common.proto.slice_pb2_grpc import SliceServiceServicer @@ -21,7 +21,7 @@ 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 common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string from context.client.ContextClient import ContextClient from interdomain.client.InterdomainClient import InterdomainClient from service.client.ServiceClient import ServiceClient @@ -41,9 +41,9 @@ class SliceServiceServicerImpl(SliceServiceServicer): context_client = ContextClient() try: _slice = context_client.GetSlice(request.slice_id) - json_current_slice = grpc_message_to_json(_slice) + #json_current_slice = grpc_message_to_json(_slice) except: - json_current_slice = {} + #json_current_slice = {} slice_request = Slice() slice_request.slice_id.CopyFrom(request.slice_id) slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED @@ -82,7 +82,7 @@ class SliceServiceServicerImpl(SliceServiceServicer): except: service_request = Service() service_request.service_id.CopyFrom(service_id) - service_request.service_type = ServiceTypeEnum.SERVICETYPE_L2NM + service_request.service_type = ServiceTypeEnum.SERVICETYPE_UNKNOWN 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 @@ -95,6 +95,34 @@ class SliceServiceServicerImpl(SliceServiceServicer): copy_constraints(request.slice_constraints, service_request.service_constraints) copy_config_rules(request.slice_config.config_rules, service_request.service_config.config_rules) + service_request.service_type = ServiceTypeEnum.SERVICETYPE_UNKNOWN + for config_rule in request.slice_config.config_rules: + LOGGER.info('config_rule: {:s}'.format(grpc_message_to_json_string(config_rule))) + config_rule_kind = config_rule.WhichOneof('config_rule') + LOGGER.info('config_rule_kind: {:s}'.format(str(config_rule_kind))) + if config_rule_kind != 'custom': continue + custom = config_rule.custom + resource_key = custom.resource_key + LOGGER.info('resource_key: {:s}'.format(str(resource_key))) + + # TODO: parse resource key with regular expression, e.g.: + # m = re.match('\/device\[[^\]]\]\/endpoint\[[^\]]\]\/settings', s) + if not resource_key.startswith('/device'): continue + if not resource_key.endswith('/settings'): continue + + resource_value = json.loads(custom.resource_value) + LOGGER.info('resource_value: {:s}'.format(str(resource_value))) + + if service_request.service_type == ServiceTypeEnum.SERVICETYPE_UNKNOWN: + if (resource_value.get('address_ip') is not None and \ + resource_value.get('address_prefix') is not None): + service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM + LOGGER.info('is L3') + else: + service_request.service_type = ServiceTypeEnum.SERVICETYPE_L2NM + LOGGER.info('is L2') + break + 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') diff --git a/src/tests/ofc22/run_test_01_bootstrap.sh b/src/tests/ofc22/run_test_01_bootstrap.sh index ef23c28eb0af1158bd31dd9f35f330e7225bdd07..bb740707321b24fc960299f2eac91cc2d9775b64 100755 --- a/src/tests/ofc22/run_test_01_bootstrap.sh +++ b/src/tests/ofc22/run_test_01_bootstrap.sh @@ -17,4 +17,5 @@ # - my_deploy.sh # - tfs_runtime_env_vars.sh +source tfs_runtime_env_vars.sh pytest --verbose src/tests/ofc22/tests/test_functional_bootstrap.py diff --git a/src/tests/ofc22/run_test_02_create_service.sh b/src/tests/ofc22/run_test_02_create_service.sh index 20fc3db65dd57ae8697253443050b1767d9b77a1..8b6c8658df759bdcb777f83c6c7846d0ea7b48ed 100755 --- a/src/tests/ofc22/run_test_02_create_service.sh +++ b/src/tests/ofc22/run_test_02_create_service.sh @@ -13,4 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. +source tfs_runtime_env_vars.sh pytest --verbose src/tests/ofc22/tests/test_functional_create_service.py diff --git a/src/tests/ofc22/run_test_03_delete_service.sh b/src/tests/ofc22/run_test_03_delete_service.sh index 98073013d84e9d64e56dd9022ac163b6321ce389..51df41aee216e141b0d2e2f55a0398ecd9cdf35f 100755 --- a/src/tests/ofc22/run_test_03_delete_service.sh +++ b/src/tests/ofc22/run_test_03_delete_service.sh @@ -13,4 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. +source tfs_runtime_env_vars.sh pytest --verbose src/tests/ofc22/tests/test_functional_delete_service.py diff --git a/src/tests/ofc22/run_test_04_cleanup.sh b/src/tests/ofc22/run_test_04_cleanup.sh index f7c0aad8da0b0446d188ec1fad3f0fc0e7dc2b4a..2ba91684f9eb49075dd68877e54976f989811ae9 100755 --- a/src/tests/ofc22/run_test_04_cleanup.sh +++ b/src/tests/ofc22/run_test_04_cleanup.sh @@ -13,4 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. +source tfs_runtime_env_vars.sh pytest --verbose src/tests/ofc22/tests/test_functional_cleanup.py diff --git a/src/tests/ofc22/run_tests_and_coverage.sh b/src/tests/ofc22/run_tests_and_coverage.sh index fa5026db2310c8753d8e4476707ce46a38ecb0f2..bafc920c71a640d083497e1cd6ae025d0ea7cef5 100755 --- a/src/tests/ofc22/run_tests_and_coverage.sh +++ b/src/tests/ofc22/run_tests_and_coverage.sh @@ -29,6 +29,8 @@ rm -f $COVERAGEFILE # Force a flush of Context database kubectl --namespace $TFS_K8S_NAMESPACE exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL +source tfs_runtime_env_vars.sh + # Run functional tests and analyze code coverage at the same time coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ tests/ofc22/tests/test_functional_bootstrap.py