Commit ac066a01 authored by Ville Hallivuori's avatar Ville Hallivuori
Browse files

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
parent 56ab40bb
Loading
Loading
Loading
Loading

README_INFINERA.md

0 → 100644
+82 −0
Original line number Diff line number Diff line
# 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
+12 −1
Original line number Diff line number Diff line
@@ -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
+1 −2
Original line number Diff line number Diff line
@@ -36,8 +36,7 @@ DRIVERS = [
            FilterFieldEnum.DRIVER     : [
                ORM_DeviceDriverEnum.UNDEFINED,
                ORM_DeviceDriverEnum.OPENCONFIG,
                ORM_DeviceDriverEnum.TRANSPORT_API,
                ORM_DeviceDriverEnum.XR
                ORM_DeviceDriverEnum.TRANSPORT_API
            ],
        }
    ]),
+38 −3
Original line number Diff line number Diff line
@@ -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

+4 −4
Original line number Diff line number Diff line
@@ -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',
}
Loading