Commit 28f953b8 authored by Maria Ruiz's avatar Maria Ruiz
Browse files

implementaciones planner

parent 3b4c4f81
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -446,11 +446,18 @@ class NSController:
        if PLANNER_ENABLED:

            if self.controller_type == "sat":
                optimal_path = SATPlanner().satplanner(ietf_intent)
                logging.info(f"Optimal path: {optimal_path}")  
                viability = SATPlanner().satplanner(ietf_intent)
                if viability == "error":
                    logging.info(f"Resource allocation : Not enough satellite resources")
                elif viability == "ok":
                    logging.info(f"Resource allocation : Sufficient satellite resources available")
                else:
                    logging.info(f"Resource allocation : Partial resources available, need to configure shaper with CIR {viability} ")
                    return viability
                 
            else:
                viability = Planner().planner(ietf_intent)
                logging.info(f"Resource allocation in the satellite segment: {viability}")
                logging.info(f"Resource allocation : {viability}")

    def __realizer(self, ietf_intent, need_nrp=False, order=None, nrp=None):
        """
@@ -1351,6 +1358,11 @@ class NSController:
            elif metric_type == "one-way-delay-variation-maximum": 
                tolerance = bound   

        if self.__mapper(ietf_intent) != "ok" and self.__mapper(ietf_intent) != "error":
            cir = self.__mapper(ietf_intent)
        else:
            cir = None

        # Construcción del diccionario intent
        intent_nms = {
            
@@ -1389,6 +1401,7 @@ class NSController:
            "bandwidth": bandwidth,
            "latency": latency,
            "tolerance": tolerance,
            "CIR": cir

        }
        intent_sat = {
+22 −18
Original line number Diff line number Diff line
@@ -23,24 +23,28 @@ class SATPlanner:
    """
    def satplanner(self, intent):

        resources = self.__retrieve_resources()

        type = intent.get("ietf-network-slice-service:network-slice-services", {}).get("slo-sle-templates", {}).get("slo-sle-template", [])[0].get("id")
        source = intent.get("ietf-network-slice-service:network-slice-services", {}).get("slice-service", [])[0].get("sdps", {}).get("sdp", [])[0].get("node-id") 
        destination = intent.get("ietf-network-slice-service:network-slice-services", {}).get("slice-service", [])[0].get("sdps", {}).get("sdp", [])[1].get("node-id") 
        service = intent.get("ietf-network-slice-service:network-slice-services", {}).get("slice-service", [])[0].get("sdps", {}).get("sdp", [])[0].get("match-criterion",[]).get("match-type")
        serviceid = intent.get("ietf-network-slice-service:network-slice-services", {}).get("slice-service", [])[0].get("sdps", {}).get("sdp", [])[0].get("match-criterion",[]).get("value")
        bandwidth = intent.get("ietf-network-slice-service:network-slice-services", {}).get("slo-sle-templates", {}).get("slo-sle-template", [])[0].get("slo-policy", {}).get("metric-bound",[])[0].get("bound")
        delay =  intent.get("ietf-network-slice-service:network-slice-services", {}).get("slo-sle-templates", {}).get("slo-sle-template", [])[0].get("slo-policy", {}).get("metric-bound",[])[1].get("bound")



        return {""}

    def __retrieve_resources(self):
       
        #primero comprobamos los recursos disponibles 
        with open(os.path.join(SRC_PATH, "planner/sat_resurces_ddbb.json"), "r") as archivo:
            resources = json.load(archivo)
      
        return resources
            data = json.load(archivo)

        links = data["satellite-segment-nodes"][0]["links"]["link"]
        total = sum(link.get("bandwidth", 0) for link in links)

        print("Total occupied bandwidth in satellite resources:", total)

        if total >= 140:
            print("There are not enough satellite resources to allocate the requested network slice.")
            viability = "error"
            return viability
        else:
            disponible = 140 - total
            if bandwidth <= disponible:
                viability = "ok"
                return viability
            elif type == "A":
                extra = bandwidth - disponible 
                P4_cir = extra - 5 # CIR que hab´ra que configurar en el shaper para limitar el trafico de menor prioridad
                return P4_cir
