Commit 6cd56977 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Device component:

- Cosmetic changes in L2/L3 VPN drivers
- Upgraded Optical TFS Driver
parent 32e0c18c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -188,7 +188,10 @@ if LOAD_ALL_DEVICE_DRIVERS:
    DRIVERS.append(
        (OpticalTfsDriver, [
            {
                FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPEN_LINE_SYSTEM,
                FilterFieldEnum.DEVICE_TYPE: [
                    DeviceTypeEnum.OPEN_LINE_SYSTEM,
                    DeviceTypeEnum.TERAFLOWSDN_CONTROLLER,
                ],
                FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_OPTICAL_TFS,
            }
        ]))
+2 −1
Original line number Diff line number Diff line
@@ -70,9 +70,10 @@ class IetfL2VpnDriver(_Driver):

    def Connect(self) -> bool:
        with self.__lock:
            if self.__started.is_set(): return True
            try:
                self.wim.check_credentials()
            except Exception:  # pylint: disable=broad-except
            except:     # pylint: disable=bare-except
                LOGGER.exception('Exception checking credentials')
                return False
            else:
+33 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum

GET_DEVICES_URL = '{:s}://{:s}:{:d}/tfs-api/devices'
GET_LINKS_URL   = '{:s}://{:s}:{:d}/tfs-api/links'

TIMEOUT = 30

HTTP_OK_CODES = {
@@ -47,6 +48,10 @@ MAPPING_DRIVER = {
    'DEVICEDRIVER_OPTICAL_TFS'          : 9,
    'DEVICEDRIVER_IETF_ACTN'            : 10,
    'DEVICEDRIVER_OC'                   : 11,
    'DEVICEDRIVER_QKD'                  : 12,
    'DEVICEDRIVER_IETF_L3VPN'           : 13,
    'DEVICEDRIVER_IETF_SLICE'           : 14,
    'DEVICEDRIVER_NCE'                  : 15,
}

MSG_ERROR = 'Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}'
@@ -60,20 +65,30 @@ class TfsApiClient:
    ) -> None:
        self._devices_url = GET_DEVICES_URL.format(scheme, address, port)
        self._links_url   = GET_LINKS_URL.format(scheme, address, port)
        self._auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None

    def get_devices_endpoints(self, import_topology : ImportTopologyEnum = ImportTopologyEnum.DEVICES) -> List[Dict]:
        self._auth        = (
            HTTPBasicAuth(username, password)
            if username is not None and password is not None
            else None
        )

    def get_devices_endpoints(
        self, import_topology : ImportTopologyEnum = ImportTopologyEnum.DEVICES
    ) -> List[Dict]:
        LOGGER.debug('[get_devices_endpoints] begin')
        LOGGER.debug('[get_devices_endpoints] import_topology={:s}'.format(str(import_topology)))
        MSG = '[get_devices_endpoints] import_topology={:s}'
        LOGGER.debug(MSG.format(str(import_topology)))

        reply = requests.get(self._devices_url, timeout=TIMEOUT, verify=False, auth=self._auth)
        if reply.status_code not in HTTP_OK_CODES:
            msg = MSG_ERROR.format(str(self._devices_url), str(reply.status_code), str(reply))
            msg = MSG_ERROR.format(
                str(self._devices_url), str(reply.status_code), str(reply)
            )
            LOGGER.error(msg)
            raise Exception(msg)

        if import_topology == ImportTopologyEnum.DISABLED:
            raise Exception('Unsupported import_topology mode: {:s}'.format(str(import_topology)))
            MSG = 'Unsupported import_topology mode: {:s}'
            raise Exception(MSG.format(str(import_topology)))

        result = list()
        for json_device in reply.json()['devices']:
@@ -87,7 +102,10 @@ class TfsApiClient:
                'name': json_device['name'],
                'type': device_type,
                'status': MAPPING_STATUS[device_status],
                'drivers': [MAPPING_DRIVER[driver] for driver in json_device['device_drivers']],
                'drivers': [
                    MAPPING_DRIVER[driver]
                    for driver in json_device['device_drivers']
                ],
            }
            result.append((device_url, device_data))

@@ -108,7 +126,9 @@ class TfsApiClient:

        reply = requests.get(self._links_url, timeout=TIMEOUT, verify=False, auth=self._auth)
        if reply.status_code not in HTTP_OK_CODES:
            msg = MSG_ERROR.format(str(self._links_url), str(reply.status_code), str(reply))
            msg = MSG_ERROR.format(
                str(self._links_url), str(reply.status_code), str(reply)
            )
            LOGGER.error(msg)
            raise Exception(msg)

