Commit 29da50b1 authored by Javier Velázquez's avatar Javier Velázquez
Browse files

Merge branch 'feat/31-tid-new-realizer-for-e2e-optical-slices' into 'develop'

Resolve "(TID) New Realizer for E2E Optical Slices"

See merge request !31
parents 95079a40 d10de4fc
Loading
Loading
Loading
Loading
Loading
+36 −2
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
# This file is an original contribution from Telefonica Innovación Digital S.L.

from ..tfs.helpers.tfs_connector import tfs_connector
import logging, requests
import os

def e2e_connect(requests, controller_ip):
    """ 
@@ -24,5 +26,37 @@ def e2e_connect(requests, controller_ip):
        requests (list): List of requests to be sent to the TFS e2e controller.
        controller_ip (str): IP address of the TFS e2e controller.
    """
    response = tfs_connector().webui_post(controller_ip, requests)

    def _extract_slice_id(payload):
        if isinstance(payload, dict):
            services = payload.get("services")
        else:
            services = payload

        if not services or not isinstance(services, list):
            return None

        first_service = services[0]
        if isinstance(first_service, list) and first_service:
            first_service = first_service[0]

        if not isinstance(first_service, dict):
            return None

        slice_id = first_service.get("service_id", {}).get("service_uuid", {}).get("uuid")
        if slice_id:
            return slice_id

        rule_set = first_service.get("rule_set", {})
        l3vpn = rule_set.get("l3vpn", {})
        slice_id = l3vpn.get("tunnel-uuid") or l3vpn.get("uuid")
        if slice_id:
            return slice_id

        return rule_set.get("uuid")

    slice_id = _extract_slice_id(requests) or "TEST-SLICE"
    logging.info("Connecting end-to-end services in TFS controller at %s with slice ID %s", controller_ip, slice_id)

    response = tfs_connector().ipowdm_post(os.getenv("E2E_OPTICAL_IP"), slice_id, requests)
    return response
+31 −55
Original line number Diff line number Diff line
@@ -87,65 +87,41 @@ def l3ipowdm_slice(rules):
            logging.debug(f"Sending Media Channel Service to Orchestrator: {tfs_request}")
            tfs_requests.append(tfs_request)

        elif rule["type"] == "ACTIVATE_TRANSCEIVER":
            params = {
                "router_id": rule["content"]["node-uuid"],
                "router_tp": rule["content"]["termination-point-uuid"],
                "frequency": rule["content"]["frequency-ghz"],
                "power":     rule["content"]["tx-power-dbm"]
            }
            transceiver_params.append(params)
        elif rule["type"] == "CONFIG_VPNL3":
            src_router_id  = rule["content"]["src-node-uuid"]

            if src_router_id == transceiver_params[0]["router_id"]:
                src_power = transceiver_params[0]["power"]
                src_frequency = transceiver_params[0]["frequency"]
                dst_power = transceiver_params[1]["power"]
                dst_frequency = transceiver_params[1]["frequency"]
            else:
                src_power = transceiver_params[1]["power"]
                src_frequency = transceiver_params[1]["frequency"]
                dst_power = transceiver_params[0]["power"]
                dst_frequency = transceiver_params[0]["frequency"]

            src_router_id  = rule["content"]["src-node-uuid"]
            src_ip_address = rule["content"]["src-ip-address"]
            src_ip_mask    = rule["content"]["src-ip-mask"]
            src_vlan_id    = rule["content"]["src-vlan-id"]

            dst_router_id  = rule["content"]["dest-node-uuid"]
            dst_ip_address = rule["content"]["dest-ip-address"]
            dst_ip_mask    = rule["content"]["dest-ip-mask"]
            dst_vlan_id    = rule["content"]["dest-vlan-id"]
        elif rule["type"] == "XR_AGENT_ACTIVATE_TRANSCEIVER":
            transceiver_params = rule["content"]["components"]

        elif rule["type"] == "CONFIG_VPNL3":
            service_uuid = rule["content"]["tunnel-uuid"]

            tfs_request = load_template(os.path.join(TEMPLATES_PATH, "IPoWDM_orchestrator.json"))
            tfs_request["services"][0]["service_id"]["service_uuid"]["uuid"] = service_uuid
            config_rules = tfs_request["services"][0]["service_config"]["config_rules"][0]
            src = config_rules["ipowdm"]["rule_set"]["src"]
            src.append({
                'uuid': src_router_id,
                'ip_address': src_ip_address,
                'ip_mask': src_ip_mask,
                'vlan_id': src_vlan_id,
                'power': src_power,
                'frequency': src_frequency
            })
            src = [{
                'uuid': rule["content"]["src-node-uuid"],
                'ip_address': rule["content"]["src-ip-address"],
                'ip_mask': rule["content"]["src-ip-mask"],
                'vlan_id': rule["content"]["src-vlan-id"]
            }]

            dst = config_rules["ipowdm"]["rule_set"]["dst"]
            dst = []
            i = 1
            while f"dest{i}-node-uuid" in rule["content"]:
                dst.append({
                'uuid': dst_router_id,
                'ip_address': dst_ip_address,
                'ip_mask': dst_ip_mask,
                'vlan_id': dst_vlan_id,
                'power': dst_power,
                'frequency': dst_frequency
                    'uuid': rule["content"][f"dest{i}-node-uuid"],
                    'ip_address': rule["content"][f"dest{i}-ip-address"],
                    'ip_mask': rule["content"][f"dest{i}-ip-mask"],
                    'vlan_id': rule["content"][f"dest{i}-vlan-id"]
                })
                i += 1

            config_rules["ipowdm"]["rule_set"]["bw"]        = bandwidth
            config_rules["ipowdm"]["rule_set"]["uuid"]      = service_uuid
            tfs_request = load_template(os.path.join(TEMPLATES_PATH, "IPoWDM_orchestrator.json"))
            
            config_rules = tfs_request
            config_rules["endpoint_id"]["device_id"]["device_uuid"]["uuid"] = rule["controller_uuid"]
            config_rules["rule_set"]["uuid"] = rule["controller_uuid"]
            config_rules["rule_set"]["src"] = src
            config_rules["rule_set"]["dst"] = dst
            config_rules["rule_set"]["transceiver"] = {
                "components": transceiver_params
            }
            config_rules["rule_set"]["l3vpn"] = rule["content"]

            logging.debug(f"Sending IPoWDM Service to Orchestrator: {tfs_request}")
            tfs_requests.append(tfs_request)