+2 −2
Original line number Diff line number Diff line
@@ -10,20 +10,20 @@
            "link":[
                {
                    "link-id": "1",
                    "vlan-id": "106",
                    "slo-profile":"A",
                    "type": "GEO" ,
                    "bandwidth": 4,
                    "capacity": 10,
                    "latency": 50,
                    "FRW_frequency": 1200000,
                    "RTN_frequency": 1338000                   
                },
                {
                    "link-id": "2",
                    "vlan-id": "106",
                    "slo-profile":"B",
                    "type": "LEO" ,
                    "bandwidth": 8,
                    "capacity": 20,
                    "latency": 30,
                    "FRW_frequency": 12000004,
                    "RTN_frequency": 1338000                   
+120 −44
Original line number Diff line number Diff line
@@ -14,12 +14,10 @@

# This file is an original contribution from Telefonica Innovación Digital S.L.

import logging
import requests
import logging, requests, json, os
from requests.auth import HTTPBasicAuth
from http import HTTPStatus
from src.Constants import SATNMS_IP
import json
from src.Constants import SATNMS_IP, SRC_PATH

class SAT_NMS:
    
@@ -30,7 +28,7 @@ class SAT_NMS:
        
        print(f'\n\n{json_data}\n')

        logging.info("Procesando petición")
        logging.info("Processing satellite slice request")

        src_node_id = json_data.get("src_node_id", None)
        dst_node_ip = json_data.get("dst_node_id", None)
@@ -44,12 +42,15 @@ class SAT_NMS:

        shaper = None
        bandwidth = None
        validation = None

        new_service = self.new_service(self.satnms_ip, vlan_id)
        #creación se servicio L2_bridge en el NMS
        new_service, validation = self.new_service(self.satnms_ip, vlan_id)
        if validation == "error":
            return

        if new_service is not None:
            num_service = new_service.get("reply",{}).get("%row")
            
            #mapeo QoS:
            if QoS_profile == "A":
                qos_mapped = "qos:0 QoS_P7"
@@ -61,22 +62,42 @@ class SAT_NMS:
            else:
                qos_mapped = "qos:0 QoS_P7" #default

            add_route_controller = self.add_routes_controller(self.satnms_ip, num_service, vlan_id, qos_mapped)
            #se añaden ñas rutas ligadas al nuevo servicio y al QoS tanto en HUB como STATION:

            add_route_controller, validation = self.add_routes_controller(self.satnms_ip, num_service, vlan_id, qos_mapped)
            if validation == "error":
                return
            else:
                print(f'\n\n{add_route_controller}\n')

            add_route_station = self.add_routes_station(self.satnms_ip, num_service, vlan_id, qos_mapped)
            add_route_station, validation = self.add_routes_station(self.satnms_ip, num_service, vlan_id, qos_mapped)
            if validation == "error":
                return
            else:
                print(f'\n\n{add_route_station}\n')


            #cambio del bandwidth en función del symbol rate. Aquí ojoporque lo que soporta el NMS es limitado. Mejor para las pruebas a none y reefinar si queda tiempo 
            if bandwidth is not None:
                change_symbol_rate = self.change_symbol_rate(self.satnms_ip, bandwidth)
                change_symbol_rate, validation = self.change_symbol_rate(self.satnms_ip, bandwidth)
                if validation == "error":
                    return  
                else:
                    print(f'\n\n{change_symbol_rate}\n')

            #Si se ha asociado a algun flujo QoS:P7 se aplicar shaper 1 al resto de flujos de menor prioridad. Limitar CIR a 30Mbps 
            if shaper is not None:
                shaper_applied = self.shaper(self.satnms_ip, shaper)
                shaper_applied, validation = self.shaper(self.satnms_ip, shaper)
                if validation == "error":
                    return  
                else:
                    print(f'\n\n{shaper_applied}\n')

            self.actualizacion_ddbb(json_data)


        else: 
            print("No se pudo crear la Slice")
            print("Unable to create the Slice in the satellite segment")

    def loggin_NMS(self,ip):

@@ -92,14 +113,17 @@ class SAT_NMS:
            
        else:
            print(f"error al obtener la informacion de la IP; {response.status_code}")
            return None
            validation = "error"
            return validation
    
    def new_service(self,ip, vlan_id):

        #creación se servicio L2_bridge en el NMS

        session = self.loggin_NMS(ip)

        if session is None:
            print("No se pudo iniciar sesion en el NMS")
            print("Unable to log in the NMS")
            return None

        url= "http://"+ip+":8000/api/object/write/network=0/new_item=service"
@@ -129,18 +153,20 @@ class SAT_NMS:
        error_code = response.json().get("error_code",None)

        if response.status_code==200 and error_code !="0":
            logging.info("servicio creado en el NMS")
            return response.json()
            logging.info("New service created in the NMS")
            validation = "ok"
            return response.json(),validation
        else:
            print(f"Error al crear el servicio; error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            return None
            print(f"NMS Error creating service; error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            validation = "error"
            return validation
        
    def add_routes_controller(self,ip, num_service, vlan_id, qos_mapped):

        session = self.loggin_NMS(ip)
        
        if session is None:
            print("No se pudo iniciar sesion en el NMS")
            print("Unable to log in the NMS")
            return None
        
        #Añadir la ruta al controller: 
@@ -159,19 +185,21 @@ class SAT_NMS:
        error_code = response.json().get("error_code",None)

        if response.status_code==200 and error_code !="0":
            logging.info("Nueva ruta añadida en HUB")
            logging.info("New route added: HUB")
            validation = "ok"
            #print(f'\n\n{payload}\n')
            return response.json()
            return response.json(), validation
        else:
            print(f"Error al añadir la ruta en HUB; error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            return None
            print(f"Error adding the route: HUB; error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            validation = "error"
            return validation

    def add_routes_station(self,ip, num_service, vlan_id, qos_mapped):

        session = self.loggin_NMS(ip)
        
        if session is None:
            print("No se pudo iniciar sesion en el NMS")
            print("Unable to log in the NMS")
            return None
        
        #Añadir la ruta al controller: 
@@ -190,11 +218,13 @@ class SAT_NMS:
        error_code = response.json().get("error_code",None)

        if response.status_code==200 and error_code !="0":
            logging.info("Nueva ruta añadida en STATION")
            return response.json()
            logging.info("New route added: STATION")
            validation = "ok"
            return response.json(), validation
        else:
            print(f"Error al añadir la ruta en STATION;  error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            return None      
            print(f"Error adding the route: STATION;  error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            validation = "error"
            return validation      
                  
    def change_symbol_rate(self,ip,bw):
        
@@ -202,7 +232,7 @@ class SAT_NMS:
        #Bw viene dado en Kbps

        if bw>300:
            print("Throughput no soportado")
            print("Unsupported throughput")
            return None 
        else:   
            bpsym = int(4) # bits por simbolo 16APSK
@@ -214,7 +244,7 @@ class SAT_NMS:
            session = self.loggin_NMS(ip)

            if session is None:
                print("No se pudo iniciar sesion en el NMS")
                print("Unable to log in the NMS")
                return None
    
            url = "http://"+ip+":8000/api/object/write/controller=0"
@@ -236,11 +266,13 @@ class SAT_NMS:
            error_code_s = response_s.json().get("error_code",None)

            if response_c.status_code==200 and response_s.status_code==200 and error_code_c !="0" and error_code_s !="0":
                logging.info("Symbol rate"+str(symbol_rate)+" modificado en HUB y STATION")
                return response_s.json()
                logging.info("Symbol rate"+str(symbol_rate)+" modified at: HUB y STATION")
                validation = "ok"
                return response_s.json(),validation
            else:
                print(f"Error modificar el Symbol rate; HUB error code:"+str(response_c.json().get("error_code",None))+ "; HUB error log: "+str(response_c.json().get("error_log",None))+"; STATION error code:"+str(response_s.json().get("error_code",None))+ "; STATION error log: "+str(response_s.json().get("error_log",None)))
                return None
                print(f"Error modifying Symbol rate; HUB error code:"+str(response_c.json().get("error_code",None))+ "; HUB error log: "+str(response_c.json().get("error_log",None))+"; STATION error code:"+str(response_s.json().get("error_code",None))+ "; STATION error log: "+str(response_s.json().get("error_log",None)))
                validation = "error"
                return validation

    def shaper(self,ip,shaper):
        
@@ -261,16 +293,60 @@ class SAT_NMS:
        error_code = response.json().get("error_code",None)

        if response.status_code==200 and error_code !="0":
            logging.info("Shaper aplicado")
            return response.json()
            logging.info("Shaper applied")
            validation = "ok"
            return response.json(), validation
        else:
            print(f"Error al aplicar el shaper; error code:"+str(response.json().get("error_code",None))+ "; error log: "+str(response.json().get("error_log",None)))
            validation = "error"
            return validation
        
    def get_controller_data(self,ip):
        
        session = self.loggin_NMS(ip)

        if session is None:
            print("Unable to log in the NMS")
            return None

def actualizacion_ddbb():
    #función para actualizar el estado de los recursos en la BBDD. importante que sea una vez que se haya realizado la configuración en el NMS 
    return
        url= "http://"+ip+":8000/api/object/get/controller=0"

        response = requests.get(url, cookies=session, auth=('admin', '12345'))
        return response.json()

    def actualizacion_ddbb(self,json_data,ip):
    
    #función para actualizar el estado de los recursos en la BBDD. importante que sea una vez que se haya realizado la configuración en el NMS 
    #si el resto de funciones se han realizado con éxito se añade el link en la BBDD

        vlan_id = json_data.get("vlan_id", None)
        QoS_profile = json_data.get("QoS_profile", None)
        bandwidth = json_data.get("bandwidth", None)
        latency = json_data.get("latency", None)

        if latency < 30:
            type = "LEO"
        else:
            type = "GEO"

        FRW_frequency = self.get_controller_data(ip).get("tx_freq", None)
        RTN_frequency = self.get_controller_data(ip).get("rx_freq", None)

        with open(os.path.join(SRC_PATH, "planner/sat_resurces_ddbb.json"), "r") as archivo:
            data = json.load(archivo)
        links = data["satellite-segment-nodes"][0]["links"]["link"]
        next_id = len(links) + 1
        new_link = {
            "id": str(next_id),
            "vlan-id": vlan_id,
            "slo-profile":QoS_profile,
            "type": type,
            "bandwidth": bandwidth,
            "latency": latency,
            "FRW_frequency": FRW_frequency,
            "RTN_frequency": RTN_frequency     
        }
        links.append(new_link)
        with open(os.path.join(SRC_PATH, "planner/sat_resurces_ddbb.json"), "w") as archivo:
            json.dump(data, archivo, indent=4)      
            logging.info("Database updated with new link")    
 No newline at end of file