atlanticwave-sdx / sdx-controller

Central Controller for AtlanticWave SDX.
https://www.atlanticwave-sdx.net
MIT License
1 stars 3 forks source link

Connection request should allow user to specify which VLAN to be used on ingress and egress #232

Closed italovalcy closed 3 months ago

italovalcy commented 6 months ago

Hi,

It is interesting that the connection request should allow the user to define which VLAN ID he/she wants to use when requesting a circuit (ingress and egress, which may be different by the way).

Choosing the user VLAN does not relate to VLAN IDs used for inter-domain connections. The latter will be automatically chosen from the SDX Controller / PCE.

In the meantime, it would be nice if the GET /connection displays which VLAN was chose for ingress and egress from the user request (again, only on user ports, not inter-OXP ports)

YufengXin commented 6 months ago

Yes. The pce core function handles these different VLAN combinations. Some code might be needed on the front. The 'requesthandler' class was meant to properly handle the different request combinations. We'll create a meta issue with a list of these individual scenario.

As I mentioned in an earlier message: we need a template/spec for the connection response that works for Meican. The 'connection' object itself has an optional 'path' field that actually could show all the internal VLANs-:)

italovalcy commented 4 months ago

Hi @YufengXin can you please provide an update if the VLAN ID is already supported by SDX-Controller connection creation request?

As per the swagger API spec, it does not seems to support:

https://github.com/atlanticwave-sdx/sdx-controller/blob/main/sdx_controller/swagger/swagger.yaml#L408-L433

YufengXin commented 4 months ago

@italovalcy The port is an object here, which could contain the user specified VLANs. I am sure the backend support it. However, I thought we still need to test the actual request json from you, would you please provide an example you used? @sajith would look into it.

sajith commented 4 months ago

https://github.com/atlanticwave-sdx/pce/pull/177 ("Update getting port when breakdown") is related, right? The PR was made when I was away, so I'm not quite up to speed on that. I guess we should get it merged first?

sajith commented 4 months ago

Also here's #/components/schemas/port:

https://github.com/atlanticwave-sdx/sdx-controller/blob/b931068826eac56d46ec490b1826dbaecf572175/sdx_controller/swagger/swagger.yaml#L710-L743

And here's an example connection request:

{
    "id": "test-connection-request",
    "name": "Test connection request",
    "start_time": "2000-01-23T04:56:07.000Z",
    "end_time": "2000-01-23T04:56:07.000Z",
    "bandwidth_required": 10,
    "latency_required": 300,
    "egress_port": {
        "id": "urn:sdx:port:amlight.net:A1:1",
        "name": "Novi100:1",
        "node": "urn:sdx:node:amlight.net:A1",
        "status": "up"
    },
    "ingress_port": {
        "id": "urn:ogf:network:sdx:port:zaoxi:A1:2",
        "name": "Novi100:2",
        "node": "urn:ogf:network:sdx:node:zaoxi:A1",
        "status": "up"
    }
}

What would a request that carries a VLAN ID look like? I don't believe that Topology Data Model Specification specifies a format/schema for connection requests.

YufengXin commented 4 months ago

@sajith I think we reused the 'label' and 'label_range' fields in the port object for the connection request, ie, 'label' for the type, vlan in this case, and 'vlan_range' for the value. See this test json in data model.

https://github.com/atlanticwave-sdx/datamodel/blob/main/src/sdx_datamodel/data/requests/test_request_p2p.json

That's why I remembered this was tested already.

@italovalcy we'll use your test request to test. But there is no specification doc for request yet. I started with the json schema like others and tried to reuse as much as possible. We can use your schema/convention.

YufengXin commented 3 months ago