+3 −2
Original line number Diff line number Diff line
@@ -39,13 +39,14 @@ def create_site_from_sdp(sdp, ietf_intent, connectivity_type, layer_type):
    router_id = safe_get(sdp, ["sdp", "attachment-circuits", "attachment-circuit", 0, "ac-node-id"])
    router_if = safe_get(sdp, ["sdp", "attachment-circuits", "attachment-circuit", 0, "ac-tp-id"])
    
    logging.debug(f"Configured site for SDP {safe_get(sdp, ['sdp', 'id'])} with location: {location}, router_id: {router_id}, router_if: {router_if}")
    sdp_id = safe_get(sdp, ["sdp", "id"]) or safe_get(sdp, ["sdp", "node-id"])
    logging.debug(f"Configured site for SDP {sdp_id} with location: {location}, router_id: {router_id}, router_if: {router_if}")
    
    network_access = create_network_access(sdp, ietf_intent, connectivity_type, router_id, router_if, layer_type)

    # Create site structure
    site = {
        "site-id": safe_get(sdp, ["sdp", "id"]),
        "site-id": sdp_id,
        "locations": {
            "location": [{"location-id": location}]
        },
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ def send_controller(controller_type, requests):
        response = ixia_connect(requests, current_app.config["IXIA_IP"])
        logging.info("Requests sent to Ixia")
    elif controller_type == "E2E":
        response = e2e_connect(requests, current_app.config["TFS_E2E"])
        response = e2e_connect(requests, current_app.config["TFS_E2E_IP"])
        logging.info("Requests sent to Teraflow E2E")
    elif controller_type == "RESTCONF":
        response = restconf_connect(requests, current_app.config["RESTCONF_IP"])
+29 −0
Original line number Diff line number Diff line
@@ -77,6 +77,35 @@ class tfs_connector():
        logging.debug("Http response: %s",response.text)
        return response

    def ipowdm_post(self, tfs_ip: str, slice_id: str, payload: object, timeout: int = 60):
        """
        Post IPoWDM service payload to the controller NBI endpoint:
            http://{tfs_ip}/restconf/ipowdm/v1/service/{slice_id}

        Args:
            tfs_ip: controller host (ip[:port])
            slice_id: identifier for the slice (path parameter)
            payload: JSON-serializable payload to send
            timeout: request timeout in seconds

        Returns:
            requests.Response
        """
        session = requests.Session()
        url = f'http://{tfs_ip}/restconf/ipowdm/v1/service/{slice_id}'
        headers = {'Content-Type': 'application/json'}
        data = json.dumps(payload)
        # logging.debug("Posting IPoWDM to %s: %s", url, data)
        # response = session.post(url, headers=headers, data=data, timeout=timeout)
        # response.raise_for_status()
        # logging.debug("Http response: %s", response.text)
        # STATIC RESPONSE FOR TESTING PURPOSES
        response = requests.Response()
        response.status_code = 200
        response._content = b'{"status": "success", "message": "IPoWDM service created successfully"}'
        logging.debug("Mocked Http response: %s", response.text)
        return response
    
    def nbi_delete(self, tfs_ip: str, service_type: str , service_id: str) -> requests.Response:
        """
        Delete service from TFS NBI.
Loading