Commit eb54830c authored by Pablo Armingol's avatar Pablo Armingol
Browse files

feat: implement payload handling for IPoWDM requests, update path tunnel...

feat: implement payload handling for IPoWDM requests, update path tunnel naming, and enable IETF L3VPN driver configuration templates
parent f7125e1c
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -192,15 +192,15 @@ class IetfL3VpnDriver(_Driver):
        with self.__lock:
            if 'ipowdm' in str(resources):
                LOGGER.info('Processing IPoWDM resources: {:s}'.format(str(resources)))
                # for resource in resources:
                #     if 'ipowdm' in str(resource):
                #         try:
                #             create_request(resource)
                #             LOGGER.info('Request created successfully')
                #             results.append((resource, True))
                #         except Exception as e:
                #             MSG = 'Invalid resource_value type: expected dict, got {:s}'
                #             results.append((resource, e))
                for resource in resources:
                    if 'ipowdm' in str(resource):
                        try:
                            create_request(resource)
                            LOGGER.info('Request created successfully')
                            results.append((resource, True))
                        except Exception as e:
                            MSG = 'Invalid resource_value type: expected dict, got {:s}'
                            results.append((resource, e))
            else:
                for resource in resources:
                    resource_key, resource_value = resource
+149 −0
Original line number Diff line number Diff line
{
    "ietf-l3vpn-svc:l3vpn-svc": {
        "vpn-services": {
            "vpn-service": [
                {
                    "vpn-id": "r2r-l3vpn_v2"
                }
            ]
        },
        "sites": {
            "site": [
                {
                    "site-id": "site_R1",
                    "management": {
                        "type": "ietf-l3vpn-svc:provider-managed"
                    },
                    "locations": {
                        "location": [
                            {
                                "location-id": "R1"
                            }
                        ]
                    },
                    "devices": {
                        "device": [
                            {
                                "device-id": "r1",
                                "location": "R1"
                            }
                        ]
                    },
                    "site-network-accesses": {
                        "site-network-access": [
                            {
                                "site-network-access-id": "Ethernet10",
                                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
                                "device-reference": "r1",
                                "vpn-attachment": {
                                    "vpn-id": "r2r-l3vpn_v2",
                                    "site-role": "ietf-l3vpn-svc:spoke-role"
                                },
                                "ip-connection": {
                                    "ipv4": {
                                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
                                        "addresses": {
                                            "provider-address": "10.0.12.5",
                                            "customer-address": "10.0.12.6",
                                            "prefix-length": 30
                                        }
                                    }
                                },
                                "service": {
                                    "svc-mtu": 1500,
                                    "svc-input-bandwidth": 1000000000,
                                    "svc-output-bandwidth": 1000000000,
                                    "qos": {
                                        "qos-profile": {
                                            "classes": {
                                                "class": [
                                                    {
                                                        "class-id": "qos-realtime",
                                                        "direction": "ietf-l3vpn-svc:both",
                                                        "latency": {
                                                            "latency-boundary": 10
                                                        },
                                                        "bandwidth": {
                                                            "guaranteed-bw-percent": 100
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        ]
                    }
                },
                {
                    "site-id": "site_R2",
                    "management": {
                        "type": "ietf-l3vpn-svc:provider-managed"
                    },
                    "locations": {
                        "location": [
                            {
                                "location-id": "R2"
                            }
                        ]
                    },
                    "devices": {
                        "device": [
                            {
                                "device-id": "r2",
                                "location": "R2"
                            }
                        ]
                    },
                    "site-network-accesses": {
                        "site-network-access": [
                            {
                                "site-network-access-id": "Ethernet10",
                                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
                                "device-reference": "r2",
                                "vpn-attachment": {
                                    "vpn-id": "r2r-l3vpn_v2",
                                    "site-role": "ietf-l3vpn-svc:hub-role"
                                },
                                "ip-connection": {
                                    "ipv4": {
                                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
                                        "addresses": {
                                            "provider-address": "10.0.12.6",
                                            "customer-address": "10.0.12.5",
                                            "prefix-length": 30
                                        }
                                    }
                                },
                                "service": {
                                    "svc-mtu": 1500,
                                    "svc-input-bandwidth": 1000000000,
                                    "svc-output-bandwidth": 1000000000,
                                    "qos": {
                                        "qos-profile": {
                                            "classes": {
                                                "class": [
                                                    {
                                                        "class-id": "qos-realtime",
                                                        "direction": "ietf-l3vpn-svc:both",
                                                        "latency": {
                                                            "latency-boundary": 10
                                                        },
                                                        "bandwidth": {
                                                            "guaranteed-bw-percent": 100
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}
 No newline at end of file
+40 −226
Original line number Diff line number Diff line
@@ -27,213 +27,24 @@ HEADERS = {

executor = ThreadPoolExecutor()

site_template = {
    "site-id": "",
    "devices": {
        "device": [
            {
                "device-id": "",
                "location": ""
            }
        ]
    },
    "site-network-accesses": {
        "site-network-access": [
            {
                "site-network-access-id": "",
                "device-reference": "",
                "ip-connection": {
                    "ipv4": {
                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
                        "addresses": {
                            "provider-address": "",
                            "customer-address": "",
                            "prefix-length": ""
                        }
                    }
                },
                "vpn-attachment": {
                    "vpn-id": "vpn-p2mp"
                },
                "site-network-access-type": "ietf-l3vpn-svc:multipoint"
            }
        ]
    }
}
def generate_l3vpn_template_pair( vpn_id, svc_mtu=1500, svc_input_bandwidth=1000000000, svc_output_bandwidth=1000000000, latency_boundary=10, guaranteed_bw_percent=100):
    with open("templates/l3vpn.json", "r") as f:
        template = json.load(f)
    LOGGER.info(f"Loaded template: {json.dumps(template, indent=2)}")

def generate_l3vpn_template_pair(src, dst, vpn_id):
    template['ietf-l3vpn-svc:l3vpn-svc']['vpn-services']['vpn-service'][0]['vpn-id'] = vpn_id

    return {
        "ietf-l3vpn-svc:l3vpn-svc": {
            "vpn-services": {
                "vpn-service": [{"vpn-id": vpn_id}]
            },
            "sites": {
                "site": [
                    {
                        "site-id": src["uuid"],
                        "management": {"type": "ietf-l3vpn-svc:provider-managed"},
                        "locations": {"location": [{"location-id": f"location-{src['uuid']}"}]},
                        "devices": {"device": [{
                            "device-id": "10.0.30.1",
                            "location": f"location-{src['uuid']}"
                        }]},
                        "routing-protocols": {"routing-protocol": [{
                            "type": "ietf-l3vpn-svc:static",
                            "static": {
                                "cascaded-lan-prefixes": {
                                    "ipv4-lan-prefixes": [
                                        {
                                        "lan": "128.32.10.1/24",
                                        "lan-tag": f"vlan{src['vlan_id']}",
                                        "next-hop": "10.0.30.10"
                                        }
                                    ]
                                }
                            }
                        }]},
                        "site-network-accesses": {
                            "site-network-access": [{
                                "site-network-access-id": f"{src['vlan_id']}",
                                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
                                "device-reference": "10.0.30.1",
                                "vpn-attachment": {
                                    "vpn-id": vpn_id, "site-role": "ietf-l3vpn-svc:spoke-role"
                                },
                                "ip-connection": {
                                    "ipv4": {
                                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
                                        "addresses": {
                                            "provider-address": "10.0.30.254",
                                            "customer-address": "10.0.30.10",
                                            "prefix-length": 24
                                        }
                                    }
                                },
                                "routing-protocols": {"routing-protocol": [{
                                    "type": "ietf-l3vpn-svc:static",
                                    "static": {
                                        "cascaded-lan-prefixes": {
                                            "ipv4-lan-prefixes": [
                                                {
                                                "lan": "172.1.101.1/24",
                                                "lan-tag": "vlan100",
                                                "next-hop": "10.0.30.254"
                                                }
                                            ]
                                        }
                                    }
                                }]},
                                "service": {
                                    "svc-mtu": 1500,
                                    "svc-input-bandwidth": 1000000000,
                                    "svc-output-bandwidth": 1000000000,
                                    "qos": {
                                        "qos-profile": {
                                        "classes": {
                                            "class": [
                                            {
                                                "class-id": "qos-realtime",
                                                "direction": "ietf-l3vpn-svc:both",
                                                "latency": {
                                                "latency-boundary": 10
                                                },
                                                "bandwidth": {
                                                "guaranteed-bw-percent": 100
                                                }
                                            }
                                            ]
                                        }
                                        }
                                    }
                                }
                            }]
                        }
                    },
                    {
                        "site-id": dst["uuid"],
                        "management": {"type": "ietf-l3vpn-svc:provider-managed"},
                        "locations": {"location": [{"location-id": f"location-{dst['uuid']}"}]},
                        "devices": {"device": [{
                            "device-id": "10.0.20.1",
                            "location": f"location-{dst['uuid']}"
                        }]},
                        "routing-protocols": {"routing-protocol": [{
                            "type": "ietf-l3vpn-svc:static",
                            "static": {
                                "cascaded-lan-prefixes": {
                                    "ipv4-lan-prefixes": [
                                        {
                                        "lan": "172.1.101.1/24",
                                        "lan-tag": "vlan200",
                                        "next-hop": "172.10.33.2"
                                        }
                                    ]
                                }
                            }
                        }]},
                        "site-network-accesses": {
                            "site-network-access": [{
                                "site-network-access-id": f"{dst['vlan_id']}",
                                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
                                "device-reference": "10.0.20.1",
                                "vpn-attachment": {
                                    "vpn-id": vpn_id, "site-role": "ietf-l3vpn-svc:hub-role"
                                },
                                "ip-connection": {
                                    "ipv4": {
                                        "address-allocation-type": "ietf-l3vpn-svc:static-address",
                                        "addresses": {
                                            "provider-address": "172.10.33.254",
                                            "customer-address": "172.10.33.2",
                                            "prefix-length": 24
                                        }
                                    }
                                },
                                "routing-protocols": {"routing-protocol": [{
                                    "type": "ietf-l3vpn-svc:static",
                                    "static": {
                                        "cascaded-lan-prefixes": {
                                            "ipv4-lan-prefixes": [
                                                {
                                                "lan": "128.32.10.1/24",
                                                "lan-tag": "vlan200",
                                                "next-hop": "172.10.33.254"
                                                }
                                            ]
                                        }
                                    }
                                }]},
                                "service": {
                                    "svc-mtu": 1500,
                                    "svc-input-bandwidth": 1000000000,
                                    "svc-output-bandwidth": 1000000000,
                                    "qos": {
                                        "qos-profile": {
                                        "classes": {
                                            "class": [
                                            {
                                                "class-id": "qos-realtime",
                                                "direction": "ietf-l3vpn-svc:both",
                                                "latency": {
                                                "latency-boundary": 10
                                                },
                                                "bandwidth": {
                                                "guaranteed-bw-percent": 100
                                                }
                                            }
                                            ]
                                        }
                                        }
                                    }
                                }
                            }]
                        }
                    }
                ]
            }
        }
    }
    for site in template['ietf-l3vpn-svc:l3vpn-svc']['sites']['site']:
        for access in site['site-network-accesses']['site-network-access']:
            access['vpn-attachment']['vpn-id'] = vpn_id
            access['service']['svc-mtu'] = svc_mtu
            access['service']['svc-input-bandwidth'] = svc_input_bandwidth
            access['service']['svc-output-bandwidth'] = svc_output_bandwidth
            for qos_class in access['service']['qos']['qos-profile']['classes']['class']:
                qos_class['latency']['latency-boundary'] = latency_boundary
                qos_class['bandwidth']['guaranteed-bw-percent'] = guaranteed_bw_percent
    
    return template

def create_request(resource_value):
    """ Create and send HTTP request based on a JSON template and provided resource value.
@@ -256,6 +67,7 @@ def create_request(resource_value):

    LOGGER.info("Creating request for resource_value: %s", resource_value)


    node_src = resource_value[1]['rule_set']['src'][0]
    src = [{
        'uuid': node_src["uuid"],
@@ -275,36 +87,38 @@ def create_request(resource_value):

    sites_input = src + dsts

    dests_uuids = [dst['uuid'] for dst in dsts]
    src_uuid = src[0]['uuid']
    vpn_id = src_uuid + "-" + "-".join(dests_uuids)

    components = resource_value[1]['rule_set']['transceiver']['components']
    for i, device in enumerate(components):
        name = sites_input[i]['uuid']

        if name == "T2.1":device["frequency"]= 195000000
        if name == "T1.1":device["frequency"]= 195006250
        if name == "T1.2":device["frequency"]= 195018750
        if name == "T1.3":device["frequency"]= 195031250

        LOGGER.debug(f"NODE TO CONFIGURE: \n{name}: {json.dumps(device, indent=2)}")
        response = patch_optical_channel_frequency(device, name)
        LOGGER.debug(f"RESPONSE :\n {response}")
        LOGGER.info(f"NODE TO CONFIGURE: \n{name}: {json.dumps(device, indent=2)}")
    #     response = patch_optical_channel_frequency(device, name)
    #     LOGGER.debug(f"RESPONSE :\n {response}")
    templates = []
    for dst in dsts:
        vpn = "L3VPN_"+src[0]['uuid']+"_"+dst['uuid']
        templates.append(generate_l3vpn_template_pair(src[0], dst,vpn))
        templates.append(generate_l3vpn_template_pair(vpn_id=vpn_id, svc_mtu="1500", svc_input_bandwidth=1000000000, svc_output_bandwidth=1000000000, latency_boundary=10, guaranteed_bw_percent=100))
    LOGGER.info(f"Generated L3VPN P2MP service JSONs:\n{json.dumps(templates, indent=2)}")

    url = "http://192.168.202.254:80/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
    headers = {
        'accept': 'application/json',
        'Content-Type': 'application/json'
    }

    for template in templates:
        LOGGER.info("Generated L3VPN P2MP service JSON:\n%s", json.dumps(template, indent=2))
    # url = "http://192.168.202.254:80/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
    # headers = {
    #     'accept': 'application/json',
    #     'Content-Type': 'application/json'
    # }

        response = requests.post(url = url, headers= headers, json=template)
        LOGGER.debug(response)
    # for template in templates:
    #     LOGGER.info("Generated L3VPN P2MP service JSON:\n%s", json.dumps(template, indent=2))

    #     response = requests.post(url = url, headers= headers, json=template)
    #     LOGGER.debug(response)
    return None



def patch_optical_channel_frequency(data, DEVICE_ID):
    encoded_path = f"http://192.168.202.254:80/restconf/data/device={DEVICE_ID}/openconfig-platform:components/component=channel-1/optical-channel/config"

+25 −6
Original line number Diff line number Diff line
@@ -35,14 +35,33 @@ class IPoWDMService(Resource):
        request_data = request.get_json()
        LOGGER.info("IPoWDM request data: %s", json.dumps(request_data, indent=2))

        if 'src' not in request_data or 'dst' not in request_data:
            return {'status': 'error', 'message': 'Missing required fields: src and dst'}, 400

        # Support nested/wrapped payload structure
        if isinstance(request_data, dict) and 'services' in request_data:
            services = request_data['services']
            if isinstance(services, list) and len(services) > 0:
                first_item = services[0]
                if isinstance(first_item, list) and len(first_item) > 0:
                    first_item = first_item[0]
                if isinstance(first_item, dict):
                    request_data = first_item

        if isinstance(request_data, dict) and 'rule_set' in request_data:
            rule_set = request_data['rule_set']
            src_endpoints = rule_set.get('src', [])
            dst_endpoints = rule_set.get('dst', [])
            bandwidth = rule_set.get('bw', 100)
            device_id = rule_set.get('uuid', 'TFS-PACKET')
            if 'endpoint_id' in request_data:
                device_id = request_data['endpoint_id'].get('device_id', {}).get('device_uuid', {}).get('uuid') or device_id
        else:
            src_endpoints = request_data.get('src', [])
            dst_endpoints = request_data.get('dst', [])
            bandwidth = request_data.get('bw', 100)
            device_id = request_data.get('device_id', 'TFS-PACKET')

        if not src_endpoints or not dst_endpoints:
            return {'status': 'error', 'message': 'Missing required fields: src and dst'}, 400

        LOGGER.info(f"Service UUID: {serviceId}")
        LOGGER.info(f"Bandwidth: {bandwidth}")
        LOGGER.info(f"Source endpoints: {len(src_endpoints)}")
+1 −81

File changed.

Preview size limit exceeded, changes collapsed.