(related datamodel #102, pce issue#179): on user specified vlans on ports. The current parser and provisioning in datamodel and pce have implemented functions to process both port.vlan_range and port.services.l2vpn-ptp.vlan_range, aka user specified vlan function. The idea is to use port.vlan_range for the user specified vlans in the connection request, and port.services.l2vpn-ptp.vlan_range for the available vlan ranges in the OXP's topology.json. But we need to finalize/test the whole process.

To kick it off, I started a draft on the request connection Specification draft in the project Google drive: https://docs.google.com/document/d/1vMKn5Mjf404BPJIilBcs2VpikdzOxS1jTep4kdJ1_0I/edit

The workflow: spec doc-> json schema->parser->unittest->swagger.yaml->sdx-doc.

(Note: for this version, we should just get the basic done, then we can iterate and add new requirements in the request)

@italovalcy @jab1982 @sajith

italovalcy commented 3 months ago

Hi @YufengXin and @sajith I tried to use the label and vlan_range as in the data model request example above, but it didnt seems to have any effect on the sdx-controller:

curl -X POST http://0.0.0.0:8080/SDX-Controller/1.0.0/connection -H 'Content-Type: application/json' -d '{"id": "test-222-333-1", "name": "Test connection request 22", "start_time": "2000-01-23T04:56:07.000Z", "end_time": "2000-01-23T04:56:07.000Z", "bandwidth_required": 10, "latency_required": 300, "egress_port": {"id": "urn:sdx:port:tenet.ac.za:Tenet03:50", "name": "Tenet03:50", "node": "urn:sdx:port:tenet.ac.za:Tenet03", "status": "up", "label": "vlan", "label_range": "107"}, "ingress_port": {"id": "urn:sdx:port:ampath.net:Ampath3:50", "name": "Ampath3:50", "node": "urn:sdx:port:ampath.net:Ampath3", "status": "up", "label": "vlan", "label_range": "107"}}'

# Logs:

INFO:sdx_pce.topology.temanager:generate_traffic_matrix: connection_request: {'id': 'test-222-333-1', 'name': 'Test connection request 22', 'start_time': '2000-01-23T04:56:07.000Z', 'end_time': '2000-01-23T04:56:07.000Z', 'bandwidth_required': 10, 'latency_required': 300, 'egress_port': {'id': 'urn:sdx:port:tenet.ac.za:Tenet03:50', 'name': 'Tenet03:50', 'node': 'urn:sdx:port:tenet.ac.za:Tenet03', 'status': 'up', 'label': 'vlan', 'label_range': '107'}, 'ingress_port': {'id': 'urn:sdx:port:ampath.net:Ampath3:50', 'name': 'Ampath3:50', 'node': 'urn:sdx:port:ampath.net:Ampath3', 'status': 'up', 'label': 'vlan', 'label_range': '107'}}
...
INFO:sdx_pce.topology.temanager:generate_connection_breakdown(): tagged_breakdown: VlanTaggedBreakdowns(breakdowns={'urn:sdx:topology:ampath.net': VlanTaggedBreakdown(name='AMPATH_vlan_99_99', dynamic_backup_path=True, uni_a=VlanTaggedPort(tag=VlanTag(value=99, tag_type=1), port_id='urn:sdx:port:ampath.net:Ampath3:2'), uni_z=VlanTaggedPort(tag=VlanTag(value=99, tag_type=1), port_id='urn:sdx:port:ampath.net:Ampath1:40')), 'urn:sdx:topology:sax.net': VlanTaggedBreakdown(name='SAX_vlan_99_99', dynamic_backup_path=True, uni_a=VlanTaggedPort(tag=VlanTag(value=99, tag_type=1), port_id='urn:sdx:port:sax.net:Sax01:40'), uni_z=VlanTaggedPort(tag=VlanTag(value=99, tag_type=1), port_id='urn:sdx:port:sax.net:Sax01:41')), 'urn:sdx:topology:tenet.ac.za': VlanTaggedBreakdown(name='TENET_vlan_99_99', dynamic_backup_path=True, uni_a=VlanTaggedPort(tag=VlanTag(value=99, tag_type=1), port_id='urn:sdx:port:tenet.ac.za:Tenet01:41'), uni_z=VlanTaggedPort(tag=VlanTag(value=99, tag_type=1), port_id='urn:sdx:port:tenet.ac.za:Tenet03:2'))})
INFO:sdx_controller.controllers.connection_controller:place_connection result: ID: test-222-333-1 reason='Connection published', code=200
YufengXin commented 3 months ago

@italovalcy Thanks for testing this. could you share the OXP topology json you used? Specifically, what are the vlan_range specified in these two ports' services component?

italovalcy commented 3 months ago

Hi @YufengXin sure thing! Here is is:

1) the topology I'm using is based on the following setup (Steps to reproduce):

