Commit 910cc1dd authored by Pablo Armingol's avatar Pablo Armingol
Browse files

Enhance NSController with new generate_rules function and refactor slice handling logic

parent 8bd4d91b
Loading
Loading
Loading
Loading
+150 −4
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@
import json
import logging
import os
import uuid
import requests
from netmiko import ConnectHandler
from src.constants import DEFAULT_LOGGING_LEVEL, SRC_PATH
from src.constants import DEFAULT_LOGGING_LEVEL

# Configure logging to provide clear and informative log messages
logging.basicConfig(
    level=DEFAULT_LOGGING_LEVEL,
    format='%(levelname)s - %(message)s')
@@ -174,10 +174,156 @@ def send_network_slice_request(data: str, action: str = "create") -> dict:
        logging.error(f"HTTP request failed: {e}")
        return {}


    # Comprobar y devolver la respuesta
    if response.ok:
        return response.json()
    else:
        print(f"Request failed with status code {response.status_code}: {response.text}")
        response.raise_for_status()

def group_block(group, action, group_id_override=None):
    active   = "true" if action == 'create' else "false"
    group_id = group_id_override if group_id_override is not None else group["digital_sub_carriers_group_id"]

    return {
        "digital_sub_carriers_group_id": group_id,
        "digital_sub_carrier_id": [
            {
                "sub_carrier_id": sid,
                "active": active,
            }
            for sid in group["subcarrier-id"]
        ]
    }

def generate_rules(connectivity_service, intent, action):
    src_name     = connectivity_service.get("source", "FALTA VALOR")
    dest_list    = connectivity_service.get("destination", ["FALTA VALOR"])
    dest_str     = ",".join(dest_list)
    config_rules = []

    network_slice_uuid_str = f"{src_name}_to_{dest_str}"
    tunnel_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, network_slice_uuid_str))
    provisionamiento = {
        "network-slice-uuid": network_slice_uuid_str,
        "viability": True,
        "actions": []
    }

    attributes = connectivity_service["connectivity-service"]["tapi-connectivity:connectivity-service"]["connection"][0]["optical-connection-attributes"]
    groups = attributes["subcarrier-attributes"]["digital-subcarrier-group"]
    # central_freq = (attributes["central-frequency"])
    # tx_power = (attributes["Tx-power"])
    # spacing = attributes["digital-subcarrier-spacing"]
    operational_mode = attributes["modulation"]["operational-mode"]
    # port = attributes["modulation"]["port"]
    hub_groups = [
        group_block(group, action, group_id_override=index + 1)
        for index, group in enumerate(groups)
    ]
    hub = {
        "name":      "channel-1",
        "frequency": 195000000,
        "target_output_power": 0,
        "operational_mode": operational_mode,
        "operation" :       "merge",
        "digital_sub_carriers_group": hub_groups
    }

    leaves = []
    for dest, group in zip(connectivity_service["destination"], groups):
        if dest == "T1.1": 
            name = "channel-1"
            freq = 195006250
        elif dest == "T1.2": 
            name =   "channel-3"
            freq =   195018750
        else: 
            name = "channel-5"
            freq = 195031250

        leaf = {
            "name": name,
            "frequency": freq,
            "target_output_power": group["Tx-power"],
            "operational_mode": int(group["operational-mode"]),
            "operation" : "merge",
            "digital_sub_carriers_group": [group_block(group, action, group_id_override=1)]
        }
        leaves.append(leaf)

    final_json = {"components": [hub] + leaves}

    if action == 'create':
        provisionamiento["actions"].append({
            "type":   "XR_AGENT_ACTIVATE_TRANSCEIVER",
            "layer":  "OPTICAL",
            "content": final_json,
            "controller-uuid": "IPoWDM Controller"
        })

        nodes = {}
        sdp_list = intent['ietf-network-slice-service:network-slice-services']['slice-service'][0]['sdps']['sdp']

        for sdp in sdp_list:
            node = sdp['node-id']
            attachments = sdp['attachment-circuits']['attachment-circuit']
            for ac in attachments:
                ip = ac.get('ac-ipv4-address', None)
                prefix = ac.get('ac-ipv4-prefix-length', None)
                last_octet = int(ip.split('.')[-1]) if ip else 0
                vlan = 100 + last_octet
                nodes[node] = {
                    "ip-address": ip,
                    "ip-mask":    prefix,
                    "vlan-id":    vlan
                }
            
        provisionamiento["actions"].append({
            "type": "CONFIG_VPNL3",
            "layer": "IP",
            "content": {
                "tunnel-uuid":      tunnel_uuid,
                "src-node-uuid":    src_name,
                "src-ip-address":   nodes[src_name]["ip-address"],
                "src-ip-mask":      str(nodes[src_name]["ip-mask"]),
                "src-vlan-id":      nodes[src_name]["vlan-id"],
                "dest1-node-uuid":  dest_list[0],
                "dest1-ip-address": nodes[dest_list[0]]["ip-address"],
                "dest1-ip-mask":    str(nodes[dest_list[0]]["ip-mask"]),
                "dest1-vlan-id":    nodes[dest_list[0]]["vlan-id"],
                "dest2-node-uuid":  dest_list[1],
                "dest2-ip-address": nodes[dest_list[1]]["ip-address"],
                "dest2-ip-mask":    str(nodes[dest_list[1]]["ip-mask"]),
                "dest2-vlan-id":    nodes[dest_list[1]]["vlan-id"]
        },
            "controller-uuid": "IP Controller"
        })
            
        config_rules.append(provisionamiento)
    else:
        nodes = []
        nodes.append(src_name)
        for dst in dest_list: nodes.append(dst)
        aux = tunnel_uuid + '-' + src_name + '-' + '-'.join(dest_list)
        provisionamiento["actions"].append({
        "type":  "DEACTIVATE_XR_AGENT_TRANSCEIVER",
        "layer": "OPTICAL",
        "content": final_json,
        "controller-uuid": "IPoWDM Controller",
        "uuid" : aux,
        "nodes": nodes
        })
        config_rules.append(provisionamiento)

    return config_rules

def get_sip_from_name(context, node_name):

    context = context.json()
    topologies = context.get("tapi-topology:topology-context", {}).get("topology", [])
    for topology in topologies:
        nodes = topology.get("nodes", [])
        for node in nodes:
            if node.get("name") == node_name:
                return node.get("uuid")
    return None  
+189 −202

File changed.

Preview size limit exceeded, changes collapsed.