Commit 7ad48262 authored by Pablo Armingol's avatar Pablo Armingol
Browse files

refactor: Remove L3VPN template generation logic and update iPOWDM service type from 12 to 13.

parent af0b4eb9
Loading
Loading
Loading
Loading
+53 −16
Original line number Diff line number Diff line
@@ -2,21 +2,56 @@
    "services": [
        {
            "service_id": {
                "context_id": {"context_uuid": {"uuid": "admin"}},
                "service_uuid": {"uuid": "644c4aa6-c2e2-4db0-9d6e-869522c4141c"}
                "context_id": {
                    "context_uuid": {
                        "uuid": "admin"
                    }
                },
                "service_uuid": {
                    "uuid": "644c4aa6-c2e2-4db0-9d6e-869522c4141c"
                }
            },
            "service_type": 13,
            "service_status": {
                "service_status": 1
            },
            "service_type": 12,
            "service_status": {"service_status": 1},
            "service_endpoint_ids": [
                {"device_id": {"device_uuid": {"uuid": "Phoenix1"}},"endpoint_uuid": {"uuid": "PORT-xe4"}},
                {"device_id": {"device_uuid": {"uuid": "Phoenix2"}},"endpoint_uuid": {"uuid": "PORT-xe4"}}
                {
                    "device_id": {
                        "device_uuid": {
                            "uuid": "Phoenix1"
                        }
                    },
                    "endpoint_uuid": {
                        "uuid": "PORT-xe4"
                    }
                },
                {
                    "device_id": {
                        "device_uuid": {
                            "uuid": "Phoenix2"
                        }
                    },
                    "endpoint_uuid": {
                        "uuid": "PORT-xe4"
                    }
                }
            ],
            "service_constraints": [],
            "service_config": {"config_rules": [
                {"action": 1, "ipowdm": {
            "service_config": {
                "config_rules": [
                    {
                        "action": 1,
                        "ipowdm": {
                            "endpoint_id": {
                        "device_id": {"device_uuid": {"uuid": "Phoenix1"}},
                        "endpoint_uuid": {"uuid": "PORT-xe4"}
                                "device_id": {
                                    "device_uuid": {
                                        "uuid": "Phoenix1"
                                    }
                                },
                                "endpoint_uuid": {
                                    "uuid": "PORT-xe4"
                                }
                            },
                            "rule_set": {
                                "src": [
@@ -42,8 +77,10 @@
                                "bw": 100,
                                "uuid": "644c4aa6-c2e2-4db0-9d6e-869522c4141c"
                            }
                }}
            ]}
                        }
                    }
                ]
            }
        }
    ]
}
 No newline at end of file
+49 −274
Original line number Diff line number Diff line
@@ -11,230 +11,15 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from types import SimpleNamespace
import os
import json
import logging
import os

import requests
from concurrent.futures import ThreadPoolExecutor

LOGGER = logging.getLogger(__name__)

HEADERS = {
    "Accept": "application/yang-data+json",
    "Content-Type": "application/yang-data+json"
}

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(src, dst, 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
                                                }
                                            }
                                            ]
                                        }
                                        }
                                    }
                                }
                            }]
                        }
                    }
                ]
            }
        }
    }