git clone https://github.com/atlanticwave-sdx/sdx-continuous-development
cd sdx-continuous-development
git checkout main
git pull
for repo in sdx-lc sdx-controller kytos-sdx-topology; do cd data-plane/; git clone https://github.com/atlanticwave-sdx/$repo container-$repo; cd ..; done
cd data-plane
cp template.env .env
./1_build_kytos.sh
./2_build_oxpos.sh
./3_build_local_controllers.sh
./4_build_mongo.sh
cd container-sdx-controller
docker build -t sdx-controller .
cd ..
docker compose up -d

# wait a couple of secunds to make the OXPs boot up. Usually I follow the steps below to make sure they are all UP:
EXP_SW=3; while true; do N_SW=$(curl -s http://0.0.0.0:8181/api/kytos/topology/v3/switches | jq -r '.switches[].id' | wc -l); echo "waiting switches $N_SW / $EXP_SW"; if [ $N_SW -eq $EXP_SW ]; then break; fi; sleep 1; done
EXP_SW=2; while true; do N_SW=$(curl -s http://0.0.0.0:8282/api/kytos/topology/v3/switches | jq -r '.switches[].id' | wc -l); echo "waiting switches $N_SW / $EXP_SW"; if [ $N_SW -eq $EXP_SW ]; then break; fi; sleep 1; done
EXP_SW=3; while true; do N_SW=$(curl -s http://0.0.0.0:8383/api/kytos/topology/v3/switches | jq -r '.switches[].id' | wc -l); echo "waiting switches $N_SW / $EXP_SW"; if [ $N_SW -eq $EXP_SW ]; then break; fi; sleep 1; done

# configure OXPs -- kytos requires some initial configs like approving switches and links just discovered
./container-kytos-sdx-topology/curl/2.enable_all.sh
./container-kytos-sdx-topology/curl/0a.version_control.sh
./container-kytos-sdx-topology/curl/0b.version_control.sh
./container-kytos-sdx-topology/curl/0c.version_control.sh

# check if the topology is correctly identified by SDX-Controller:
curl -s http://0.0.0.0:8080/SDX-Controller/1.0.0/topology | jq -r '.nodes[] | (.ports[] | .id)'
curl -s http://0.0.0.0:8080/SDX-Controller/1.0.0/topology | jq -r '.links[] | .id + " " + .ports[0].id + " " + .ports[1].id'

# finally I just submit a connection creation request to SDX-Controller which should span requests to all other OXPs:
$ curl -X POST http://0.0.0.0:8080/SDX-Controller/1.0.0/connection -H 'Content-Type: application/json' -d '{"id": "test-from-ampath-vlan-49-to-tenet-vlan-49", "name": "Test connection request 22", "start_time": "2000-01-23T04:56:07.000Z", "end_time": "2000-01-23T04:56:07.000Z", "bandwidth_required": 10, "latency_required": 300, "egress_port": {"id": "urn:sdx:port:tenet.ac.za:Tenet03:50", "name": "Tenet03:50", "node": "urn:sdx:port:tenet.ac.za:Tenet03", "status": "up", "label": "vlan", "label_range": "49"}, "ingress_port": {"id": "urn:sdx:port:ampath.net:Ampath3:50", "name": "Ampath3:50", "node": "urn:sdx:port:ampath.net:Ampath3", "status": "up", "label": "vlan", "label_range": "49"}}'
{
  "connection_id": "test-from-ampath-vlan-49-to-tenet-vlan-49",
  "reason": "Connection published",
  "status": "OK"
}

# get the connection recently created:
$ curl http://0.0.0.0:8080/SDX-Controller/1.0.0/connection/test-from-ampath-vlan-49-to-tenet-vlan-49
{
  "bandwidth_required": 10,
  "egress_port": {
    "id": "urn:sdx:port:tenet.ac.za:Tenet03:50",
    "label": "vlan",
    "label_range": "49",
    "name": "Tenet03:50",
    "node": "urn:sdx:port:tenet.ac.za:Tenet03",
    "status": "up"
  },
  "end_time": "2000-01-23T04:56:07.000Z",
  "id": "test-from-ampath-vlan-49-to-tenet-vlan-49",
  "ingress_port": {
    "id": "urn:sdx:port:ampath.net:Ampath3:50",
    "label": "vlan",
    "label_range": "49",
    "name": "Ampath3:50",
    "node": "urn:sdx:port:ampath.net:Ampath3",
    "status": "up"
  },
  "latency_required": 300,
  "name": "Test connection request 22",
  "start_time": "2000-01-23T04:56:07.000Z"
}

# get the circuits created on each OXP:
$ curl -s http://0.0.0.0:8181/api/kytos/mef_eline/v2/evc/ | jq -r '.[] | .id + " " + .name + " uni_a=" + (.uni_a|tostring) + " uni_z=" + (.uni_z|tostring)'
228080e6094e4b AMPATH_vlan_100_100 uni_a={"tag":{"tag_type":1,"value":100},"interface_id":"aa:00:00:00:00:00:00:03:2"} uni_z={"tag":{"tag_type":1,"value":100},"interface_id":"aa:00:00:00:00:00:00:01:40"}

$ curl -s http://0.0.0.0:8282/api/kytos/mef_eline/v2/evc/ | jq -r '.[] | .id + " " + .name + " uni_a=" + (.uni_a|tostring) + " uni_z=" + (.uni_z|tostring)'
d7ff9bbf55a94c SAX_vlan_100_100 uni_a={"tag":{"tag_type":1,"value":100},"interface_id":"dd:00:00:00:00:00:00:04:40"} uni_z={"tag":{"tag_type":1,"value":100},"interface_id":"dd:00:00:00:00:00:00:04:41"}

$ curl -s http://0.0.0.0:8383/api/kytos/mef_eline/v2/evc/ | jq -r '.[] | .id + " " + .name + " uni_a=" + (.uni_a|tostring) + " uni_z=" + (.uni_z|tostring)'
ae7b2b227c5940 TENET_vlan_100_100 uni_a={"tag":{"tag_type":1,"value":100},"interface_id":"cc:00:00:00:00:00:00:06:41"} uni_z={"tag":{"tag_type":1,"value":100},"interface_id":"cc:00:00:00:00:00:00:08:2"}

2) for the label range on the ports, I believe so:

$ curl -s http://0.0.0.0:8080/SDX-Controller/1.0.0/topology | jq -r '.nodes[] | (.ports[] | .id + " label_range=" + (.label_range|tostring))'
urn:sdx:port:ampath.net:Ampath3:50 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath3:2 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath3:3 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath2:1 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath2:50 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath2:40 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath2:3 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath1:1 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath1:40 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath1:2 label_range=["1-100"]
urn:sdx:port:ampath.net:Ampath1:50 label_range=["1-100"]
urn:sdx:port:sax.net:Sax01:41 label_range=["1-100"]
urn:sdx:port:sax.net:Sax01:1 label_range=["1-100"]
urn:sdx:port:sax.net:Sax01:40 label_range=["1-100"]
urn:sdx:port:sax.net:Sax01:50 label_range=["1-100"]
urn:sdx:port:sax.net:Sax02:41 label_range=["1-100"]
urn:sdx:port:sax.net:Sax02:1 label_range=["1-100"]
urn:sdx:port:sax.net:Sax02:40 label_range=["1-100"]
urn:sdx:port:sax.net:Sax02:50 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet02:41 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet02:1 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet02:50 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet03:2 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet03:50 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet01:41 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet01:1 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet01:2 label_range=["1-100"]
urn:sdx:port:tenet.ac.za:Tenet01:50 label_range=["1-100"]
YufengXin commented 3 months ago

@italovalcy As I can see, the vlan_range is [1-100] and you were asking vlan 107 in your request. 107 is outside of the OXP available vlan range, in which case, the current logic would just pick an available one to assign to your request.

A while ago, we agreed to retire the 'sdx-continuous-development' repo. Now you made it work, we could look at it again. (1) could you please make thees instruction into the readme in that repo?

(2) For the timebeing, we only need to run unittest for debugging, would you be able to save these three OXP topology.json and check them in to the tests/data in 'datamodel' repo? Thanks.

YufengXin commented 3 months ago

@italovalcy BTW, in your testing environment, are you using the main branch for sdx-controller and sdx-lc? If so, we'll try to reproduce your environment. Thanks. @mcevik0

italovalcy commented 3 months ago

@italovalcy As I can see, the vlan_range is [1-100] and you were asking vlan 107 in your request. 107 is outside of the OXP available vlan range, in which case, the current logic would just pick an available one to assign to your request.

A while ago, we agreed to retire the 'sdx-continuous-development' repo. Now you made it work, we could look at it again. (1) could you please make thees instruction into the readme in that repo?

Hi @YufengXin actually, if you see the requests I created two tests: 1) first using VLAN 107, which is outside of the range allowed from the OXP; 2) I created a second test using VLAN 49, inside the VLAN range and still got assigned VLAN 100....

