Skip to content
network_slice_controller.py 59.3 KiB
Newer Older
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
Javier Velázquez's avatar
Javier Velázquez committed

# 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.

# This file includes original contributions from Telefonica Innovación Digital S.L.

Javier Velázquez's avatar
Javier Velázquez committed
import json, time, os, logging, uuid, traceback, sys
Javier Velázquez's avatar
Javier Velázquez committed
from datetime import datetime
from src.helpers import tfs_connector, cisco_connector
from src.Constants import DEFAULT_LOGGING_LEVEL, TFS_IP, TFS_L2VPN_SUPPORT, IXIA_IP, SRC_PATH, TEMPLATES_PATH, DUMMY_MODE, DUMP_TEMPLATES, PLANNER_ENABLED, NRP_ENABLED, UPLOAD_TYPE, NBI_L2_PATH, NBI_L3_PATH
Javier Velázquez's avatar
Javier Velázquez committed
from src.realizers.ixia.NEII_V4 import NEII_controller
Javier Velázquez's avatar
Javier Velázquez committed
from src.planner.planner import Planner
Javier Velázquez's avatar
Javier Velázquez committed

# Configure logging to provide clear and informative log messages
logging.basicConfig(
    level=DEFAULT_LOGGING_LEVEL,
    format='%(levelname)s - %(message)s')

class NSController:
    """
    Network Slice Controller (NSC) - A class to manage network slice creation, 
    modification, and deletion across different network domains.

    This controller handles the translation, mapping, and realization of network 
    slice intents from different formats (3GPP and IETF) to network-specific 
    configurations.

    Key Functionalities:
    - Intent Processing: Translate and process network slice intents
    - Slice Management: Create, modify, and delete network slices
    - NRP (Network Resource Partition) Mapping: Match slice requirements with available resources
    - Slice Realization: Convert intents to specific network configurations (L2VPN, L3VPN)
    """

    def __init__(self, controller_type = "TFS", tfs_ip=TFS_IP, ixia_ip =IXIA_IP, need_l2vpn_support=TFS_L2VPN_SUPPORT): 
Javier Velázquez's avatar
Javier Velázquez committed
        """
        Initialize the Network Slice Controller.

        Args:
Javier Velázquez's avatar
Javier Velázquez committed
            controller_type (str): Flag to determine if configurations 
                should be uploaded to Teraflow or IXIA system.
Javier Velázquez's avatar
Javier Velázquez committed
            need_l2vpn_support (bool, optional): Flag to determine if additional
                L2VPN configuration support is required. Defaults to False.
        
        Attributes:
Javier Velázquez's avatar
Javier Velázquez committed
            controller_type (str): Flag for Teraflow or Ixia upload
Javier Velázquez's avatar
Javier Velázquez committed
            answer (dict): Stores slice creation responses
            start_time (float): Tracks slice setup start time
            end_time (float): Tracks slice setup end time
            need_l2vpn_support (bool): Flag for additional L2VPN configuration support
        """
Javier Velázquez's avatar
Javier Velázquez committed
        self.controller_type = controller_type
Javier Velázquez's avatar
Javier Velázquez committed
        self.tfs_ip = tfs_ip
Javier Velázquez's avatar
Javier Velázquez committed
        self.answer = {}
        self.cool_answer = {}
        self.start_time = 0
        self.end_time = 0
        self.setup_time = 0
        self.need_l2vpn_support = need_l2vpn_support
        # Internal templates and views
        self.__gpp_template = ""
        self.__ietf_template = ""
        self.__teraflow_template = ""
        self.__nrp_view = ""
        self.subnet=""

    # API Methods
    def add_flow(self, intent):
        """
        Create a new transport network slice.

        Args:
            intent (dict): Network slice intent in 3GPP or IETF format

        Returns:
            Result of the Network Slice Controller (NSC) operation

        API Endpoint:
            POST /slice

        Raises:
            ValueError: If no transport network slices are found
            Exception: For unexpected errors during slice creation process
        """
        return self.nsc(intent)

    def get_flows(self,slice_id=None):
        """
        Retrieve transport network slice information.

        This method allows retrieving:
        - All transport network slices
        - A specific slice by its ID

        Args:
            slice_id (str, optional): Unique identifier of a specific slice. 
                                      Defaults to None.

        Returns:
            dict or list: 
            - If slice_id is provided: Returns the specific slice details
            - If slice_id is None: Returns a list of all slices
            - Returns an error response if no slices are found

        API Endpoint:
            GET /slice/{id}

        Raises:
            ValueError: If no transport network slices are found
            Exception: For unexpected errors during file processing
        """
        try:
            # Read slice database from JSON file
            with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'r') as file:
                content = json.load(file)
            # If specific slice ID is provided, find and return matching slice
            if slice_id:
                for slice in content:
                    if slice["slice_id"] == slice_id:
                        return slice
            # If no slices exist, raise an error
            if len(content) == 0:
                raise ValueError("Transport network slices not found")
            
            # Return all slices if no specific ID is given
Javier Velázquez's avatar
Javier Velázquez committed
            return [slice for slice in content if slice.get("controller") == self.controller_type]
Javier Velázquez's avatar
Javier Velázquez committed
        
        except ValueError as e:
            # Handle case where no slices are found
            return self.__send_response(False, code=404, message=str(e))
        except Exception as e:
            # Handle unexpected errors
            return self.__send_response(False, code=500, message=str(e))

    def modify_flow(self,slice_id, intent):
        """
        Modify an existing transport network slice.

        Args:
            slice_id (str): Unique identifier of the slice to modify
            intent (dict): New intent configuration for the slice

        Returns:
            Result of the Network Slice Controller (NSC) operation

        API Endpoint:
            PUT /slice/{id}
        """
        return self.nsc(intent, slice_id)

    def delete_flows(self, slice_id=None):
        """
        Delete transport network slice(s).

        This method supports:
        - Deleting a specific slice by ID
        - Deleting all slices
        - Optional cleanup of L2VPN configurations

        Args:
            slice_id (str, optional): Unique identifier of slice to delete. 
                                      Defaults to None.

        Returns:
            dict: Response indicating successful deletion or error details

        API Endpoint:
            DELETE /slice/{id}

        Raises:
            ValueError: If no slices are found to delete
            Exception: For unexpected errors during deletion process

        Notes:
Javier Velázquez's avatar
Javier Velázquez committed
            - If controller_type is TFS, attempts to delete from Teraflow
Javier Velázquez's avatar
Javier Velázquez committed
            - If need_l2vpn_support is True, performs additional L2VPN cleanup
        """
        try:
            # Read current slice database
            with open(os.path.join(SRC_PATH, "slice_ddbb.json"), 'r') as file:
                content = json.load(file)
            id = None

            # Delete specific slice if slice_id is provided
            if slice_id:
                for i, slice in enumerate(content):
Javier Velázquez's avatar
Javier Velázquez committed
                    if slice["slice_id"] == slice_id and slice.get("controller") == self.controller_type:
Javier Velázquez's avatar
Javier Velázquez committed
                        del content[i]
                        id = i
Loading
Loading full blame...