Loading app.py +2 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ from flask_cors import CORS from swagger.tfs_namespace import tfs_ns from swagger.tfs_namespace import tfs_ns from swagger.ixia_namespace import ixia_ns from swagger.ixia_namespace import ixia_ns from swagger.sat_namespace import sat_ns from swagger.sat_namespace import sat_ns from swagger.SDN_namespace import sat_sdn from src.Constants import NSC_PORT, WEBUI_DEPLOY from src.Constants import NSC_PORT, WEBUI_DEPLOY from src.webui.gui import gui_bp from src.webui.gui import gui_bp Loading @@ -40,6 +41,7 @@ api = Api( api.add_namespace(tfs_ns, path="/tfs") api.add_namespace(tfs_ns, path="/tfs") api.add_namespace(ixia_ns, path="/ixia") api.add_namespace(ixia_ns, path="/ixia") api.add_namespace(sat_ns, path="/sat") #MR api.add_namespace(sat_ns, path="/sat") #MR api.add_namespace(sat_sdn, path="/sdn") #MR #gui_bp = Blueprint('gui', __name__, template_folder='templates') #gui_bp = Blueprint('gui', __name__, template_folder='templates') if WEBUI_DEPLOY: if WEBUI_DEPLOY: Loading src/Constants.py +4 −0 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,9 @@ PLANNER_ENABLED = True PCE_EXTERNAL = False PCE_EXTERNAL = False # Realizer # Realizer #sat imp options: #option 1: SDN CONTROLLER #SAT_SDN = True # Controller Flags # Controller Flags # If True, config is not sent to controllers # If True, config is not sent to controllers Loading @@ -69,6 +72,7 @@ IXIA_IP = ips.get('IXIA_IP') #####SATNMS##### #####SATNMS##### # SAT NMS IP # SAT NMS IP SATNMS_IP = ips.get('SATNMS_IP') SATNMS_IP = ips.get('SATNMS_IP') SATSDN_IP = ips.get('SATSDN_IP') # WebUI # WebUI Loading src/IPs.json +2 −1 Original line number Original line Diff line number Diff line { { "TFS_IP": "192.168.27.165", "TFS_IP": "192.168.27.165", "IXIA_IP": "192.168.27.59", "IXIA_IP": "192.168.27.59", "SATNMS_IP": "192.168.27.31" "SATNMS_IP": "192.168.27.31", "SATSDN_IP": "192.168.27.227" } } No newline at end of file src/network_slice_controller.py +74 −4 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ from src.Constants import DEFAULT_LOGGING_LEVEL, TFS_IP, TFS_L2VPN_SUPPORT, IXIA from src.realizers.ixia.NEII_V4 import NEII_controller from src.realizers.ixia.NEII_V4 import NEII_controller from src.realizers.sat.SATNMS import SAT_NMS from src.realizers.sat.SATNMS import SAT_NMS from src.realizers.sat.SATRM import SAT_RM from src.realizers.sat.SATRM import SAT_RM from src.realizers.sat.SATSDN import SAT_SDN from src.planner.planner import Planner from src.planner.planner import Planner from src.planner.sat_planner import SATPlanner from src.planner.sat_planner import SATPlanner Loading @@ -45,7 +46,7 @@ class NSController: - Slice Realization: Convert intents to specific network configurations (L2VPN, L3VPN) - Slice Realization: Convert intents to specific network configurations (L2VPN, L3VPN) """ """ def __init__(self, controller_type = "sat", tfs_ip=TFS_IP, ixia_ip =IXIA_IP, need_l2vpn_support=TFS_L2VPN_SUPPORT, satnms_ip=SATNMS_IP): def __init__(self, controller_type = None, tfs_ip=TFS_IP, ixia_ip =IXIA_IP, need_l2vpn_support=TFS_L2VPN_SUPPORT, satnms_ip=SATNMS_IP): """ """ Initialize the Network Slice Controller. Initialize the Network Slice Controller. Loading Loading @@ -302,7 +303,7 @@ class NSController: else: else: tfs_request = self.__realizer(intent) tfs_request = self.__realizer(intent) requests["services"].append(tfs_request) requests["services"].append(tfs_request) logging.info("Realizing request: {tfs_request}") logging.info(f"Realizing request: {tfs_request}") else: else: return self.__send_response(False, code=404, message="No intents found") return self.__send_response(False, code=404, message="No intents found") Loading @@ -314,6 +315,9 @@ class NSController: if DUMP_TEMPLATES: if DUMP_TEMPLATES: with open(os.path.join(TEMPLATES_PATH, "realizer_template_sat.json"), "w") as archivo: with open(os.path.join(TEMPLATES_PATH, "realizer_template_sat.json"), "w") as archivo: archivo.write(json.dumps(requests2,indent=2)) archivo.write(json.dumps(requests2,indent=2)) elif self.controller_type == "sdn": with open(os.path.join(TEMPLATES_PATH, "realizer_template_sdn.json"), "w") as archivo: archivo.write(json.dumps(requests,indent=2)) # Optional: Upload template to Teraflow # Optional: Upload template to Teraflow if not DUMMY_MODE: if not DUMMY_MODE: Loading Loading @@ -345,9 +349,18 @@ class NSController: sat_nms = SAT_NMS() sat_nms = SAT_NMS() sat_rm = SAT_RM() sat_rm = SAT_RM() for intent in requests["services"]: for intent in requests["services"]: logging.info("Request sent to SATELLITE NMS") sat_nms.nscSATNMS(intent) sat_nms.nscSATNMS(intent) logging.info("Request sent to SATELLITE SNO") sat_rm.nscSATRM(intent) sat_rm.nscSATRM(intent) logging.info("Request sent to SATELLITE NMS") elif self.controller_type == "sdn": sat_sdn = SAT_SDN() for intent in requests["services"]: logging.info("Request sent to NTN SDN controller ") sat_sdn.nscSATSDN(intent) # End performance tracking # End performance tracking self.end_time = time.perf_counter() self.end_time = time.perf_counter() Loading Loading @@ -871,6 +884,8 @@ class NSController: realizing_request = self.__ixia(ietf_intent) realizing_request = self.__ixia(ietf_intent) elif controller == "sat": elif controller == "sat": realizing_request_nms, realizing_request_sat = self.__sat(ietf_intent) realizing_request_nms, realizing_request_sat = self.__sat(ietf_intent) elif controller == "sdn": realizing_request = self.__sdn(ietf_intent) else: else: logging.warning(f"Unsupported controller: {controller}. Defaulting to TFS L2VPN realization.") logging.warning(f"Unsupported controller: {controller}. Defaulting to TFS L2VPN realization.") realizing_request = self.__tfs_l2vpn(ietf_intent) realizing_request = self.__tfs_l2vpn(ietf_intent) Loading Loading @@ -1420,3 +1435,58 @@ class NSController: logging.info(f"SATELLITE Intent realized\n") logging.info(f"SATELLITE Intent realized\n") return intent_nms, intent_sat return intent_nms, intent_sat def __sdn(self,ietf_intent): self.answer[self.subnet]["QoS Requirements"] = [] # Add service constraints for i, constraint in enumerate(ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"]): bound = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["bound"] metric_type = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["metric-type"] metric_unit = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["metric-unit"] service_constraint ={ "custom": { "constraint_type": f"{metric_type}[{metric_unit}]", "constraint_value": f"{bound}" } } self.answer[self.subnet]["QoS Requirements"].append(service_constraint["custom"]) self.answer[self.subnet]["VLAN"] = ietf_intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["service-match-criteria"]["match-criterion"][0]["value"] # Extraer la lista de métricas de forma segura metric_bounds = ietf_intent.get("ietf-network-slice-service:network-slice-services", {}) \ .get("slo-sle-templates", {}) \ .get("slo-sle-template", [{}])[0] \ .get("slo-policy", {}) \ .get("metric-bound", []) # Inicializar valores bandwidth = None latency = None tolerance = None # Asignar valores según el tipo de métrica for metric in metric_bounds: metric_type = metric.get("metric-type") bound = metric.get("bound") if metric_type == "one-way-bandwidth": bandwidth = bound elif metric_type == "one-way-delay-maximum": latency = bound elif metric_type == "one-way-delay-variation-maximum": tolerance = bound intent_sdn ={ "microwave-model:air-interface-configuration": { "air-interface-name": ietf_intent.get("ietf-network-slice-service:network-slice-services", {}) .get("slice-service", [{}])[0] .get("sdps", {}).get("sdp", [{}])[0] .get("node-id"), "tx-rate": bandwidth, "tx-power": -300, "tx-frequency": 1202000000, } } logging.info(f"SDN satellite intent realized\n") return intent_sdn src/planner/sat_resources_ddbb.json +10 −0 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,16 @@ "latency": 20, "latency": 20, "FRW_frequency": 1200000, "FRW_frequency": 1200000, "RTN_frequency": 1338000 "RTN_frequency": 1338000 }, { "id": "3", "vlan-id": "106", "slo-profile": "A", "type": "LEO", "bandwidth-Mbps": 100, "latency": 20, "FRW_frequency": 1200000, "RTN_frequency": 1338000 } } ] ] } } Loading Loading
app.py +2 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ from flask_cors import CORS from swagger.tfs_namespace import tfs_ns from swagger.tfs_namespace import tfs_ns from swagger.ixia_namespace import ixia_ns from swagger.ixia_namespace import ixia_ns from swagger.sat_namespace import sat_ns from swagger.sat_namespace import sat_ns from swagger.SDN_namespace import sat_sdn from src.Constants import NSC_PORT, WEBUI_DEPLOY from src.Constants import NSC_PORT, WEBUI_DEPLOY from src.webui.gui import gui_bp from src.webui.gui import gui_bp Loading @@ -40,6 +41,7 @@ api = Api( api.add_namespace(tfs_ns, path="/tfs") api.add_namespace(tfs_ns, path="/tfs") api.add_namespace(ixia_ns, path="/ixia") api.add_namespace(ixia_ns, path="/ixia") api.add_namespace(sat_ns, path="/sat") #MR api.add_namespace(sat_ns, path="/sat") #MR api.add_namespace(sat_sdn, path="/sdn") #MR #gui_bp = Blueprint('gui', __name__, template_folder='templates') #gui_bp = Blueprint('gui', __name__, template_folder='templates') if WEBUI_DEPLOY: if WEBUI_DEPLOY: Loading
src/Constants.py +4 −0 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,9 @@ PLANNER_ENABLED = True PCE_EXTERNAL = False PCE_EXTERNAL = False # Realizer # Realizer #sat imp options: #option 1: SDN CONTROLLER #SAT_SDN = True # Controller Flags # Controller Flags # If True, config is not sent to controllers # If True, config is not sent to controllers Loading @@ -69,6 +72,7 @@ IXIA_IP = ips.get('IXIA_IP') #####SATNMS##### #####SATNMS##### # SAT NMS IP # SAT NMS IP SATNMS_IP = ips.get('SATNMS_IP') SATNMS_IP = ips.get('SATNMS_IP') SATSDN_IP = ips.get('SATSDN_IP') # WebUI # WebUI Loading
src/IPs.json +2 −1 Original line number Original line Diff line number Diff line { { "TFS_IP": "192.168.27.165", "TFS_IP": "192.168.27.165", "IXIA_IP": "192.168.27.59", "IXIA_IP": "192.168.27.59", "SATNMS_IP": "192.168.27.31" "SATNMS_IP": "192.168.27.31", "SATSDN_IP": "192.168.27.227" } } No newline at end of file
src/network_slice_controller.py +74 −4 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ from src.Constants import DEFAULT_LOGGING_LEVEL, TFS_IP, TFS_L2VPN_SUPPORT, IXIA from src.realizers.ixia.NEII_V4 import NEII_controller from src.realizers.ixia.NEII_V4 import NEII_controller from src.realizers.sat.SATNMS import SAT_NMS from src.realizers.sat.SATNMS import SAT_NMS from src.realizers.sat.SATRM import SAT_RM from src.realizers.sat.SATRM import SAT_RM from src.realizers.sat.SATSDN import SAT_SDN from src.planner.planner import Planner from src.planner.planner import Planner from src.planner.sat_planner import SATPlanner from src.planner.sat_planner import SATPlanner Loading @@ -45,7 +46,7 @@ class NSController: - Slice Realization: Convert intents to specific network configurations (L2VPN, L3VPN) - Slice Realization: Convert intents to specific network configurations (L2VPN, L3VPN) """ """ def __init__(self, controller_type = "sat", tfs_ip=TFS_IP, ixia_ip =IXIA_IP, need_l2vpn_support=TFS_L2VPN_SUPPORT, satnms_ip=SATNMS_IP): def __init__(self, controller_type = None, tfs_ip=TFS_IP, ixia_ip =IXIA_IP, need_l2vpn_support=TFS_L2VPN_SUPPORT, satnms_ip=SATNMS_IP): """ """ Initialize the Network Slice Controller. Initialize the Network Slice Controller. Loading Loading @@ -302,7 +303,7 @@ class NSController: else: else: tfs_request = self.__realizer(intent) tfs_request = self.__realizer(intent) requests["services"].append(tfs_request) requests["services"].append(tfs_request) logging.info("Realizing request: {tfs_request}") logging.info(f"Realizing request: {tfs_request}") else: else: return self.__send_response(False, code=404, message="No intents found") return self.__send_response(False, code=404, message="No intents found") Loading @@ -314,6 +315,9 @@ class NSController: if DUMP_TEMPLATES: if DUMP_TEMPLATES: with open(os.path.join(TEMPLATES_PATH, "realizer_template_sat.json"), "w") as archivo: with open(os.path.join(TEMPLATES_PATH, "realizer_template_sat.json"), "w") as archivo: archivo.write(json.dumps(requests2,indent=2)) archivo.write(json.dumps(requests2,indent=2)) elif self.controller_type == "sdn": with open(os.path.join(TEMPLATES_PATH, "realizer_template_sdn.json"), "w") as archivo: archivo.write(json.dumps(requests,indent=2)) # Optional: Upload template to Teraflow # Optional: Upload template to Teraflow if not DUMMY_MODE: if not DUMMY_MODE: Loading Loading @@ -345,9 +349,18 @@ class NSController: sat_nms = SAT_NMS() sat_nms = SAT_NMS() sat_rm = SAT_RM() sat_rm = SAT_RM() for intent in requests["services"]: for intent in requests["services"]: logging.info("Request sent to SATELLITE NMS") sat_nms.nscSATNMS(intent) sat_nms.nscSATNMS(intent) logging.info("Request sent to SATELLITE SNO") sat_rm.nscSATRM(intent) sat_rm.nscSATRM(intent) logging.info("Request sent to SATELLITE NMS") elif self.controller_type == "sdn": sat_sdn = SAT_SDN() for intent in requests["services"]: logging.info("Request sent to NTN SDN controller ") sat_sdn.nscSATSDN(intent) # End performance tracking # End performance tracking self.end_time = time.perf_counter() self.end_time = time.perf_counter() Loading Loading @@ -871,6 +884,8 @@ class NSController: realizing_request = self.__ixia(ietf_intent) realizing_request = self.__ixia(ietf_intent) elif controller == "sat": elif controller == "sat": realizing_request_nms, realizing_request_sat = self.__sat(ietf_intent) realizing_request_nms, realizing_request_sat = self.__sat(ietf_intent) elif controller == "sdn": realizing_request = self.__sdn(ietf_intent) else: else: logging.warning(f"Unsupported controller: {controller}. Defaulting to TFS L2VPN realization.") logging.warning(f"Unsupported controller: {controller}. Defaulting to TFS L2VPN realization.") realizing_request = self.__tfs_l2vpn(ietf_intent) realizing_request = self.__tfs_l2vpn(ietf_intent) Loading Loading @@ -1420,3 +1435,58 @@ class NSController: logging.info(f"SATELLITE Intent realized\n") logging.info(f"SATELLITE Intent realized\n") return intent_nms, intent_sat return intent_nms, intent_sat def __sdn(self,ietf_intent): self.answer[self.subnet]["QoS Requirements"] = [] # Add service constraints for i, constraint in enumerate(ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"]): bound = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["bound"] metric_type = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["metric-type"] metric_unit = ietf_intent["ietf-network-slice-service:network-slice-services"]["slo-sle-templates"]["slo-sle-template"][0]["slo-policy"]["metric-bound"][i]["metric-unit"] service_constraint ={ "custom": { "constraint_type": f"{metric_type}[{metric_unit}]", "constraint_value": f"{bound}" } } self.answer[self.subnet]["QoS Requirements"].append(service_constraint["custom"]) self.answer[self.subnet]["VLAN"] = ietf_intent["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["sdps"]["sdp"][0]["service-match-criteria"]["match-criterion"][0]["value"] # Extraer la lista de métricas de forma segura metric_bounds = ietf_intent.get("ietf-network-slice-service:network-slice-services", {}) \ .get("slo-sle-templates", {}) \ .get("slo-sle-template", [{}])[0] \ .get("slo-policy", {}) \ .get("metric-bound", []) # Inicializar valores bandwidth = None latency = None tolerance = None # Asignar valores según el tipo de métrica for metric in metric_bounds: metric_type = metric.get("metric-type") bound = metric.get("bound") if metric_type == "one-way-bandwidth": bandwidth = bound elif metric_type == "one-way-delay-maximum": latency = bound elif metric_type == "one-way-delay-variation-maximum": tolerance = bound intent_sdn ={ "microwave-model:air-interface-configuration": { "air-interface-name": ietf_intent.get("ietf-network-slice-service:network-slice-services", {}) .get("slice-service", [{}])[0] .get("sdps", {}).get("sdp", [{}])[0] .get("node-id"), "tx-rate": bandwidth, "tx-power": -300, "tx-frequency": 1202000000, } } logging.info(f"SDN satellite intent realized\n") return intent_sdn
src/planner/sat_resources_ddbb.json +10 −0 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,16 @@ "latency": 20, "latency": 20, "FRW_frequency": 1200000, "FRW_frequency": 1200000, "RTN_frequency": 1338000 "RTN_frequency": 1338000 }, { "id": "3", "vlan-id": "106", "slo-profile": "A", "type": "LEO", "bandwidth-Mbps": 100, "latency": 20, "FRW_frequency": 1200000, "RTN_frequency": 1338000 } } ] ] } } Loading