@@ -116,7 +136,10 @@ class TfsApiClient:
            link_uuid : str = json_link['link_id']['link_uuid']['uuid']
            link_url = '/links/link[{:s}]'.format(link_uuid)
            link_endpoint_ids = [
                (json_endpoint_id['device_id']['device_uuid']['uuid'], json_endpoint_id['endpoint_uuid']['uuid'])
                (
                    json_endpoint_id['device_id']['device_uuid']['uuid'],
                    json_endpoint_id['endpoint_uuid']['uuid'],
                )
                for json_endpoint_id in json_link['link_endpoint_ids']
            ]
            link_data = {
+92 −97
Original line number Diff line number Diff line
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,17 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
from typing import Dict, List, Optional

import requests
import logging, requests
from requests.auth import HTTPBasicAuth

from typing import Dict, List, Optional
from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum

GET_DEVICES_URL = "{:s}://{:s}:{:d}/tfs-api/devices"
GET_LINKS_URL = "{:s}://{:s}:{:d}/tfs-api/links"
L3VPN_URL = "{:s}://{:s}:{:d}/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
GET_DEVICES_URL = '{:s}://{:s}:{:d}/tfs-api/devices'
GET_LINKS_URL   = '{:s}://{:s}:{:d}/tfs-api/links'
L3VPN_URL       = '{:s}://{:s}:{:d}/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services'

TIMEOUT = 30

HTTP_OK_CODES = {
@@ -33,59 +31,56 @@ HTTP_OK_CODES = {
}

MAPPING_STATUS = {
    "DEVICEOPERATIONALSTATUS_UNDEFINED": 0,
    "DEVICEOPERATIONALSTATUS_DISABLED": 1,
    "DEVICEOPERATIONALSTATUS_ENABLED": 2,
    'DEVICEOPERATIONALSTATUS_UNDEFINED': 0,
    'DEVICEOPERATIONALSTATUS_DISABLED' : 1,
    'DEVICEOPERATIONALSTATUS_ENABLED'  : 2,
}

MAPPING_DRIVER = {
    "DEVICEDRIVER_UNDEFINED": 0,
    "DEVICEDRIVER_OPENCONFIG": 1,
    "DEVICEDRIVER_TRANSPORT_API": 2,
    "DEVICEDRIVER_P4": 3,
    "DEVICEDRIVER_IETF_NETWORK_TOPOLOGY": 4,
    "DEVICEDRIVER_ONF_TR_532": 5,
    "DEVICEDRIVER_XR": 6,
    "DEVICEDRIVER_IETF_L2VPN": 7,
    "DEVICEDRIVER_GNMI_OPENCONFIG": 8,
    "DEVICEDRIVER_OPTICAL_TFS": 9,
    "DEVICEDRIVER_IETF_ACTN": 10,
    "DEVICEDRIVER_OC": 11,
    'DEVICEDRIVER_UNDEFINED'            : 0,
    'DEVICEDRIVER_OPENCONFIG'           : 1,
    'DEVICEDRIVER_TRANSPORT_API'        : 2,
    'DEVICEDRIVER_P4'                   : 3,
    'DEVICEDRIVER_IETF_NETWORK_TOPOLOGY': 4,
    'DEVICEDRIVER_ONF_TR_532'           : 5,
    'DEVICEDRIVER_XR'                   : 6,
    'DEVICEDRIVER_IETF_L2VPN'           : 7,
    'DEVICEDRIVER_GNMI_OPENCONFIG'      : 8,
    'DEVICEDRIVER_OPTICAL_TFS'          : 9,
    'DEVICEDRIVER_IETF_ACTN'            : 10,
    'DEVICEDRIVER_OC'                   : 11,
    'DEVICEDRIVER_QKD'                  : 12,
    'DEVICEDRIVER_IETF_L3VPN'           : 13,
    'DEVICEDRIVER_IETF_SLICE'           : 14,
    'DEVICEDRIVER_NCE'                  : 15,
}

MSG_ERROR = "Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}"
MSG_ERROR = 'Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}'

LOGGER = logging.getLogger(__name__)


class TfsApiClient:
    def __init__(
        self,
        address: str,
        port: int,
        scheme: str = "http",
        username: Optional[str] = None,
        password: Optional[str] = None,
        self, address : str, port : int, scheme : str = 'http',
        username : Optional[str] = None, password : Optional[str] = None
    ) -> None:
        self._devices_url = GET_DEVICES_URL.format(scheme, address, port)
        self._links_url   = GET_LINKS_URL.format(scheme, address, port)
        self._l3vpn_url   = L3VPN_URL.format(scheme, address, port)
        self._auth = None
        # (
        #     HTTPBasicAuth(username, password)
        #     if username is not None and password is not None
        #     else None
        # )
        self._auth        = (
            HTTPBasicAuth(username, password)
            if username is not None and password is not None
            else None
        )

    def get_devices_endpoints(
        self, import_topology : ImportTopologyEnum = ImportTopologyEnum.DEVICES
    ) -> List[Dict]:
        LOGGER.debug("[get_devices_endpoints] begin")
        LOGGER.debug(
            "[get_devices_endpoints] import_topology={:s}".format(str(import_topology))
        )
        LOGGER.debug('[get_devices_endpoints] begin')
        MSG = '[get_devices_endpoints] import_topology={:s}'
        LOGGER.debug(MSG.format(str(import_topology)))

        reply = requests.get(self._devices_url, timeout=TIMEOUT, auth=self._auth)
        reply = requests.get(self._devices_url, timeout=TIMEOUT, verify=False, auth=self._auth)
        if reply.status_code not in HTTP_OK_CODES:
            msg = MSG_ERROR.format(
                str(self._devices_url), str(reply.status_code), str(reply)
@@ -94,43 +89,44 @@ class TfsApiClient:
            raise Exception(msg)

        if import_topology == ImportTopologyEnum.DISABLED:
            raise Exception(
                "Unsupported import_topology mode: {:s}".format(str(import_topology))
            )
            MSG = 'Unsupported import_topology mode: {:s}'
            raise Exception(MSG.format(str(import_topology)))

        result = list()
        for json_device in reply.json()["devices"]:
            device_uuid: str = json_device["device_id"]["device_uuid"]["uuid"]
            device_type: str = json_device["device_type"]
            device_status = json_device["device_operational_status"]
            device_url = "/devices/device[{:s}]".format(device_uuid)
        for json_device in reply.json()['devices']:
            device_uuid : str = json_device['device_id']['device_uuid']['uuid']
            device_type : str = json_device['device_type']
            #if not device_type.startswith('emu-'): device_type = 'emu-' + device_type
            device_status = json_device['device_operational_status']
            device_url = '/devices/device[{:s}]'.format(device_uuid)
            device_data = {
                "uuid": json_device["device_id"]["device_uuid"]["uuid"],
                "name": json_device["name"],
                "type": device_type,
                "status": MAPPING_STATUS[device_status],
                "drivers": [
                    MAPPING_DRIVER[driver] for driver in json_device["device_drivers"]
                'uuid': json_device['device_id']['device_uuid']['uuid'],
                'name': json_device['name'],
                'type': device_type,
                'status': MAPPING_STATUS[device_status],
                'drivers': [
                    MAPPING_DRIVER[driver]
                    for driver in json_device['device_drivers']
                ],
            }
            result.append((device_url, device_data))

            for json_endpoint in json_device["device_endpoints"]:
                endpoint_uuid = json_endpoint["endpoint_id"]["endpoint_uuid"]["uuid"]
                endpoint_url = "/endpoints/endpoint[{:s}]".format(endpoint_uuid)
            for json_endpoint in json_device['device_endpoints']:
                endpoint_uuid = json_endpoint['endpoint_id']['endpoint_uuid']['uuid']
                endpoint_url = '/endpoints/endpoint[{:s}]'.format(endpoint_uuid)
                endpoint_data = {
                    "device_uuid": device_uuid,
                    "uuid": endpoint_uuid,
                    "name": json_endpoint["name"],
                    "type": json_endpoint["endpoint_type"],
                    'device_uuid': device_uuid,
                    'uuid': endpoint_uuid,
                    'name': json_endpoint['name'],
                    'type': json_endpoint['endpoint_type'],
                }
                result.append((endpoint_url, endpoint_data))

        if import_topology == ImportTopologyEnum.DEVICES:
            LOGGER.debug("[get_devices_endpoints] devices only; returning")
            LOGGER.debug('[get_devices_endpoints] devices only; returning')
            return result

        reply = requests.get(self._links_url, timeout=TIMEOUT, auth=self._auth)
        reply = requests.get(self._links_url, timeout=TIMEOUT, verify=False, auth=self._auth)
        if reply.status_code not in HTTP_OK_CODES:
            msg = MSG_ERROR.format(
                str(self._links_url), str(reply.status_code), str(reply)
@@ -138,50 +134,49 @@ class TfsApiClient:
            LOGGER.error(msg)
            raise Exception(msg)

        for json_link in reply.json()["links"]:
            link_uuid: str = json_link["link_id"]["link_uuid"]["uuid"]
            link_url = "/links/link[{:s}]".format(link_uuid)
        for json_link in reply.json()['links']:
            link_uuid : str = json_link['link_id']['link_uuid']['uuid']
            link_url = '/links/link[{:s}]'.format(link_uuid)
            link_endpoint_ids = [
                (
                    json_endpoint_id["device_id"]["device_uuid"]["uuid"],
                    json_endpoint_id["endpoint_uuid"]["uuid"],
                    json_endpoint_id['device_id']['device_uuid']['uuid'],
                    json_endpoint_id['endpoint_uuid']['uuid'],
                )
                for json_endpoint_id in json_link["link_endpoint_ids"]
                for json_endpoint_id in json_link['link_endpoint_ids']
            ]
            link_data = {
                "uuid": json_link["link_id"]["link_uuid"]["uuid"],
                "name": json_link["name"],
                "endpoints": link_endpoint_ids,
                'uuid': json_link['link_id']['link_uuid']['uuid'],
                'name': json_link['name'],
                'endpoints': link_endpoint_ids,
            }
            result.append((link_url, link_data))

        LOGGER.debug("[get_devices_endpoints] topology; returning")
        LOGGER.debug('[get_devices_endpoints] topology; returning')
        return result

    def create_connectivity_service(self, l3vpn_data: dict) -> None:
        try:
            requests.post(self._l3vpn_url, json=l3vpn_data)
            LOGGER.debug(
                "[create_connectivity_service] l3vpn_data={:s}".format(str(l3vpn_data))
            )
            MSG = '[create_connectivity_service] l3vpn_data={:s}'
            LOGGER.debug(MSG.format(str(l3vpn_data)))
        except requests.exceptions.ConnectionError:
            raise Exception("faild to send post request to TFS L3VPN NBI")
            raise Exception('Failed to send POST request to TFS L3VPN NBI')

    def update_connectivity_service(self, l3vpn_data: dict) -> None:
        vpn_id = l3vpn_data['ietf-l3vpn-svc:l3vpn-svc']["vpn-services"]["vpn-service"][0]["vpn-id"]
        url = self._l3vpn_url + f"/vpn-service={vpn_id}"
        vpn_id = l3vpn_data['ietf-l3vpn-svc:l3vpn-svc']['vpn-services']['vpn-service'][0]['vpn-id']
        url = self._l3vpn_url + f'/vpn-service={vpn_id}'
        try:
            requests.put(url, json=l3vpn_data)
            LOGGER.debug(
                "[update_connectivity_service] l3vpn_data={:s}".format(str(l3vpn_data))
            )
            MSG = '[update_connectivity_service] l3vpn_data={:s}'
            LOGGER.debug(MSG.format(str(l3vpn_data)))
        except requests.exceptions.ConnectionError:
            raise Exception("faild to send post request to TFS L3VPN NBI")
            raise Exception('Failed to send PUT request to TFS L3VPN NBI')

    def delete_connectivity_service(self, service_uuid: str) -> None:
        url = self._l3vpn_url + f"/vpn-service={service_uuid}"
        url = self._l3vpn_url + f'/vpn-service={service_uuid}'
        try:
            requests.delete(url, auth=self._auth)
            LOGGER.debug("[delete_connectivity_service] url={:s}".format(str(url)))
            requests.delete(url)
            MSG = '[delete_connectivity_service] url={:s}'
            LOGGER.debug(MSG.format(str(url)))
        except requests.exceptions.ConnectionError:
            raise Exception("faild to send delete request to TFS L3VPN NBI")
            raise Exception('Failed to send DELETE request to TFS L3VPN NBI')
+70 −56

File changed.

Preview size limit exceeded, changes collapsed.

Loading