def create_request(resource_value):
    """ Create and send HTTP request based on a JSON template and provided resource value.
        The JSON template is expected to be in the same directory as this script, named 'ipowdm.json'.
@@ -261,61 +46,51 @@ def create_request(resource_value):
    with open(json_path, 'r', encoding='utf-8') as f:
        template = json.load(f)

    node_src = resource_value[1]['rule_set']['src'][0]
    src = [{
        'uuid': node_src["uuid"],
        'ip_address': node_src["ip_address"],
        'ip_mask': node_src["ip_mask"],
        'vlan_id': node_src["vlan_id"]
    }]
    dst_list = resource_value[1]['rule_set']['dst']
    dsts = []
    for node in dst_list:
        dsts.append({
            'uuid': node["uuid"],
            'ip_address': node["ip_address"],
            'ip_mask': node["ip_mask"],
            'vlan_id': node["vlan_id"]
        })

    sites_input = src + dsts

    components = resource_value[1]['rule_set']['transceiver']['components']
    for i, device in enumerate(components):
        name = sites_input[i]['uuid']
    LOGGER.info("Sending POST DSTINATION request with payload: %s", json.dumps(template, indent=2))

        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
    response = FakeResponse()
    # tfs_post(template)
    return response

        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}")
    templates = []
    for dst in dsts:
        vpn = "L3VPN_"+src[0]['uuid']+"_"+dst['uuid']
        templates.append(generate_l3vpn_template_pair(src[0], dst,vpn))
class FakeResponse:
    """_Fake response object for testing purposes."""
    def __init__(self):
        self.ok = True
        self.status_code = 200
        self.text = '{"message": "OK"}'

    url = "http://192.168.202.254:80/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services"
    headers = {
        'accept': 'application/json',
        'Content-Type': 'application/json'
    }
    def json(self):
        """Return a sample JSON response."""
        return {"message": "OK"}

    for template in templates:
        LOGGER.info("Generated L3VPN P2MP service JSON:\n%s", json.dumps(template, indent=2))
def tfs_post(request):
        """
        Send a POST request to the TeraFlow Service Orchestrator.

        response = requests.post(url = url, headers= headers, json=template)
        LOGGER.debug(response)
    return None
        Args:
            ip (str): IP address of the TeraFlow Service Orchestrator.
            request (dict): The request payload to be sent.

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"
        Returns:
            dict: The response from the TeraFlow Service Orchestrator.
        """
        user="admin"
        password="admin"
        token=""
        session = requests.Session()
        session.auth = (user, password)
        url=f'http://10.95.86.62/webui'
        response=session.get(url=url)
        for item in response.iter_lines():
            if"csrf_token" in str(item):
                string=str(item).split('<input id="csrf_token" name="csrf_token" type="hidden" value=')[1]
                token=string.split(">")[0].strip('"')
        logging.debug("csrf token %s",token)

        files = {'descriptors': ("data.json", json.dumps(request).encode(
                                                                "utf-8"), "application/json")}
        token={'csrf_token':token}
        response = session.post(url,files=files,data=token,timeout=60)
        logging.debug("Http response: %s",response.text)

    patch_data = data
    response = requests.patch(f"{encoded_path}",
                            json=patch_data,
                            headers=HEADERS)
    assert response.status_code == 200
        return response
+24 −24
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ class IPoWDMService(Resource):
            service = Service()
            service.service_id.service_uuid.uuid = serviceId
            service.service_id.context_id.context_uuid.uuid = "admin"
            service.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
            service.service_type = ServiceTypeEnum.SERVICETYPE_IPOWDM
            service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
            service.name = f"IPoWDM-{serviceId}"

+111 −33
Original line number Diff line number Diff line
#!/bin/bash

# Test IPoWDM service creation and deletion via NBI
# Tests the endpoint /restconf/ipowdm/v1/service/{uuid}

set -e

NBI_URL="${NBI_URL:-http://10.95.86.58}"

echo "=========================================="
echo "IPoWDM NBI Test"
echo "IPoWDM NBI Test - Create and Delete"
echo "=========================================="
echo ""

# Test 1: Create IPoWDM Service
echo ">>> Test 1: POST /restconf/ipowdm/v1/service/test-ipowdm-001"
# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0

# Function to run a test
run_test() {
    local test_name="$1"
    local method="$2"
    local endpoint="$3"
    local data="$4"
    local expected_status="$5"

    TESTS_RUN=$((TESTS_RUN + 1))
    echo ">>> Test $TESTS_RUN: $test_name"
    echo ""

    if [ -n "$data" ]; then
        response=$(curl -v -X "$method" \
            "$NBI_URL$endpoint" \
            -H "Content-Type: application/json" \
            -d "$data" \
            2>&1)
    else
        response=$(curl -v -X "$method" \
            "$NBI_URL$endpoint" \
            -H "Content-Type: application/json" \
            2>&1)
    fi

    echo "$response"
    echo ""

IPOWDM_DATA='{
    # Check if expected status is in response
    if echo "$response" | grep -q "HTTP.*$expected_status"; then
        echo "✓ PASSED: Got expected status $expected_status"
        TESTS_PASSED=$((TESTS_PASSED + 1))
    else
        echo "✗ FAILED: Expected status $expected_status"
        TESTS_FAILED=$((TESTS_FAILED + 1))
    fi

    echo ""
    echo "Waiting 2 seconds..."
    sleep 2
    echo ""
}

# Test 1: Create IPoWDM Service
echo "==========================================
TEST 1: CREATE IPOWDM SERVICE
==========================================
"

IPOWDM_CREATE_DATA='{
  "src": [{
    "uuid": "Phoenix-1",
    "ip_address": "10.10.1.1",
    "ip_mask": "/24",
    "vlan_id": 100,
    "power": 0.0,
    "frequency": 194700.0
    "vlan_id": 100
  }],
  "dst": [{
    "uuid": "Phoenix-2",
    "ip_address": "10.10.2.1",
    "ip_mask": "/24",
    "vlan_id": 100,
    "power": 0.0,
    "frequency": 194700.0
    "vlan_id": 100
  }],
  "bw": 100,
  "uuid": "test-ipowdm-001",
  "transceiver": {
    "components": [
      {
        "name": "Optics0/0/0/1",
        "frequency": 194700.0,
        "target_output_power": -10.0,
        "operational_mode": 0,
        "digital_sub_carriers_group": [],
        "operation": "activate"
      },
      {
        "name": "Optics0/0/0/2",
        "frequency": 194700.0,
        "target_output_power": -10.0,
        "operational_mode": 0,
        "digital_sub_carriers_group": [],
        "operation": "activate"
      }
    ]
  },
  "device_id": "TFS-PACKET"
}'

curl -v -X POST \
  "$NBI_URL/restconf/ipowdm/v1/service/test-ipowdm-001" \
  -H "Content-Type: application/json" \
  -d "$IPOWDM_DATA"

echo ""
echo ""
echo "Waiting 2 seconds..."
sleep 2
echo ""
run_test \
    "Create IPoWDM Service" \
    "POST" \
    "/restconf/ipowdm/v1/service/test-ipowdm-001" \
    "$IPOWDM_CREATE_DATA" \
    "201"

# Test 2: Delete IPoWDM Service
echo ">>> Test 2: DELETE /restconf/ipowdm/v1/service/test-ipowdm-001"
echo ""
sleep 4
DELETE_DATA='{
echo "==========================================
TEST 2: DELETE IPOWDM SERVICE
==========================================
"

IPOWDM_DELETE_DATA='{
  "device_id": "TFS-PACKET"
}'

curl -v -X DELETE \
  "$NBI_URL/restconf/ipowdm/v1/service/test-ipowdm-001" \
  -H "Content-Type: application/json" \
  -d "$DELETE_DATA"
run_test \
    "Delete IPoWDM Service" \
    "DELETE" \
    "/restconf/ipowdm/v1/service/test-ipowdm-001" \
    "$IPOWDM_DELETE_DATA" \
    "200"

echo ""
echo ""
echo "==========================================="
echo "Test completed - Check NBI logs"
echo "==========================================="
# Test Summary
echo "=========================================="
echo "TEST SUMMARY"
echo "=========================================="
echo "Total Tests Run:    $TESTS_RUN"
echo "Tests Passed:       $TESTS_PASSED"
echo "Tests Failed:       $TESTS_FAILED"
echo "=========================================="

if [ $TESTS_FAILED -eq 0 ]; then
    echo "✓ ALL TESTS PASSED"
    exit 0
else
    echo "✗ SOME TESTS FAILED"
    exit 1
fi