For situation 1, the SDX-Controller has to reply saying that the requested VLAN is not allowed, instead of creating a VLAN of the choice of the SDX-COntroller.

For situation 2, the SDX-Controller just ignored the request from the user and assigned a VLAN of its choice again..

(2) For the timebeing, we only need to run unittest for debugging, would you be able to save these three OXP topology.json and check them in to the tests/data in 'datamodel' repo? Thanks.

In this case you just need to run the same steps as I did before and you should be able to get the JSONs! ;)

italovalcy commented 3 months ago

@italovalcy BTW, in your testing environment, are you using the main branch for sdx-controller and sdx-lc? If so, we'll try to reproduce your environment. Thanks. @mcevik0

I'm using main branch.

YufengXin commented 3 months ago

Thanks, @italovalcy.

I'll leave the testing environment to Mert. (I see both submodules were one month old.)

@sajith Could you please take a look at this issue? I think our unittest json tried to cover both in- and out- vlan range cases, please double check and fix. Thx.

italovalcy commented 3 months ago

Hi Yufeng,

I'll leave the testing environment to Mert. (I see both submodules were one month old.)

Yes, good point! Indeed, on the procedure above I just ignored the submodules and cloned directly from upstream. See the specific part here:

for repo in sdx-lc sdx-controller kytos-sdx-topology; do cd data-plane/; git clone https://github.com/atlanticwave-sdx/$repo container-$repo; cd ..; done
sajith commented 3 months ago

