Commit 82fe306f authored by Shayan Hajipour's avatar Shayan Hajipour
Browse files

feat: ietf slice delete nbi endpoints added

- tests updated
parent e45fa0e0
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
# Copyright 2022-2024 ETSI OSG/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.
# 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
from typing import Dict

from flask import request
from flask.json import jsonify
from flask_restful import Resource
from werkzeug.exceptions import UnsupportedMediaType

from context.client.ContextClient import ContextClient
from slice.client.SliceClient import SliceClient

from ..tools.Authentication import HTTP_AUTH
from ..tools.HttpStatusCodes import (
    HTTP_CREATED,
)
from .ietf_slice_handler import IETFSliceHandler

LOGGER = logging.getLogger(__name__)


class NSS_Service_Match_Criterion(Resource):
    # @HTTP_AUTH.login_required
    def get(self):
        response = jsonify({"message": "All went well!"})
        # TODO Return list of current network-slice-services
        return response

    # @HTTP_AUTH.login_required
    def delete(self, slice_id: str, sdp_id: str, match_criterion_id: str):
        context_client = ContextClient()
        slice_request = IETFSliceHandler.delete_match_criteria(
            slice_id, sdp_id, int(match_criterion_id), context_client
        )
        slice_client = SliceClient()
        slice_client.UpdateSlice(slice_request)

        response = jsonify({})
        response.status_code = HTTP_CREATED
        return response
+48 −0
Original line number Diff line number Diff line
# Copyright 2022-2024 ETSI OSG/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.
# 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
from typing import Dict

from flask import request
from flask.json import jsonify
from flask_restful import Resource
from werkzeug.exceptions import UnsupportedMediaType

from context.client.ContextClient import ContextClient

from ..tools.Authentication import HTTP_AUTH
from ..tools.HttpStatusCodes import HTTP_CREATED
from .ietf_slice_handler import IETFSliceHandler

LOGGER = logging.getLogger(__name__)


class NSS_Service_Connection_Groups(Resource):
    # @HTTP_AUTH.login_required
    def get(self):
        response = jsonify({"message": "All went well!"})
        # TODO Return list of current network-slice-services
        return response

    # @HTTP_AUTH.login_required
    def delete(self, slice_id: str, connection_group_id: str):
        context_client = ContextClient()
        slice_request = IETFSliceHandler.delete_connection_group(
            slice_id, connection_group_id, context_client
        )
        _ = context_client.SetSlice(slice_request)

        response = jsonify({})
        response.status_code = HTTP_CREATED
        return response
+45 −0
Original line number Diff line number Diff line
# Copyright 2022-2024 ETSI OSG/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.
# 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
from typing import Dict

from flask import request
from flask.json import jsonify
from flask_restful import Resource
from werkzeug.exceptions import UnsupportedMediaType

from context.client.ContextClient import ContextClient

from ..tools.HttpStatusCodes import HTTP_OK
from .ietf_slice_handler import IETFSliceHandler

LOGGER = logging.getLogger(__name__)


class NSS_Service_SDP(Resource):
    # @HTTP_AUTH.login_required
    def get(self):
        response = jsonify({"message": "All went well!"})
        # TODO Return list of current network-slice-services
        return response

    # @HTTP_AUTH.login_required
    def delete(self, slice_id: str, sdp_id: str):
        context_client = ContextClient()
        slice_request = IETFSliceHandler.delete_sdp(slice_id, sdp_id, context_client)
        _ = context_client.SetSlice(slice_request)

        response = jsonify({})
        response.status_code = HTTP_OK
        return response
+42 −11
Original line number Diff line number Diff line
@@ -16,23 +16,54 @@
# Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/

from flask_restful import Resource

from nbi.service.rest_server.RestServer import RestServer
from .NSS_Services import NSS_Services

from .NSS_Service import NSS_Service
from .NSS_Services_SDPs import NSS_Service_SDPs
from .NSS_Services_Connection_Groups import NSS_Service_Connection_Groups
from .NSS_Service_Match_Criteria import NSS_Service_Match_Criteria
from .NSS_Service_Match_Criterion import NSS_Service_Match_Criterion
from .NSS_Services import NSS_Services
from .NSS_Services_Connection_Groups import NSS_Service_Connection_Groups
from .NSS_Services_SDP import NSS_Service_SDP
from .NSS_Services_SDPs import NSS_Service_SDPs

URL_PREFIX = "/restconf/data/ietf-network-slice-service:ietf-nss"

URL_PREFIX = '/restconf/data/ietf-network-slice-service:ietf-nss'

def _add_resource(rest_server: RestServer, resource: Resource, *urls, **kwargs):
    urls = [(URL_PREFIX + url) for url in urls]
    rest_server.add_resource(resource, *urls, **kwargs)

def register_ietf_nss(rest_server : RestServer):
    _add_resource(rest_server, NSS_Services, '/network-slice-services')
    _add_resource(rest_server, NSS_Service, '/network-slice-services/slice-service=<string:slice_id>')
    _add_resource(rest_server, NSS_Service_SDPs, '/network-slice-services/slice-service=<string:slice_id>/sdps')
    _add_resource(rest_server, NSS_Service_Connection_Groups, '/network-slice-services/slice-service=<string:slice_id>/connection-groups')
    _add_resource(rest_server, NSS_Service_Match_Criteria, '/network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>/service-match-criteria')

