Commit 4ad6f0e7 authored by Pablo Armingol's avatar Pablo Armingol
Browse files

NBI: Implement IPoWDM service with RESTful API endpoints for create and delete operations

parent 805d1f1b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ from .ietf_l3vpn import register_ietf_l3vpn
from .ietf_network import register_ietf_network
from .ietf_network_slice import register_ietf_nss
from .optical_slice import register_optical_slice
from .ipowdm import register_ipowdm
from .osm_nbi import register_osm_api
from .qkd_app import register_qkd_app
from .restconf_root import register_restconf_root
@@ -100,6 +101,7 @@ register_ietf_l3vpn (nbi_app)
register_ietf_network    (nbi_app)
register_ietf_nss        (nbi_app)
register_optical_slice   (nbi_app)
register_ipowdm          (nbi_app)
register_osm_api         (nbi_app)
register_qkd_app         (nbi_app)
register_restconf_root   (nbi_app)
+100 −0
Original line number Diff line number Diff line
import logging
import json
from flask_restful import Resource, request
from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, Device, Service, ServiceTypeEnum, ServiceStatusEnum
from device.client.DeviceClient import DeviceClient
from service.client.ServiceClient import ServiceClient
import requests

LOGGER = logging.getLogger(__name__)

class IpowdmService(Resource):
    def __init__(self):
        super().__init__()
        self.device_client = DeviceClient()
        self.service_client = ServiceClient()

    def post(self, sliceId: str):
        LOGGER.info("Received POST request for IPoWDM service: %s", sliceId)

        data = request.get_json()
        LOGGER.info("IPoWDM data: %s", json.dumps(data, indent=2))

        try:
            service = Service()
            service.service_id.service_uuid.uuid = sliceId
            service.service_id.context_id.context_uuid.uuid = "admin"
            # It's an IP over WDM connectivity service, so maybe TAPI_CONNECTIVITY_SERVICE or L3NM
            service.service_type = ServiceTypeEnum.SERVICETYPE_L3NM 
            service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
            service.name = f"IPoWDM-{sliceId}"

            service_response = self.service_client.CreateService(service)
            LOGGER.info("Created TFS IPoWDM service: %s", service_response)

        except Exception as e:
            LOGGER.error("Failed to create TFS IPoWDM service: %s", str(e), exc_info=True)
            return {'status': 'error', 'message': f'Failed to create TFS service: {str(e)}'}, 500

        # Send the configuration to the corresponding device. 
        # ietf_l3vpn driver is usually loaded in the IP Controller.
        device_id_str = "IP Controller"
        try:
            device = Device()
            device.device_id.device_uuid.uuid = device_id_str
            config_rule = ConfigRule()
            config_rule.action = ConfigActionEnum.CONFIGACTION_SET
            # The resource_key needs to contain 'ipowdm' for the ietf_l3vpn driver to handle it appropriately
            config_rule.custom.resource_key = f'/ipowdm/context/{sliceId}'
            config_rule.custom.resource_value = json.dumps(data)
            device.device_config.config_rules.append(config_rule)
            self.device_client.ConfigureDevice(device)
            LOGGER.info("Configured device %s with IPoWDM service %s", device_id_str, sliceId)

        except Exception as e:
            LOGGER.error("Failed to configure device: %s", str(e))
            return {'status': 'error', 'message': f'Failed to configure device: {str(e)}'}, 500

        return {
            'status': 'success',
            'message': f'IPoWDM service created for {sliceId}',
            'sliceId': sliceId
        }, 201

    def delete(self, sliceId: str):
        LOGGER.info("Received DELETE request for IPoWDM service: %s", sliceId)

        try:
            from common.proto.context_pb2 import ServiceId

            service_id = ServiceId()
            service_id.service_uuid.uuid = sliceId
            service_id.context_id.context_uuid.uuid = "admin"

            self.service_client.DeleteService(service_id)
            LOGGER.info("Deleted TFS service: %s", sliceId)

        except Exception as e:
            LOGGER.error("Failed to delete TFS IPoWDM service: %s", str(e), exc_info=True)
            return {'status': 'error', 'message': f'Failed to delete TFS service: {str(e)}'}, 500

        device_id_str = "IP Controller"
        try:
            device = Device()
            device.device_id.device_uuid.uuid = device_id_str
            config_rule = ConfigRule()
            config_rule.action = ConfigActionEnum.CONFIGACTION_DELETE
            config_rule.custom.resource_key = f'/ipowdm/context/{sliceId}'
            config_rule.custom.resource_value = "{}" # or empty
            device.device_config.config_rules.append(config_rule)
            self.device_client.ConfigureDevice(device)
            LOGGER.info("Sent DELETE configuration to device %s for IPoWDM service %s", device_id_str, sliceId)
        except Exception as e:
            LOGGER.warning("Failed to delete from device: %s", str(e))
            return {'status': 'error', 'message': f'Failed to delete from device: {str(e)}'}, 500

        return {
            'status': 'success',
            'message': f'IPoWDM service deleted for {sliceId}',
            'sliceId': sliceId
        }, 200
+11 −0
Original line number Diff line number Diff line
from nbi.service.NbiApplication import NbiApplication
from .Resources import IpowdmService

URL_PREFIX = '/restconf/ipowdm/v1'

def register_ipowdm(nbi_app : NbiApplication):
    nbi_app.add_rest_api_resource(
        IpowdmService,
        URL_PREFIX + '/service/<string:sliceId>',
        endpoint='ipowdm.service'
    )