It would be even better if docker.io/awsdx/sdx-controller and docker.io/awsdx/sdx-lc images could be used instead of building them off submodules...

I see that using those docker images is an item in https://github.com/atlanticwave-sdx/sdx-continuous-development/issues/106. Is the plan to resurrect that repo? How quick/easy would it be to use it for local testing today?

YufengXin commented 3 months ago

Since submodules are not used anyway and the Kytos NAPP now works, let Mert and Cong try to duplicate the setup first. Then move to issue #247 on using these images.

This issue is on itself, let's get an unittest case work in duplicating Italo's test.

italovalcy commented 3 months ago

Hi team, any updates on this issue?

sajith commented 3 months ago

Not yet. I will get to this, but not sure when.

YufengXin commented 3 months ago

@italovalcy I think you relayed Jeronimo's opinion to hold on this issue, because it depends on the request specification and examples.

Anyway, I made the move, making changes in 'datamdoel' and 'sdx-lc' first , that include cleaning up and streamline the schema and the code, after turning on the function to parse the 'vlan_range' attribute moved from the port object to the port.services.

And as I explained to you, any changes in the datamodel will trigger the chain reaction: datamodel<->sdx-lc<->pce and finally here in sdx-controller.

I have two PRs in datamodel and sdx-lc that have completed the unittest. The next step is to conduct the system tests with sdx-lc and sdx-controller before merging.

italovalcy commented 3 months ago

Hi Yufeng,

@italovalcy I think you relayed Jeronimo's opinion to hold on this issue, because it depends on the request specification and examples.

Thanks for looking into this. Actually, what I mentioned was regarding the openapi spec on Kytos SDX topology, that task was put on hold to wait for the final connection spec from Jeronimo. However, I think we have all we need from the current spec: https://github.com/atlanticwave-sdx/datamodel/blob/main/src/sdx_datamodel/data/requests/test_request_p2p.json#L13

We even discussed about this in two meetings ago (on the meeting 2024-05-01) and we talked about using that data model spec the way it was and then later on we adapt to comply with the final connection model spec.