From ac066a01a6ce73d9eaba4c0ed61083d865747897 Mon Sep 17 00:00:00 2001 From: Ville Petteri Hallivuori <VHallivuori@infinera.com> Date: Mon, 8 Aug 2022 05:42:10 -0700 Subject: [PATCH] Pull request #2: vhallivu/XR_DRIVER_EMULATE_ENDPOINTS Merge in XRCA/teraflow from vhallivu/XR_DRIVER_EMULATE_ENDPOINTS to xr_development Squashed commit of the following: commit da5b46937d8f0dd87f535e3d736dc1d9e2043e94 Author: Ville Hallivuori <VHallivuori@infinera.com> Date: Mon Aug 8 15:21:16 2022 +0300 Updates to emulation commit b9d9e566f4622f85767c85b72494fbb33896de60 Author: Ville Hallivuori <VHallivuori@infinera.com> Date: Mon Aug 8 13:49:55 2022 +0300 Add XR constellation icon for topology commit 6d24a643f11ecb684043332500c2ee8b2768e900 Author: Ville Hallivuori <VHallivuori@infinera.com> Date: Mon Aug 8 12:56:16 2022 +0300 Improved XR service creation stubs commit 7d31fd2ecc67848368e2d0eddb616faa6115128d Author: Ville Hallivuori <VHallivuori@infinera.com> Date: Mon Aug 8 08:07:10 2022 +0300 Eulation for XrDriver endpoints --- README_INFINERA.md | 82 +++++++ src/common/tools/object_factory/Device.py | 13 +- src/device/service/drivers/__init__.py | 3 +- src/device/service/drivers/xr/XrDriver.py | 41 +++- src/device/service/drivers/xr/__init__.py | 8 +- .../java/eu/teraflow/policy/Serializer.java | 2 + .../service/service_handlers/__init__.py | 4 +- src/tests/ofc22/descriptors_emulated_xr.json | 33 +-- src/tests/ofc22/setup_test_env.sh | 9 + src/tests/ofc22/tests/ObjectsXr.py | 232 ++++++++++++++++++ .../test_functional_create_service_xr.py | 130 ++++++++++ .../topology_icons/xr-constellation.png | Bin 0 -> 37336 bytes 12 files changed, 523 insertions(+), 34 deletions(-) create mode 100644 README_INFINERA.md create mode 100755 src/tests/ofc22/setup_test_env.sh create mode 100644 src/tests/ofc22/tests/ObjectsXr.py create mode 100644 src/tests/ofc22/tests/test_functional_create_service_xr.py create mode 100644 src/webui/service/static/topology_icons/xr-constellation.png diff --git a/README_INFINERA.md b/README_INFINERA.md new file mode 100644 index 000000000..4d3c1a3f0 --- /dev/null +++ b/README_INFINERA.md @@ -0,0 +1,82 @@ +# Infinera Readme + +This file will be removed before uploading to origin. + +There are some instructions at https://gitlab.com/teraflow-h2020/controller/-/tree/develop/tutorial . They are not completely up to date and don't 100% work. + +Note that many of the scripts expect this and that K8s namespace being used, they are not consistent, so use manual kubectl commands where necessary. + +Infinera repo (cloned from upstream) is https://bitbucket.infinera.com/projects/XRCA/repos/teraflow/browse . The main development branch for us is xr-development (branched of origin/develop). + +## Preliminaries + +Kubernetes must be installed and configured. + +Note that if runninc MicroK8s (I would highly recommend it), then install also regular kubectl so that scripts work. That is, download the kubectl, and also export credidentials to standard location. + +```bash +# As a root +su - +cd /usr/local/bin +curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" +chmod 755 kubectl +exit + +# As your local user +cd ~/.kube +microk8s config > config +``` + +Local Docker registry is needed for build results. Use the following command to start local registry (docker will pull necessary images from Internet) + +```bash +docker run -d -p 32000:5000 --restart=always --name registry registry:2 +``` + +Setup mydeploy script outside the git repo. E.g. following will do. SOURCE IT ON ALL SHELLS. + +```bash +export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" + +export TFS_COMPONENTS="context device automation service compute monitoring webui" +export TFS_IMAGE_TAG="dev" +export TFS_K8S_NAMESPACE="tfs" +export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" +export TFS_GRAFANA_PASSWORD="admin123+" +``` + +Build is containerized, pytest used for setup is not. Teraflow has some third party venv suggestion in docs. However standard venv works. Create: + +```bash +python -m venv .venv +source .venv/bin/activate +./install_requirements.sh +``` + +SOURCE VENV ACTIVATE ON ANY SHELL USED FOR PYTHON RELATED WORK (e.g. pytest). + +Use apt-get to install any missing tools (e.g. jq is required). + +## Building + +Run deploy script to build in docker containers and then instantiate to configured K8s cluster. Deploy script must be sources for this to work! + +```bash +./deploy.sh +``` + +## Testing + +Upload descriptors_emulatex_xr.json via WEB UI to setup fake topology. + +Setup service by following commands in src directory. Kubernetes endpoins change on every build, so setup script is mandatory. + +```bash + source tests/ofc22/setup_test_env.sh + python -m pytest --verbose tests/ofc22/tests/test_functional_create_service_xr.py +``` + +Good logs to check are: + +* kubectl logs service/deviceservice --namespace tfs +* kubectl logs service/webuiservice --namespace tfs diff --git a/src/common/tools/object_factory/Device.py b/src/common/tools/object_factory/Device.py index 32baff9ae..0b597a77a 100644 --- a/src/common/tools/object_factory/Device.py +++ b/src/common/tools/object_factory/Device.py @@ -15,7 +15,7 @@ import copy from typing import Dict, List, Tuple from common.DeviceTypes import DeviceTypeEnum -from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum +from common.proto.context_pb2 import DEVICEDRIVER_XR, DeviceDriverEnum, DeviceOperationalStatusEnum from common.tools.object_factory.ConfigRule import json_config_rule_set DEVICE_DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED @@ -32,6 +32,9 @@ DEVICE_PR_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG] DEVICE_TAPI_TYPE = DeviceTypeEnum.OPTICAL_LINE_SYSTEM.value DEVICE_TAPI_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API] +DEVICE_XR_CONSTELLATION_TYPE = DeviceTypeEnum.XR_CONSTELLATION.value +DEVICE_XR_CONSTELLATION_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_XR] + # check which enum type and value assign to microwave device DEVICE_MICROWAVE_TYPE = DeviceTypeEnum.MICROVAWE_RADIO_SYSTEM.value DEVICE_MICROWAVE_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY] @@ -85,6 +88,14 @@ def json_device_tapi_disabled( return json_device( device_uuid, DEVICE_TAPI_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers) +def json_device_xr_constellation_disabled( + device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [], + drivers : List[Dict] = DEVICE_XR_CONSTELLATION_DRIVERS + ): + return json_device( + device_uuid, DEVICE_XR_CONSTELLATION_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers) + + def json_device_microwave_disabled( device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [], drivers : List[Dict] = DEVICE_MICROWAVE_DRIVERS diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index 4b67a77ea..e4f9c8d54 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -36,8 +36,7 @@ DRIVERS = [ FilterFieldEnum.DRIVER : [ ORM_DeviceDriverEnum.UNDEFINED, ORM_DeviceDriverEnum.OPENCONFIG, - ORM_DeviceDriverEnum.TRANSPORT_API, - ORM_DeviceDriverEnum.XR + ORM_DeviceDriverEnum.TRANSPORT_API ], } ]), diff --git a/src/device/service/drivers/xr/XrDriver.py b/src/device/service/drivers/xr/XrDriver.py index 8f40012a2..81898d7c7 100644 --- a/src/device/service/drivers/xr/XrDriver.py +++ b/src/device/service/drivers/xr/XrDriver.py @@ -33,6 +33,8 @@ class XrDriver(_Driver): self.__audience = settings["audience"] if "audience" in settings else "test" self.__client_id = settings["client_id"] if "client_id" in settings else "test" + self.__services = {} + # FIXME: remove LOGGER.info(f"FIXME!!! XrDriver, cm {address}:{port}, {settings=}"); @@ -76,28 +78,61 @@ class XrDriver(_Driver): with self.__lock: return [] + def fake_interface_names(self) -> List[str]: + interfaces = [] + # Using 4 as max leaf and lane to keep prints small during development + for lane in range(0,4): + interfaces.append(f"HUB-LANE-{lane:02}") + for leaf in range(1,5): + for lane in range(0,4): + interfaces.append(f"LEAF-{leaf:02}-LANE-{lane:02}") + return interfaces + def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: chk_type('resources', resource_keys, list) results = [] - # TODO + # TODO: Completely fake interface information until we get same info from CM + for ifname in self.fake_interface_names(): + results.append((f"/endpoints/endpoint[{ifname}]", {'uuid': ifname, 'type': 'optical', 'sample_types': {}})) return results + def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + LOGGER.info(f"FIXME!!! XrDriver, SetConfig {resources=}"); + + # Logged config seems like: + #[('/service[44ca3570-4e1a-49b5-8aab-06c92f239fab:optical]', '{"capacity_unit": "GHz", "capacity_value": 1, "direction": "UNIDIRECTIONAL", "input_sip": "HUB-LANE-01", "layer_protocol_name": "PHOTONIC_MEDIA", "layer_protocol_qualifier": "tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC", "output_sip": "LEAF-02-LANE-01", "uuid": "44ca3570-4e1a-49b5-8aab-06c92f239fab:optical"}')] results = [] if len(resources) == 0: return results - # TODO + # Temporary dummy version + for key, config in resources: + self.__services[key] = config + + # TODO: config to CM + # Ignore "direction=UNIDIRECITONAL", it seems that controller only creates one direction... + results.append(True) return results def DeleteConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + LOGGER.info(f"FIXME!!! XrDriver, DeleteConfig {resources=}"); + results = [] if len(resources) == 0: return results - #TODO + # Temporary dummy version + for key, config in resources: + if key in self.__services[key]: + del self.__services[key] + # TODO: Delete config from CM + results.append(True) + else: + results.append(False) + return results diff --git a/src/device/service/drivers/xr/__init__.py b/src/device/service/drivers/xr/__init__.py index 329bbc306..6c466ff98 100644 --- a/src/device/service/drivers/xr/__init__.py +++ b/src/device/service/drivers/xr/__init__.py @@ -15,13 +15,13 @@ from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES ALL_RESOURCE_KEYS = [ -# RESOURCE_ENDPOINTS, -# RESOURCE_INTERFACES, + RESOURCE_ENDPOINTS, + RESOURCE_INTERFACES, # RESOURCE_NETWORK_INSTANCES, ] RESOURCE_KEY_MAPPINGS = { -# RESOURCE_ENDPOINTS : 'component', -# RESOURCE_INTERFACES : 'interface', + RESOURCE_ENDPOINTS : 'component', + RESOURCE_INTERFACES : 'interface', # RESOURCE_NETWORK_INSTANCES: 'network_instance', } diff --git a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java index 9121f1ba9..ede45d0c2 100644 --- a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java +++ b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java @@ -2080,6 +2080,8 @@ public class Serializer { return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY; case ONF_TR_352: return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352; + case XR: + return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_XR; case UNDEFINED: default: return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_UNDEFINED; diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py index 6abe4048f..07a653a4f 100644 --- a/src/service/service/service_handlers/__init__.py +++ b/src/service/service/service_handlers/__init__.py @@ -33,7 +33,7 @@ SERVICE_HANDLERS = [ (TapiServiceHandler, [ { FilterFieldEnum.SERVICE_TYPE : ORM_ServiceTypeEnum.TAPI_CONNECTIVITY_SERVICE, - FilterFieldEnum.DEVICE_DRIVER : ORM_DeviceDriverEnum.TRANSPORT_API, + FilterFieldEnum.DEVICE_DRIVER : [ORM_DeviceDriverEnum.TRANSPORT_API, ORM_DeviceDriverEnum.XR], } ]), -] +] \ No newline at end of file diff --git a/src/tests/ofc22/descriptors_emulated_xr.json b/src/tests/ofc22/descriptors_emulated_xr.json index 1f0474e86..a3fc07bcf 100644 --- a/src/tests/ofc22/descriptors_emulated_xr.json +++ b/src/tests/ofc22/descriptors_emulated_xr.json @@ -62,57 +62,46 @@ "device_drivers": [0], "device_endpoints": [] }, - { - "device_id": {"device_uuid": {"uuid": "O1-OLS"}}, - "device_type": "emu-optical-line-system", - "device_config": {"config_rules": [ - {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, - {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, - {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"aade6001-f00b-5e2f-a357-6a0a9d3de870\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"eb287d83-f05e-53ec-ab5a-adf6bd2b5418\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"0ef74f99-1acc-57bd-ab9d-4b958b06c513\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"50296d99-58cc-5ce7-82f5-fc8ee4eec2ec\"}]}"}} - ]}, - "device_operational_status": 1, - "device_drivers": [0], - "device_endpoints": [] - }, { "device_id": {"device_uuid": {"uuid": "X1-XR-CONSTELLATION"}}, "device_type": "xr-constellation", "device_config": {"config_rules": [ {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.19.219.44"}}, - {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "443"}} + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"HUB-LANE-01\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"LEAF-01-LANE-01\"}]}"}} ]}, "device_operational_status": 1, - "device_drivers": [0], + "device_drivers": [6], "device_endpoints": [] } ], "links": [ { - "link_id": {"link_uuid": {"uuid": "R1-EMU/13/0/0==O1-OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, + "link_id": {"link_uuid": {"uuid": "R1-EMU/13/0/0==XR1-HUB-LANE-01"}}, "link_endpoint_ids": [ {"device_id": {"device_uuid": {"uuid": "R1-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}}, - {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}} + {"device_id": {"device_uuid": {"uuid": "X1-XR-CONSTELLATION"}}, "endpoint_uuid": {"uuid": "HUB-LANE-01"}} ] }, { - "link_id": {"link_uuid": {"uuid": "R2-EMU/13/0/0==O1-OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, + "link_id": {"link_uuid": {"uuid": "R2-EMU/13/0/0==XR1-LEAF-01-LANE-01"}}, "link_endpoint_ids": [ {"device_id": {"device_uuid": {"uuid": "R2-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}}, - {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}} + {"device_id": {"device_uuid": {"uuid": "X1-XR-CONSTELLATION"}}, "endpoint_uuid": {"uuid": "LEAF-01-LANE-01"}} ] }, { - "link_id": {"link_uuid": {"uuid": "R3-EMU/13/0/0==O1-OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, + "link_id": {"link_uuid": {"uuid": "R3-EMU/13/0/0==XR1-LEAF-02-LANE-01"}}, "link_endpoint_ids": [ {"device_id": {"device_uuid": {"uuid": "R3-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}}, - {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}} + {"device_id": {"device_uuid": {"uuid": "X1-XR-CONSTELLATION"}}, "endpoint_uuid": {"uuid": "LEAF-02-LANE-01"}} ] }, { - "link_id": {"link_uuid": {"uuid": "R4-EMU/13/0/0==O1-OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, + "link_id": {"link_uuid": {"uuid": "R4-EMU/13/0/0==XR1-LEAF-03-LANE-01"}}, "link_endpoint_ids": [ {"device_id": {"device_uuid": {"uuid": "R4-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}}, - {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} + {"device_id": {"device_uuid": {"uuid": "X1-XR-CONSTELLATION"}}, "endpoint_uuid": {"uuid": "LEAF-03-LANE-01"}} ] } ] diff --git a/src/tests/ofc22/setup_test_env.sh b/src/tests/ofc22/setup_test_env.sh new file mode 100755 index 000000000..1f8b0a5a7 --- /dev/null +++ b/src/tests/ofc22/setup_test_env.sh @@ -0,0 +1,9 @@ +#!/bin/sh +export CONTEXTSERVICE_SERVICE_HOST=$(kubectl get service/contextservice --namespace tfs --template '{{.spec.clusterIP}}') +export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service/contextservice --namespace tfs -o jsonpath='{.spec.ports[?(@.name=="grpc")].port}') +export COMPUTESERVICE_SERVICE_HOST=$(kubectl get service/computeservice --namespace tfs --template '{{.spec.clusterIP}}') +export COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service/computeservice --namespace tfs -o jsonpath='{.spec.ports[?(@.name=="http")].port}') +echo "CONTEXTSERVICE_SERVICE_HOST=$CONTEXTSERVICE_SERVICE_HOST" +echo "CONTEXTSERVICE_SERVICE_PORT_GRPC=$CONTEXTSERVICE_SERVICE_PORT_GRPC" +echo "COMPUTESERVICE_SERVICE_HOST=$COMPUTESERVICE_SERVICE_HOST" +echo "COMPUTESERVICE_SERVICE_PORT_HTTP=$COMPUTESERVICE_SERVICE_PORT_HTTP" diff --git a/src/tests/ofc22/tests/ObjectsXr.py b/src/tests/ofc22/tests/ObjectsXr.py new file mode 100644 index 000000000..12d2b48ee --- /dev/null +++ b/src/tests/ofc22/tests/ObjectsXr.py @@ -0,0 +1,232 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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. + +from typing import Dict, List, Tuple +from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.tools.object_factory.Context import json_context, json_context_id +from common.tools.object_factory.Device import ( + json_device_connect_rules, json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, + json_device_emulated_tapi_disabled, json_device_id, json_device_packetrouter_disabled, json_device_tapi_disabled) +from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id +from common.tools.object_factory.Link import json_link, json_link_id +from common.tools.object_factory.Topology import json_topology, json_topology_id +from context.proto.kpi_sample_types_pb2 import KpiSampleType + +# ----- Context -------------------------------------------------------------------------------------------------------- +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) +CONTEXT = json_context(DEFAULT_CONTEXT_UUID) + +# ----- Topology ------------------------------------------------------------------------------------------------------- +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) + +# ----- Monitoring Samples --------------------------------------------------------------------------------------------- +PACKET_PORT_SAMPLE_TYPES = [ + KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED, + KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED, + KpiSampleType.KPISAMPLETYPE_BYTES_TRANSMITTED, + KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED, +] + +# ----- Device Credentials and Settings -------------------------------------------------------------------------------- +try: + from .Credentials import DEVICE_R1_ADDRESS, DEVICE_R1_PORT, DEVICE_R1_USERNAME, DEVICE_R1_PASSWORD + from .Credentials import DEVICE_R3_ADDRESS, DEVICE_R3_PORT, DEVICE_R3_USERNAME, DEVICE_R3_PASSWORD + #from .Credentials import DEVICE_O1_ADDRESS, DEVICE_O1_PORT + USE_REAL_DEVICES = True # Use real devices +except ImportError: + USE_REAL_DEVICES = False # Use emulated devices + + DEVICE_R1_ADDRESS = '0.0.0.0' + DEVICE_R1_PORT = 830 + DEVICE_R1_USERNAME = 'admin' + DEVICE_R1_PASSWORD = 'admin' + + DEVICE_R3_ADDRESS = '0.0.0.0' + DEVICE_R3_PORT = 830 + DEVICE_R3_USERNAME = 'admin' + DEVICE_R3_PASSWORD = 'admin' + +DEVICE_X1_ADDRESS = '172.19.219.44' +DEVICE_X1_PORT = 443 + +#USE_REAL_DEVICES = False # Uncomment to force to use emulated devices + +def json_endpoint_ids(device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]]): + return [ + json_endpoint_id(device_id, ep_uuid, topology_id=None) + for ep_uuid, _, _ in endpoint_descriptors + ] + +def json_endpoints(device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]]): + return [ + json_endpoint(device_id, ep_uuid, ep_type, topology_id=None, kpi_sample_types=ep_sample_types) + for ep_uuid, ep_type, ep_sample_types in endpoint_descriptors + ] + +def get_link_uuid(a_device_id : Dict, a_endpoint_id : Dict, z_device_id : Dict, z_endpoint_id : Dict) -> str: + return '{:s}/{:s}=={:s}/{:s}'.format( + a_device_id['device_uuid']['uuid'], a_endpoint_id['endpoint_uuid']['uuid'], + z_device_id['device_uuid']['uuid'], z_endpoint_id['endpoint_uuid']['uuid']) + + +# ----- Devices -------------------------------------------------------------------------------------------------------- +if not USE_REAL_DEVICES: + json_device_packetrouter_disabled = json_device_emulated_packet_router_disabled + json_device_tapi_disabled = json_device_emulated_tapi_disabled + +DEVICE_R1_UUID = 'R1-EMU' +DEVICE_R1_TIMEOUT = 120 +DEVICE_R1_ENDPOINT_DEFS = [('13/0/0', 'optical', []), ('13/1/2', 'copper', PACKET_PORT_SAMPLE_TYPES)] +DEVICE_R1_ID = json_device_id(DEVICE_R1_UUID) +#DEVICE_R1_ENDPOINTS = json_endpoints(DEVICE_R1_ID, DEVICE_R1_ENDPOINT_DEFS) +DEVICE_R1_ENDPOINT_IDS = json_endpoint_ids(DEVICE_R1_ID, DEVICE_R1_ENDPOINT_DEFS) +DEVICE_R1 = json_device_packetrouter_disabled(DEVICE_R1_UUID) +ENDPOINT_ID_R1_13_0_0 = DEVICE_R1_ENDPOINT_IDS[0] +ENDPOINT_ID_R1_13_1_2 = DEVICE_R1_ENDPOINT_IDS[1] +DEVICE_R1_CONNECT_RULES = json_device_connect_rules(DEVICE_R1_ADDRESS, DEVICE_R1_PORT, { + 'username': DEVICE_R1_USERNAME, + 'password': DEVICE_R1_PASSWORD, + 'timeout' : DEVICE_R1_TIMEOUT, +}) if USE_REAL_DEVICES else json_device_emulated_connect_rules(DEVICE_R1_ENDPOINT_DEFS) + + +DEVICE_R2_UUID = 'R2-EMU' +DEVICE_R2_ENDPOINT_DEFS = [('13/0/0', 'optical', []), ('13/1/2', 'copper', PACKET_PORT_SAMPLE_TYPES)] +DEVICE_R2_ID = json_device_id(DEVICE_R2_UUID) +#DEVICE_R2_ENDPOINTS = json_endpoints(DEVICE_R2_ID, DEVICE_R2_ENDPOINT_DEFS) +DEVICE_R2_ENDPOINT_IDS = json_endpoint_ids(DEVICE_R2_ID, DEVICE_R2_ENDPOINT_DEFS) +DEVICE_R2 = json_device_emulated_packet_router_disabled(DEVICE_R2_UUID) +ENDPOINT_ID_R2_13_0_0 = DEVICE_R2_ENDPOINT_IDS[0] +ENDPOINT_ID_R2_13_1_2 = DEVICE_R2_ENDPOINT_IDS[1] +DEVICE_R2_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_R2_ENDPOINT_DEFS) + + +DEVICE_R3_UUID = 'R3-EMU' +DEVICE_R3_TIMEOUT = 120 +DEVICE_R3_ENDPOINT_DEFS = [('13/0/0', 'optical', []), ('13/1/2', 'copper', PACKET_PORT_SAMPLE_TYPES)] +DEVICE_R3_ID = json_device_id(DEVICE_R3_UUID) +#DEVICE_R3_ENDPOINTS = json_endpoints(DEVICE_R3_ID, DEVICE_R3_ENDPOINT_DEFS) +DEVICE_R3_ENDPOINT_IDS = json_endpoint_ids(DEVICE_R3_ID, DEVICE_R3_ENDPOINT_DEFS) +DEVICE_R3 = json_device_packetrouter_disabled(DEVICE_R3_UUID) +ENDPOINT_ID_R3_13_0_0 = DEVICE_R3_ENDPOINT_IDS[0] +ENDPOINT_ID_R3_13_1_2 = DEVICE_R3_ENDPOINT_IDS[1] +DEVICE_R3_CONNECT_RULES = json_device_connect_rules(DEVICE_R3_ADDRESS, DEVICE_R3_PORT, { + 'username': DEVICE_R3_USERNAME, + 'password': DEVICE_R3_PASSWORD, + 'timeout' : DEVICE_R3_TIMEOUT, +}) if USE_REAL_DEVICES else json_device_emulated_connect_rules(DEVICE_R3_ENDPOINT_DEFS) + + +DEVICE_R4_UUID = 'R4-EMU' +DEVICE_R4_ENDPOINT_DEFS = [('13/0/0', 'optical', []), ('13/1/2', 'copper', PACKET_PORT_SAMPLE_TYPES)] +DEVICE_R4_ID = json_device_id(DEVICE_R4_UUID) +#DEVICE_R4_ENDPOINTS = json_endpoints(DEVICE_R4_ID, DEVICE_R4_ENDPOINT_DEFS) +DEVICE_R4_ENDPOINT_IDS = json_endpoint_ids(DEVICE_R4_ID, DEVICE_R4_ENDPOINT_DEFS) +DEVICE_R4 = json_device_emulated_packet_router_disabled(DEVICE_R4_UUID) +ENDPOINT_ID_R4_13_0_0 = DEVICE_R4_ENDPOINT_IDS[0] +ENDPOINT_ID_R4_13_1_2 = DEVICE_R4_ENDPOINT_IDS[1] +DEVICE_R4_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_R4_ENDPOINT_DEFS) + + +DEVICE_X1_UUID = 'X1-XR-CONSTELLATION' +DEVICE_X1_TIMEOUT = 120 +DEVICE_X1_ENDPOINT_DEFS = [ + ('HUB-LANE-01', 'optical', []), + ('LEAF-01-LANE-01', 'optical', []), + ('LEAF-02-LANE-01', 'optical', []), + ('LEAF-03-LANE-01', 'optical', []), +] +DEVICE_X1_ID = json_device_id(DEVICE_X1_UUID) +DEVICE_X1 = json_device_tapi_disabled(DEVICE_X1_UUID) +DEVICE_X1_ENDPOINT_IDS = json_endpoint_ids(DEVICE_X1_ID, DEVICE_X1_ENDPOINT_DEFS) +ENDPOINT_ID_X1_EP1 = DEVICE_X1_ENDPOINT_IDS[0] +ENDPOINT_ID_X1_EP2 = DEVICE_X1_ENDPOINT_IDS[1] +ENDPOINT_ID_X1_EP3 = DEVICE_X1_ENDPOINT_IDS[2] +ENDPOINT_ID_X1_EP4 = DEVICE_X1_ENDPOINT_IDS[3] +DEVICE_X1_CONNECT_RULES = json_device_connect_rules(DEVICE_X1_ADDRESS, DEVICE_X1_PORT, { + 'timeout' : DEVICE_X1_TIMEOUT, +}) +# Always using real device (CM, whether CM has emulated backend is another story) +#if USE_REAL_DEVICES else json_device_emulated_connect_rules(DEVICE_X1_ENDPOINT_DEFS) + + +# ----- Links ---------------------------------------------------------------------------------------------------------- +LINK_R1_X1_UUID = get_link_uuid(DEVICE_R1_ID, ENDPOINT_ID_R1_13_0_0, DEVICE_X1_ID, ENDPOINT_ID_X1_EP1) +LINK_R1_X1_ID = json_link_id(LINK_R1_X1_UUID) +LINK_R1_X1 = json_link(LINK_R1_X1_UUID, [ENDPOINT_ID_R1_13_0_0, ENDPOINT_ID_X1_EP1]) + +LINK_R2_X1_UUID = get_link_uuid(DEVICE_R2_ID, ENDPOINT_ID_R2_13_0_0, DEVICE_X1_ID, ENDPOINT_ID_X1_EP2) +LINK_R2_X1_ID = json_link_id(LINK_R2_X1_UUID) +LINK_R2_X1 = json_link(LINK_R2_X1_UUID, [ENDPOINT_ID_R2_13_0_0, ENDPOINT_ID_X1_EP2]) + +LINK_R3_X1_UUID = get_link_uuid(DEVICE_R3_ID, ENDPOINT_ID_R3_13_0_0, DEVICE_X1_ID, ENDPOINT_ID_X1_EP3) +LINK_R3_X1_ID = json_link_id(LINK_R3_X1_UUID) +LINK_R3_X1 = json_link(LINK_R3_X1_UUID, [ENDPOINT_ID_R3_13_0_0, ENDPOINT_ID_X1_EP3]) + +LINK_R4_X1_UUID = get_link_uuid(DEVICE_R4_ID, ENDPOINT_ID_R4_13_0_0, DEVICE_X1_ID, ENDPOINT_ID_X1_EP4) +LINK_R4_X1_ID = json_link_id(LINK_R4_X1_UUID) +LINK_R4_X1 = json_link(LINK_R4_X1_UUID, [ENDPOINT_ID_R4_13_0_0, ENDPOINT_ID_X1_EP4]) + + +# ----- WIM Service Settings ------------------------------------------------------------------------------------------- + +def compose_service_endpoint_id(endpoint_id): + device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] + endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] + return ':'.join([device_uuid, endpoint_uuid]) + +WIM_SEP_R1_ID = compose_service_endpoint_id(ENDPOINT_ID_R1_13_1_2) +WIM_SEP_R1_SITE_ID = '1' +WIM_SEP_R1_BEARER = WIM_SEP_R1_ID +WIM_SRV_R1_VLAN_ID = 400 + +WIM_SEP_R3_ID = compose_service_endpoint_id(ENDPOINT_ID_R3_13_1_2) +WIM_SEP_R3_SITE_ID = '2' +WIM_SEP_R3_BEARER = WIM_SEP_R3_ID +WIM_SRV_R3_VLAN_ID = 500 + +WIM_USERNAME = 'admin' +WIM_PASSWORD = 'admin' + +WIM_MAPPING = [ + {'device-id': DEVICE_R1_UUID, 'service_endpoint_id': WIM_SEP_R1_ID, + 'service_mapping_info': {'bearer': {'bearer-reference': WIM_SEP_R1_BEARER}, 'site-id': WIM_SEP_R1_SITE_ID}}, + {'device-id': DEVICE_R3_UUID, 'service_endpoint_id': WIM_SEP_R3_ID, + 'service_mapping_info': {'bearer': {'bearer-reference': WIM_SEP_R3_BEARER}, 'site-id': WIM_SEP_R3_SITE_ID}}, +] +WIM_SERVICE_TYPE = 'ELINE' +WIM_SERVICE_CONNECTION_POINTS = [ + {'service_endpoint_id': WIM_SEP_R1_ID, + 'service_endpoint_encapsulation_type': 'dot1q', + 'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_R1_VLAN_ID}}, + {'service_endpoint_id': WIM_SEP_R3_ID, + 'service_endpoint_encapsulation_type': 'dot1q', + 'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_R3_VLAN_ID}}, +] + +# ----- Object Collections --------------------------------------------------------------------------------------------- + +CONTEXTS = [CONTEXT] +TOPOLOGIES = [TOPOLOGY] + +DEVICES = [ + (DEVICE_R1, DEVICE_R1_CONNECT_RULES), + (DEVICE_R2, DEVICE_R2_CONNECT_RULES), + (DEVICE_R3, DEVICE_R3_CONNECT_RULES), + (DEVICE_R4, DEVICE_R4_CONNECT_RULES), + (DEVICE_X1, DEVICE_X1_CONNECT_RULES), +] + +LINKS = [LINK_R1_X1, LINK_R2_X1, LINK_R3_X1, LINK_R4_X1] diff --git a/src/tests/ofc22/tests/test_functional_create_service_xr.py b/src/tests/ofc22/tests/test_functional_create_service_xr.py new file mode 100644 index 000000000..882950cd5 --- /dev/null +++ b/src/tests/ofc22/tests/test_functional_create_service_xr.py @@ -0,0 +1,130 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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, pytest +from common.DeviceTypes import DeviceTypeEnum +from common.Settings import get_setting +from common.tests.EventTools import EVENT_CREATE, EVENT_UPDATE, check_events +from common.tools.object_factory.Connection import json_connection_id +from common.tools.object_factory.Device import json_device_id +from common.tools.object_factory.Service import json_service_id +from common.tools.grpc.Tools import grpc_message_to_json_string +from compute.tests.mock_osm.MockOSM import MockOSM +from context.client.ContextClient import ContextClient +from context.client.EventsCollector import EventsCollector +from context.proto.context_pb2 import ContextId, Empty +from .ObjectsXr import ( + CONTEXT_ID, CONTEXTS, DEVICE_X1_UUID, DEVICE_R1_UUID, DEVICE_R3_UUID, DEVICES, LINKS, TOPOLOGIES, + WIM_MAPPING, WIM_PASSWORD, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE, WIM_USERNAME) + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +DEVTYPE_EMU_PR = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value +#DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value +DEVTYPE_EMU_OLS = DeviceTypeEnum.XR_CONSTELLATION.value + + +@pytest.fixture(scope='session') +def context_client(): + _client = ContextClient(get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC')) + yield _client + _client.close() + + +@pytest.fixture(scope='session') +def osm_wim(): + wim_url = 'http://{:s}:{:s}'.format( + get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP'))) + return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD) + + +def test_scenario_is_correct(context_client : ContextClient): # pylint: disable=redefined-outer-name + # ----- List entities - Ensure links are created ------------------------------------------------------------------- + response = context_client.ListContexts(Empty()) + assert len(response.contexts) == len(CONTEXTS) + + response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) + assert len(response.topologies) == len(TOPOLOGIES) + + response = context_client.ListDevices(Empty()) + assert len(response.devices) == len(DEVICES) + + response = context_client.ListLinks(Empty()) + assert len(response.links) == len(LINKS) + + response = context_client.ListServices(ContextId(**CONTEXT_ID)) + assert len(response.services) == 0 + + +def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name + # ----- Start the EventsCollector ---------------------------------------------------------------------------------- + events_collector = EventsCollector(context_client, log_events_received=True) + events_collector.start() + + # ----- Create Service --------------------------------------------------------------------------------------------- + service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS) + osm_wim.get_connectivity_service_status(service_uuid) + + # ----- Validate collected events ---------------------------------------------------------------------------------- + + packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR) + optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_EMU_OLS) + optical_service_uuid = '{:s}:optical'.format(service_uuid) + + expected_events = [ + # Create packet service and add first endpoint + ('ServiceEvent', EVENT_CREATE, json_service_id(service_uuid, context_id=CONTEXT_ID)), + ('ServiceEvent', EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)), + + # Configure OLS controller, create optical service, create optical connection + ('DeviceEvent', EVENT_UPDATE, json_device_id(DEVICE_X1_UUID)), + ('ServiceEvent', EVENT_CREATE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)), + ('ConnectionEvent', EVENT_CREATE, json_connection_id(optical_connection_uuid)), + + # Configure endpoint packet devices, add second endpoint to service, create connection + ('DeviceEvent', EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)), + ('DeviceEvent', EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)), + ('ServiceEvent', EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)), + ('ConnectionEvent', EVENT_CREATE, json_connection_id(packet_connection_uuid)), + ] + check_events(events_collector, expected_events) + + # ----- Stop the EventsCollector ----------------------------------------------------------------------------------- + events_collector.stop() + + +def test_scenario_service_created(context_client : ContextClient): # pylint: disable=redefined-outer-name + # ----- List entities - Ensure service is created ------------------------------------------------------------------ + response = context_client.ListContexts(Empty()) + assert len(response.contexts) == len(CONTEXTS) + + response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) + assert len(response.topologies) == len(TOPOLOGIES) + + response = context_client.ListDevices(Empty()) + assert len(response.devices) == len(DEVICES) + + response = context_client.ListLinks(Empty()) + assert len(response.links) == len(LINKS) + + response = context_client.ListServices(ContextId(**CONTEXT_ID)) + LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) + assert len(response.services) == 2 # L3NM + TAPI + for service in response.services: + service_id = service.service_id + response = context_client.ListConnections(service_id) + LOGGER.info(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( + grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) + assert len(response.connections) == 1 # one connection per service diff --git a/src/webui/service/static/topology_icons/xr-constellation.png b/src/webui/service/static/topology_icons/xr-constellation.png new file mode 100644 index 0000000000000000000000000000000000000000..518ca5a60b1d6b9c674783873189566430adccf9 GIT binary patch literal 37336 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°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 Z|39ORx&-~ZicJ6j002ovPDHLkV1nd;djS9d literal 0 HcmV?d00001 -- GitLab