def register_ietf_nss(rest_server: RestServer):
    _add_resource(rest_server, NSS_Services, "/network-slice-services")
    _add_resource(
        rest_server,
        NSS_Service,
        "/network-slice-services/slice-service=<string:slice_id>",
    )
    _add_resource(
        rest_server,
        NSS_Service_SDPs,
        "/network-slice-services/slice-service=<string:slice_id>/sdps",
    )
    _add_resource(
        rest_server,
        NSS_Service_SDP,
        "/network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>",
    )
    _add_resource(
        rest_server,
        NSS_Service_Connection_Groups,
        "/network-slice-services/slice-service=<string:slice_id>/connection-groups",
    )
    _add_resource(
        rest_server,
        NSS_Service_Match_Criteria,
        "/network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>/service-match-criteria",
    )
    _add_resource(
        rest_server,
        NSS_Service_Match_Criterion,
        "/network-slice-services/slice-service=<string:slice_id>/sdps/sdp=<string:sdp_id>/service-match-criteria/match-criterion=<string:match_criterion_id>",
    )
+96 −0
Original line number Diff line number Diff line
@@ -119,6 +119,33 @@ class IETFSliceHandler:
        )
        return slice_request

    @staticmethod
    def delete_sdp(
        slice_uuid: str, sdp_id: str, context_client: ContextClient
    ) -> Slice:
        slice_request = get_slice_by_uuid(context_client, slice_uuid)
        for cr in slice_request.slice_config.config_rules:
            if cr.WhichOneof("config_rule") != "custom":
                continue
            if cr.custom.resource_key == RESOURCE_KEY:
                ietf_data = json.loads(cr.custom.resource_value)
                break
        else:
            raise Exception("ietf data not found")
        slice_services = ietf_data["network-slice-services"]["slice-service"]
        slice_service = slice_services[0]
        slice_sdps = slice_service["sdps"]["sdp"]
        sdp_idx = list((slice_sdp["id"] == sdp_id for slice_sdp in slice_sdps)).index(
            True
        )
        slice_sdps.pop(sdp_idx)
        raise_if_differs = False
        fields = {name: (value, raise_if_differs) for name, value in ietf_data.items()}
        update_config_rule_custom(
            slice_request.slice_config.config_rules, RESOURCE_KEY, fields
        )
        return slice_request

    @staticmethod
    def create_connection_group(
        request_data: dict, slice_id: str, context_client: ContextClient
@@ -145,6 +172,36 @@ class IETFSliceHandler:
        update_config_rule_custom(slice.slice_config.config_rules, RESOURCE_KEY, fields)
        return slice

    @staticmethod
    def delete_connection_group(
        slice_uuid: str, connection_group_id: str, context_client: ContextClient
    ) -> Slice:
        slice_request = get_slice_by_uuid(context_client, slice_uuid)
        for cr in slice_request.slice_config.config_rules:
            if cr.WhichOneof("config_rule") != "custom":
                continue
            if cr.custom.resource_key == RESOURCE_KEY:
                ietf_data = json.loads(cr.custom.resource_value)
                break
        else:
            raise Exception("ietf data not found")
        slice_services = ietf_data["network-slice-services"]["slice-service"]
        slice_service = slice_services[0]
        slice_connection_groups = slice_service["connection-groups"]["connection-group"]
        sdp_idx = list(
            (
                slice_cr["id"] == connection_group_id
                for slice_cr in slice_connection_groups
            )
        ).index(True)
        slice_connection_groups.pop(sdp_idx)
        raise_if_differs = False
        fields = {name: (value, raise_if_differs) for name, value in ietf_data.items()}
        update_config_rule_custom(
            slice_request.slice_config.config_rules, RESOURCE_KEY, fields
        )
        return slice_request

    @staticmethod
    def create_match_criteria(
        request_data: dict, slice_id: str, sdp_id: str, context_client: ContextClient
@@ -237,3 +294,42 @@ class IETFSliceHandler:
            slice_request.slice_config.config_rules, RESOURCE_KEY, fields
        )
        return slice_request

    @staticmethod
    def delete_match_criteria(
        slice_uuid: str,
        sdp_id: str,
        match_criterion_id: int,
        context_client: ContextClient,
    ) -> Slice:
        slice_request = get_slice_by_uuid(context_client, slice_uuid)
        slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
        for cr in slice_request.slice_config.config_rules:
            if cr.WhichOneof("config_rule") != "custom":
                continue
            if cr.custom.resource_key == RESOURCE_KEY:
                ietf_data = json.loads(cr.custom.resource_value)
                break
        else:
            raise Exception("ietf data not found")
        slice_services = ietf_data["network-slice-services"]["slice-service"]
        slice_service = slice_services[0]
        sdps = slice_service["sdps"]["sdp"]
        for sdp in sdps:
            if sdp["id"] == sdp_id:
                match_criteria = sdp["service-match-criteria"]["match-criterion"]
                match_criterion_idx = [
                    match_criterion["index"] == match_criterion_id
                    for match_criterion in match_criteria
                ].index(True)
                del match_criteria[match_criterion_idx]
                break
        else:
            raise Exception("Second SDP not found")

        raise_if_differs = False
        fields = {name: (value, raise_if_differs) for name, value in ietf_data.items()}
        update_config_rule_custom(
            slice_request.slice_config.config_rules, RESOURCE_KEY, fields
        )
        return slice_request
Loading