Loading src/helpers.py +150 −4 Original line number Diff line number Diff line Loading @@ -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') Loading Loading @@ -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 src/network_slice_controller.py +189 −202 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/helpers.py +150 −4 Original line number Diff line number Diff line Loading @@ -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') Loading Loading @@ -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
src/network_slice_controller.py +189 −202 File changed.Preview size limit exceeded, changes collapsed. Show changes