From d352735669b21101b09e744365b1687d5b4a6ff4 Mon Sep 17 00:00:00 2001 From: TFS Date: Tue, 26 Mar 2024 23:32:35 +0100 Subject: [PATCH 001/638] new test script --- src/tests/ofc24/deploy-node-agents.sh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/tests/ofc24/deploy-node-agents.sh b/src/tests/ofc24/deploy-node-agents.sh index 5c3c8d0d2..79d6c1dc3 100755 --- a/src/tests/ofc24/deploy-node-agents.sh +++ b/src/tests/ofc24/deploy-node-agents.sh @@ -34,21 +34,18 @@ echo "Create Management Network and Node Agents:" echo "------------------------------------------" docker network create -d bridge --subnet=172.254.253.0/24 --gateway=172.254.253.254 --ip-range=172.254.253.0/24 na-br docker run -d --name na-t1 --network=na-br --ip 172.254.253.1 \ - --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \ --volume "$PWD/src/tests/${TEST_NAME}/platform_t1.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \ - asgamb1/flexscale-hhi.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh + asgamb1/flexscale-hhi.img:latest ./startNetconfAgent.sh docker run -d --name na-t2 --network=na-br --ip 172.254.253.2 \ - --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \ --volume "$PWD/src/tests/${TEST_NAME}/platform_t2.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \ - asgamb1/flexscale-hhi.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh + asgamb1/flexscale-hhi.img:latest ./startNetconfAgent.sh docker run -d --name na-r1 --network=na-br --ip 172.254.253.101 \ - --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \ --volume "$PWD/src/tests/${TEST_NAME}/platform_r1.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \ - asgamb1/flexscale-node.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh + asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh + docker run -d --name na-r2 --network=na-br --ip 172.254.253.102 \ - --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \ --volume "$PWD/src/tests/${TEST_NAME}/platform_r2.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \ - asgamb1/flexscale-node.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh + asgamb1/flexscale-node.img:latest ./startNetconfAgent.sh echo -- GitLab From 635efe54c3c74ceb79bfbfb1873bd300b1b11ec5 Mon Sep 17 00:00:00 2001 From: Lluis Gifre Renom Date: Fri, 30 May 2025 11:23:02 +0000 Subject: [PATCH 002/638] CI/CD tests: - Disable all unitary tests - Disable all end-to-end tests but RyuOpenFlow --- .gitlab-ci.yml | 66 ++++++------ src/tests/.gitlab-ci.yml | 24 ++--- src/tests/ryu-openflow/.gitlab-ci.yml | 142 +++++++++----------------- 3 files changed, 93 insertions(+), 139 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1aa5e597d..cc85679d0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,39 +21,39 @@ stages: # include the individual .gitlab-ci.yml of each micro-service and tests include: - #- local: '/manifests/.gitlab-ci.yml' - - local: '/src/monitoring/.gitlab-ci.yml' - - local: '/src/nbi/.gitlab-ci.yml' - - local: '/src/context/.gitlab-ci.yml' - - local: '/src/device/.gitlab-ci.yml' - - local: '/src/service/.gitlab-ci.yml' - - local: '/src/dbscanserving/.gitlab-ci.yml' - - local: '/src/opticalattackmitigator/.gitlab-ci.yml' - - local: '/src/opticalattackdetector/.gitlab-ci.yml' - - local: '/src/opticalattackmanager/.gitlab-ci.yml' - - local: '/src/opticalcontroller/.gitlab-ci.yml' - - local: '/src/ztp/.gitlab-ci.yml' - - local: '/src/policy/.gitlab-ci.yml' - - local: '/src/automation/.gitlab-ci.yml' - - local: '/src/forecaster/.gitlab-ci.yml' - #- local: '/src/webui/.gitlab-ci.yml' - #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml' - #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml' - #- local: '/src/l3_attackmitigator/.gitlab-ci.yml' - - local: '/src/slice/.gitlab-ci.yml' - #- local: '/src/interdomain/.gitlab-ci.yml' - - local: '/src/pathcomp/.gitlab-ci.yml' - #- local: '/src/dlt/.gitlab-ci.yml' - - local: '/src/load_generator/.gitlab-ci.yml' - - local: '/src/bgpls_speaker/.gitlab-ci.yml' - - local: '/src/kpi_manager/.gitlab-ci.yml' - - local: '/src/kpi_value_api/.gitlab-ci.yml' - #- local: '/src/kpi_value_writer/.gitlab-ci.yml' - #- local: '/src/telemetry/.gitlab-ci.yml' - - local: '/src/analytics/.gitlab-ci.yml' - - local: '/src/qos_profile/.gitlab-ci.yml' - - local: '/src/vnt_manager/.gitlab-ci.yml' - - local: '/src/e2e_orchestrator/.gitlab-ci.yml' +# #- local: '/manifests/.gitlab-ci.yml' +# - local: '/src/monitoring/.gitlab-ci.yml' +# - local: '/src/nbi/.gitlab-ci.yml' +# - local: '/src/context/.gitlab-ci.yml' +# - local: '/src/device/.gitlab-ci.yml' +# - local: '/src/service/.gitlab-ci.yml' +# - local: '/src/dbscanserving/.gitlab-ci.yml' +# - local: '/src/opticalattackmitigator/.gitlab-ci.yml' +# - local: '/src/opticalattackdetector/.gitlab-ci.yml' +# - local: '/src/opticalattackmanager/.gitlab-ci.yml' +# - local: '/src/opticalcontroller/.gitlab-ci.yml' +# - local: '/src/ztp/.gitlab-ci.yml' +# - local: '/src/policy/.gitlab-ci.yml' +# - local: '/src/automation/.gitlab-ci.yml' +# - local: '/src/forecaster/.gitlab-ci.yml' +# #- local: '/src/webui/.gitlab-ci.yml' +# #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml' +# #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml' +# #- local: '/src/l3_attackmitigator/.gitlab-ci.yml' +# - local: '/src/slice/.gitlab-ci.yml' +# #- local: '/src/interdomain/.gitlab-ci.yml' +# - local: '/src/pathcomp/.gitlab-ci.yml' +# #- local: '/src/dlt/.gitlab-ci.yml' +# - local: '/src/load_generator/.gitlab-ci.yml' +# - local: '/src/bgpls_speaker/.gitlab-ci.yml' +# - local: '/src/kpi_manager/.gitlab-ci.yml' +# - local: '/src/kpi_value_api/.gitlab-ci.yml' +# #- local: '/src/kpi_value_writer/.gitlab-ci.yml' +# #- local: '/src/telemetry/.gitlab-ci.yml' +# - local: '/src/analytics/.gitlab-ci.yml' +# - local: '/src/qos_profile/.gitlab-ci.yml' +# - local: '/src/vnt_manager/.gitlab-ci.yml' +# - local: '/src/e2e_orchestrator/.gitlab-ci.yml' # This should be last one: end-to-end integration tests - local: '/src/tests/.gitlab-ci.yml' diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml index dfccc4726..775bf2167 100644 --- a/src/tests/.gitlab-ci.yml +++ b/src/tests/.gitlab-ci.yml @@ -14,16 +14,16 @@ # include the individual .gitlab-ci.yml of each end-to-end integration test include: - - local: '/src/tests/ofc22/.gitlab-ci.yml' - #- local: '/src/tests/oeccpsc22/.gitlab-ci.yml' - - local: '/src/tests/ecoc22/.gitlab-ci.yml' - #- local: '/src/tests/nfvsdn22/.gitlab-ci.yml' - #- local: '/src/tests/ofc23/.gitlab-ci.yml' - - local: '/src/tests/ofc24/.gitlab-ci.yml' - - local: '/src/tests/eucnc24/.gitlab-ci.yml' - #- local: '/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml' - #- local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml' - #- local: '/src/tests/ofc25/.gitlab-ci.yml' - #- local: '/src/tests/ryu-openflow/.gitlab-ci.yml' +# - local: '/src/tests/ofc22/.gitlab-ci.yml' +# #- local: '/src/tests/oeccpsc22/.gitlab-ci.yml' +# - local: '/src/tests/ecoc22/.gitlab-ci.yml' +# #- local: '/src/tests/nfvsdn22/.gitlab-ci.yml' +# #- local: '/src/tests/ofc23/.gitlab-ci.yml' +# - local: '/src/tests/ofc24/.gitlab-ci.yml' +# - local: '/src/tests/eucnc24/.gitlab-ci.yml' +# #- local: '/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml' +# #- local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml' +# #- local: '/src/tests/ofc25/.gitlab-ci.yml' + - local: '/src/tests/ryu-openflow/.gitlab-ci.yml' - - local: '/src/tests/tools/mock_tfs_nbi_dependencies/.gitlab-ci.yml' +# - local: '/src/tests/tools/mock_tfs_nbi_dependencies/.gitlab-ci.yml' diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 42d595384..112d3b68e 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -56,27 +56,29 @@ build ryu-openflow: # asgamb1/oc23bgp.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh -## Deploy TeraFlowSDN and Execute end-2-end test -#end2end_test ryu-openflow: -# timeout: 90m -# variables: -# TEST_NAME: 'ryu-openflow' -# stage: end2end_test -# # Disable to force running it after all other tasks -# #needs: -# # - build ryu-openflow -# before_script: -# - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY -# - docker ps -aq | xargs -r docker rm -f -# - containerlab destroy --all --cleanup || true -# script: -# # Download Docker image to run the test -# - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}:latest" -# -# # Check MicroK8s is ready -# - microk8s status --wait-ready -# - kubectl get pods --all-namespaces -# +# Deploy TeraFlowSDN and Execute end-2-end test +end2end_test ryu-openflow: + timeout: 90m + variables: + TEST_NAME: 'ryu-openflow' + IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' + stage: end2end_test + # Disable to force running it after all other tasks + #needs: + # - build ryu-openflow + before_script: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + - docker ps -aq | xargs -r docker rm -f + #- containerlab destroy --all --cleanup || true + # cleanup mininet + script: + # Download Docker image to run the test + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}:latest" + + # Check MicroK8s is ready + - microk8s status --wait-ready + - kubectl get pods --all-namespaces + # # Deploy ContainerLab Scenario # - RUNNER_PATH=`pwd` # #- cd $PWD/src/tests/${TEST_NAME} @@ -86,16 +88,15 @@ build ryu-openflow: # - cd /tmp/clab/${TEST_NAME} # - containerlab deploy --reconfigure --topo ryu-openflow.clab.yml # - cd $RUNNER_PATH -# + +# deploy ryu + +# deploy mininet + # # Wait for initialization of Device NOSes # - sleep 3 # - docker ps -a # -# # Dump configuration of the routers (before any configuration) -# - containerlab exec --name ryu-openflow --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# # # Configure TeraFlowSDN deployment # # Uncomment if DEBUG log level is needed for the components # #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml @@ -145,49 +146,7 @@ build ryu-openflow: # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" # $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-onboarding.sh # -# # Run end-to-end test: configure service TFS -# - > -# docker run -t --rm --name ${TEST_NAME} --network=host -# --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" -# --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" -# $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-tfs-create.sh -# -# # Dump configuration of the routers (after configure TFS service) -# - containerlab exec --name ryu-openflow --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# -# # Run end-to-end test: test connectivity with ping -# - export TEST1_10=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.10' --format json) -# - echo $TEST1_10 -# - echo $TEST1_10 | grep -E '3 packets transmitted, 3 received, 0\% packet loss' -# - export TEST1_1=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.1' --format json) -# - echo $TEST1_1 -# - echo $TEST1_1 | grep -E '3 packets transmitted, 3 received, 0\% packet loss' -# - export TEST2_1=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.1' --format json) -# - echo $TEST2_1 -# - echo $TEST2_1 | grep -E '3 packets transmitted, 3 received, 0\% packet loss' -# - export TEST2_10=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.2.10' --format json) -# - echo $TEST2_10 -# - echo $TEST2_10 | grep -E '3 packets transmitted, 3 received, 0\% packet loss' -# - export TEST3_1=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.1' --format json) -# - echo $TEST3_1 -# - echo $TEST3_1 | grep -E '3 packets transmitted, 0 received, 100\% packet loss' -# - export TEST3_10=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.3.10' --format json) -# - echo $TEST3_10 -# - echo $TEST3_10 | grep -E '3 packets transmitted, 0 received, 100\% packet loss' -# -# # Run end-to-end test: deconfigure service TFS -# - > -# docker run -t --rm --name ${TEST_NAME} --network=host -# --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" -# --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" -# $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-tfs-remove.sh -# -# # Dump configuration of the routers (after deconfigure TFS service) -# - containerlab exec --name ryu-openflow --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" +# # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) # # # Run end-to-end test: configure service IETF # - > @@ -196,10 +155,7 @@ build ryu-openflow: # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" # $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-ietf-create.sh # -# # Dump configuration of the routers (after configure IETF service) -# - containerlab exec --name ryu-openflow --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" +# # Dump configuration of the switches (OpenFlow rules configured) (after configure IETF service) # # # Run end-to-end test: test connectivity with ping # - export TEST1_10=$(containerlab exec --name ryu-openflow --label clab-node-name=dc1 --cmd 'ping -n -c3 172.16.1.10' --format json) @@ -228,10 +184,7 @@ build ryu-openflow: # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" # $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-ietf-remove.sh # -# # Dump configuration of the routers (after deconfigure IETF service) -# - containerlab exec --name ryu-openflow --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" +# # Dump configuration of the switches (OpenFlow rules configured) (after deconfigure IETF service) # # # Run end-to-end test: cleanup scenario # - > @@ -241,10 +194,7 @@ build ryu-openflow: # $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-cleanup.sh # # after_script: -# # Dump configuration of the routers (on after_script) -# - containerlab exec --name ryu-openflow --label clab-node-name=r1 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r2 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" -# - containerlab exec --name ryu-openflow --label clab-node-name=r3 --cmd "Cli --command \"enable"$'\n'$"show running-config\"" +# # Dump configuration of the switches (OpenFlow rules configured) (on after_script) # # # Dump TeraFlowSDN component logs # - source src/tests/${TEST_NAME}/deploy_specs.sh @@ -262,17 +212,21 @@ build ryu-openflow: # - cd /tmp/clab/${TEST_NAME} # - containerlab destroy --topo ryu-openflow.clab.yml --cleanup || true # - sudo rm -rf clab-ryu-openflow/ .ryu-openflow.clab.yml.bak || true + +# destroy ryu +# destroy mininet + # - cd $RUNNER_PATH # - kubectl delete namespaces tfs || true -# -# # Clean old docker images -# - docker images --filter="dangling=true" --quiet | xargs -r docker rmi -# -# #coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' -# rules: -# - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' -# - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' -# artifacts: -# when: always -# reports: -# junit: ./src/tests/${TEST_NAME}/report_*.xml + + # Clean old docker images + - docker images --filter="dangling=true" --quiet | xargs -r docker rmi + + #coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' + artifacts: + when: always + reports: + junit: ./src/tests/${TEST_NAME}/report_*.xml -- GitLab From adc467739b09706b06d14fdbe7137edabebb28b6 Mon Sep 17 00:00:00 2001 From: Lluis Gifre Renom Date: Fri, 30 May 2025 11:26:30 +0000 Subject: [PATCH 003/638] CI/CD test Ryu-OpenFlow fix --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 112d3b68e..642a49da5 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -61,7 +61,7 @@ end2end_test ryu-openflow: timeout: 90m variables: TEST_NAME: 'ryu-openflow' - IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' + IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' stage: end2end_test # Disable to force running it after all other tasks #needs: -- GitLab From 8a1310455a3dff33345f828ca0550ea53cad5fe2 Mon Sep 17 00:00:00 2001 From: Lluis Gifre Renom Date: Fri, 30 May 2025 11:37:17 +0000 Subject: [PATCH 004/638] Fix CI/CD pipeline for Ryu OpenFlow test --- src/tests/ryu-openflow/.gitlab-ci.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 642a49da5..b068bd2cc 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -28,13 +28,15 @@ build ryu-openflow: - echo "CI_MERGE_REQUEST_IID = $CI_MERGE_REQUEST_IID" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Ryu.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Mininet.Dockerfile . + - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-test:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Test.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-test:${IMAGE_TAG}" after_script: - docker images --filter="dangling=true" --quiet | xargs -r docker rmi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' + #- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - changes: - src/common/**/*.py - proto/*.proto @@ -72,8 +74,10 @@ end2end_test ryu-openflow: #- containerlab destroy --all --cleanup || true # cleanup mininet script: - # Download Docker image to run the test - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}:latest" + # Download Docker images to run the test + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" # Check MicroK8s is ready - microk8s status --wait-ready @@ -225,7 +229,7 @@ end2end_test ryu-openflow: #coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' - - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' + #- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' artifacts: when: always reports: -- GitLab From 63c64cc0cd18c09e203fd2a3e303e2e2dc4a0332 Mon Sep 17 00:00:00 2001 From: Lluis Gifre Renom Date: Fri, 30 May 2025 11:42:28 +0000 Subject: [PATCH 005/638] Fix CI/CD pipeline --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cc85679d0..1657d3dc0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,6 +19,12 @@ stages: - unit_test - end2end_test +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' + when: always + - when: never + # include the individual .gitlab-ci.yml of each micro-service and tests include: # #- local: '/manifests/.gitlab-ci.yml' -- GitLab From 1ce39e9c7053a0d976571cd84b8395442a366bfe Mon Sep 17 00:00:00 2001 From: Lluis Gifre Renom Date: Fri, 30 May 2025 11:45:22 +0000 Subject: [PATCH 006/638] Fix CI/CD pipeline for Ryu OpenFlow --- src/tests/ryu-openflow/.gitlab-ci.yml | 4 ---- src/tests/ryu-openflow/Mininet.Dockerfile | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index b068bd2cc..f66a0f135 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -21,11 +21,7 @@ build ryu-openflow: before_script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - docker ps -aq | xargs -r docker rm -f - - containerlab destroy --all --cleanup || true script: - - echo "CI_PIPELINE_SOURCE = $CI_PIPELINE_SOURCE" - - echo "CI_MERGE_REQUEST_ID = $CI_MERGE_REQUEST_ID" - - echo "CI_MERGE_REQUEST_IID = $CI_MERGE_REQUEST_IID" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Ryu.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Mininet.Dockerfile . diff --git a/src/tests/ryu-openflow/Mininet.Dockerfile b/src/tests/ryu-openflow/Mininet.Dockerfile index a465297e4..0a829bb49 100644 --- a/src/tests/ryu-openflow/Mininet.Dockerfile +++ b/src/tests/ryu-openflow/Mininet.Dockerfile @@ -22,6 +22,6 @@ RUN apt-get update && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -COPY custom_pentagon_topology.py /opt/custom_pentagon_topology.py +COPY src/tests/ryu-openflow/custom_pentagon_topology.py /opt/custom_pentagon_topology.py CMD ["python3", "/opt/custom_pentagon_topology.py"] -- GitLab From 3c76230f71ce6c9f4d7f9c154ff1b8c648e5c9cd Mon Sep 17 00:00:00 2001 From: Lluis Gifre Renom Date: Fri, 30 May 2025 11:49:07 +0000 Subject: [PATCH 007/638] CI/CD pipeline fix on Ryu OpenFlow --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index f66a0f135..734cf49a0 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -25,7 +25,7 @@ build ryu-openflow: - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Ryu.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Mininet.Dockerfile . - - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-test:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Test.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-test:${IMAGE_TAG}" after_script: -- GitLab From cf2b4b99d7155f7aed38a53a369f5233f89679bf Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 30 May 2025 13:48:48 +0000 Subject: [PATCH 008/638] deploy ryu and mininet --- src/tests/ryu-openflow/.gitlab-ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 734cf49a0..5ea18b234 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -69,7 +69,8 @@ end2end_test ryu-openflow: - docker ps -aq | xargs -r docker rm -f #- containerlab destroy --all --cleanup || true # cleanup mininet - script: + - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c + # Download Docker images to run the test - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" @@ -90,12 +91,15 @@ end2end_test ryu-openflow: # - cd $RUNNER_PATH # deploy ryu + - docker network create tfs-test-net + - docker run -d --name ryu --network tfs-test-net "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" # deploy mininet + - docker run -d --name mininet --network tfs-test-net "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # # Wait for initialization of Device NOSes -# - sleep 3 -# - docker ps -a + - sleep 10 + - docker ps -a # # # Configure TeraFlowSDN deployment # # Uncomment if DEBUG log level is needed for the components -- GitLab From 4744209b62cf74e73456ef41a3aacb761f0e4046 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 30 May 2025 13:55:31 +0000 Subject: [PATCH 009/638] Update file .gitlab-ci.yml --- src/tests/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml index 775bf2167..c3faacd02 100644 --- a/src/tests/.gitlab-ci.yml +++ b/src/tests/.gitlab-ci.yml @@ -24,6 +24,6 @@ include: # #- local: '/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml' # #- local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml' # #- local: '/src/tests/ofc25/.gitlab-ci.yml' - - local: '/src/tests/ryu-openflow/.gitlab-ci.yml' + - local: '/src/tests/ryu-openflow/.gitlab-ci.yml' # - local: '/src/tests/tools/mock_tfs_nbi_dependencies/.gitlab-ci.yml' -- GitLab From 1b5f0857dabfe8874456b5cff0bcfb791ca5d177 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 30 May 2025 13:58:16 +0000 Subject: [PATCH 010/638] Update 2 files - /src/tests/.gitlab-ci.yml - /src/tests/ryu-openflow/.gitlab-ci.yml --- src/tests/.gitlab-ci.yml | 2 +- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml index c3faacd02..775bf2167 100644 --- a/src/tests/.gitlab-ci.yml +++ b/src/tests/.gitlab-ci.yml @@ -24,6 +24,6 @@ include: # #- local: '/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml' # #- local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml' # #- local: '/src/tests/ofc25/.gitlab-ci.yml' - - local: '/src/tests/ryu-openflow/.gitlab-ci.yml' + - local: '/src/tests/ryu-openflow/.gitlab-ci.yml' # - local: '/src/tests/tools/mock_tfs_nbi_dependencies/.gitlab-ci.yml' diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 5ea18b234..90f3ffdc7 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -70,7 +70,7 @@ end2end_test ryu-openflow: #- containerlab destroy --all --cleanup || true # cleanup mininet - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c - + script: # Download Docker images to run the test - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -- GitLab From ad271ace673950aaafe3b7d8009ee1624ff45288 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 09:38:45 +0000 Subject: [PATCH 011/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 77 +++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 90f3ffdc7..70451fc36 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -91,38 +91,47 @@ end2end_test ryu-openflow: # - cd $RUNNER_PATH # deploy ryu - - docker network create tfs-test-net - - docker run -d --name ryu --network tfs-test-net "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker network create -d bridge \ + --subnet=172.254.254.0/24 \ + --gateway=172.254.254.1 \ + tfs-test-net -# deploy mininet - - docker run -d --name mininet --network tfs-test-net "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker run -d --name ryu \ + --network tfs-test-net \ + --ip 172.254.254.10 \ + "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + + # deploy mininet + - docker run -d --name mininet \ + --network tfs-test-net \ + "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # # Wait for initialization of Device NOSes - sleep 10 - docker ps -a # -# # Configure TeraFlowSDN deployment -# # Uncomment if DEBUG log level is needed for the components -# #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml -# #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml -# #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml -# #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml -# #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml -# #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml -# -# - source src/tests/${TEST_NAME}/deploy_specs.sh -# #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" -# #- export TFS_SKIP_BUILD="YES" -# #- export TFS_IMAGE_TAG="latest" -# #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" -# -# # Deploy TeraFlowSDN -# - ./deploy/crdb.sh -# - ./deploy/nats.sh -# - ./deploy/kafka.sh -# - ./deploy/qdb.sh -# - ./deploy/tfs.sh -# - ./deploy/show.sh + Configure TeraFlowSDN deployment + # Uncomment if DEBUG log level is needed for the components + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml +# + - source src/tests/${TEST_NAME}/deploy_specs.sh + - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" + - export TFS_SKIP_BUILD="YES" + - export TFS_IMAGE_TAG="latest" + - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" +# + Deploy TeraFlowSDN + - ./deploy/crdb.sh + - ./deploy/nats.sh + - ./deploy/kafka.sh + - ./deploy/qdb.sh + - ./deploy/tfs.sh + - ./deploy/show.sh # # ## Wait for Context to be subscribed to NATS # ## WARNING: this loop is infinite if there is no subscriber (such as monitoring). @@ -141,14 +150,14 @@ end2end_test ryu-openflow: # # break # # fi # # done -# - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server -# -# # Run end-to-end test: onboard scenario -# - > -# docker run -t --rm --name ${TEST_NAME} --network=host -# --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" -# --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" -# $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-onboarding.sh + - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server +# + # Run end-to-end test: onboard scenario + - > + docker run -t --rm --name ${TEST_NAME} --network=host + --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" + --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" + $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh # # # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) # -- GitLab From a38cc19288116d6635c812a2271e0f8ba34509a8 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 09:44:43 +0000 Subject: [PATCH 012/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 70451fc36..b05d55a60 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -90,21 +90,11 @@ end2end_test ryu-openflow: # - containerlab deploy --reconfigure --topo ryu-openflow.clab.yml # - cd $RUNNER_PATH -# deploy ryu - - docker network create -d bridge \ - --subnet=172.254.254.0/24 \ - --gateway=172.254.254.1 \ - tfs-test-net - - - docker run -d --name ryu \ - --network tfs-test-net \ - --ip 172.254.254.10 \ - "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - # deploy mininet - - docker run -d --name mininet \ - --network tfs-test-net \ - "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker network rm tfs-test-net || true + - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-net + - docker run -d --name ryu --network tfs-test-net --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-net "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # # Wait for initialization of Device NOSes - sleep 10 -- GitLab From 2641069e3400cba12a406b44b0701a56044dad8b Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 09:49:09 +0000 Subject: [PATCH 013/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index b05d55a60..0e512db95 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -91,10 +91,9 @@ end2end_test ryu-openflow: # - cd $RUNNER_PATH - docker network rm tfs-test-net || true - - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-net - - docker run -d --name ryu --network tfs-test-net --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker run -d --name mininet --network tfs-test-net "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # # Wait for initialization of Device NOSes - sleep 10 -- GitLab From e556845778382f66181d2441c7d853504999a57c Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 09:54:03 +0000 Subject: [PATCH 014/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 0e512db95..13c80f075 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,7 +55,7 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test ryu-openflow: +end2end_test_ryu-openflow: timeout: 90m variables: TEST_NAME: 'ryu-openflow' -- GitLab From 673008a3bf8682f1ad53a07e7c4f390fa47e267a Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 09:55:13 +0000 Subject: [PATCH 015/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 13c80f075..30df68f52 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,7 +55,7 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test_ryu-openflow: +end2end_test ryu-openflow: timeout: 90m variables: TEST_NAME: 'ryu-openflow' @@ -90,10 +90,10 @@ end2end_test_ryu-openflow: # - containerlab deploy --reconfigure --topo ryu-openflow.clab.yml # - cd $RUNNER_PATH - - docker network rm tfs-test-net || true - - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + # - docker network rm tfs-test-net || true + # - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + # - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + # - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # # Wait for initialization of Device NOSes - sleep 10 -- GitLab From fddc8cb86418fea2b5ae4b1baffeab5305cdf106 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:07:32 +0000 Subject: [PATCH 016/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 30df68f52..6b790de61 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -32,7 +32,6 @@ build ryu-openflow: - docker images --filter="dangling=true" --quiet | xargs -r docker rmi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' - #- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - changes: - src/common/**/*.py - proto/*.proto @@ -90,10 +89,10 @@ end2end_test ryu-openflow: # - containerlab deploy --reconfigure --topo ryu-openflow.clab.yml # - cd $RUNNER_PATH - # - docker network rm tfs-test-net || true - # - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - # - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - # - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker network rm tfs-test-net || true + - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # # Wait for initialization of Device NOSes - sleep 10 -- GitLab From 03705c1504a92749e5f4a6e0d4b455e232496b2e Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:15:28 +0000 Subject: [PATCH 017/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 93 ++++++++++++++------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 6b790de61..c3d262a88 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -32,6 +32,7 @@ build ryu-openflow: - docker images --filter="dangling=true" --quiet | xargs -r docker rmi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' + #- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - changes: - src/common/**/*.py - proto/*.proto @@ -69,15 +70,15 @@ end2end_test ryu-openflow: #- containerlab destroy --all --cleanup || true # cleanup mininet - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c - script: - # Download Docker images to run the test - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" + #script: + ## Download Docker images to run the test + #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" # Check MicroK8s is ready - - microk8s status --wait-ready - - kubectl get pods --all-namespaces + #- microk8s status --wait-ready + #- kubectl get pods --all-namespaces # # Deploy ContainerLab Scenario # - RUNNER_PATH=`pwd` @@ -89,37 +90,37 @@ end2end_test ryu-openflow: # - containerlab deploy --reconfigure --topo ryu-openflow.clab.yml # - cd $RUNNER_PATH - - docker network rm tfs-test-net || true - - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - -# # Wait for initialization of Device NOSes - - sleep 10 - - docker ps -a -# - Configure TeraFlowSDN deployment - # Uncomment if DEBUG log level is needed for the components - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml -# - - source src/tests/${TEST_NAME}/deploy_specs.sh - - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" - - export TFS_SKIP_BUILD="YES" - - export TFS_IMAGE_TAG="latest" - - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" -# - Deploy TeraFlowSDN - - ./deploy/crdb.sh - - ./deploy/nats.sh - - ./deploy/kafka.sh - - ./deploy/qdb.sh - - ./deploy/tfs.sh - - ./deploy/show.sh + #- docker network rm tfs-test-net || true + #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + #- docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + #- docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" +# +# # # Wait for initialization of Device NOSes + #- sleep 10 + #- docker ps -a +## + # Configure TeraFlowSDN deployment + ## Uncomment if DEBUG log level is needed for the components + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml +## + #- source src/tests/${TEST_NAME}/deploy_specs.sh + #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" + #- export TFS_SKIP_BUILD="YES" + #- export TFS_IMAGE_TAG="latest" + #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" +# + # Deploy TeraFlowSDN + # - ./deploy/crdb.sh + # - ./deploy/nats.sh + # - ./deploy/kafka.sh + # - ./deploy/qdb.sh + # - ./deploy/tfs.sh + # - ./deploy/show.sh # # ## Wait for Context to be subscribed to NATS # ## WARNING: this loop is infinite if there is no subscriber (such as monitoring). @@ -138,14 +139,14 @@ end2end_test ryu-openflow: # # break # # fi # # done - - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server -# - # Run end-to-end test: onboard scenario - - > - docker run -t --rm --name ${TEST_NAME} --network=host - --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" - --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" - $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh + #- kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server + + ## Run end-to-end test: onboard scenario + #- > + # docker run -t --rm --name ${TEST_NAME} --network=host + # --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" + # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" + # $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh # # # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) # -- GitLab From 4aeb762f6bb9644ebda60fc3c6857f9bcfd97458 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:16:15 +0000 Subject: [PATCH 018/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index c3d262a88..0fff56ed0 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -64,12 +64,12 @@ end2end_test ryu-openflow: # Disable to force running it after all other tasks #needs: # - build ryu-openflow - before_script: - - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - - docker ps -aq | xargs -r docker rm -f - #- containerlab destroy --all --cleanup || true - # cleanup mininet - - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c + #before_script: + # - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + # - docker ps -aq | xargs -r docker rm -f + # #- containerlab destroy --all --cleanup || true + # # cleanup mininet + # - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c #script: ## Download Docker images to run the test #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" -- GitLab From 78245bf36615961c9fa9325048efe661baa2c176 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:16:38 +0000 Subject: [PATCH 019/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 0fff56ed0..d70e1a443 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,12 +55,12 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test ryu-openflow: - timeout: 90m - variables: - TEST_NAME: 'ryu-openflow' - IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' - stage: end2end_test +#end2end_test ryu-openflow: + #timeout: 90m + #variables: + #TEST_NAME: 'ryu-openflow' + #IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' + #stage: end2end_test # Disable to force running it after all other tasks #needs: # - build ryu-openflow -- GitLab From 815d4ebe471d2e6beebf870e3e9c76d75d2dbea8 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:19:15 +0000 Subject: [PATCH 020/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d70e1a443..8db2f7cd6 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,9 +55,9 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -#end2end_test ryu-openflow: - #timeout: 90m - #variables: +end2end_test ryu-openflow: + timeout: 90m + variables: #TEST_NAME: 'ryu-openflow' #IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' #stage: end2end_test -- GitLab From b433da472f601756fa1bdb156569801c6d6588e5 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:20:48 +0000 Subject: [PATCH 021/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 8db2f7cd6..47a971965 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,7 +55,7 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test ryu-openflow: +end2end_test ryu_openflow: timeout: 90m variables: #TEST_NAME: 'ryu-openflow' -- GitLab From 7ba83be56e7a7568dd86787614a85a60a8ad9fd4 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:28:13 +0000 Subject: [PATCH 022/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 47a971965..d394c7681 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -58,8 +58,8 @@ build ryu-openflow: end2end_test ryu_openflow: timeout: 90m variables: - #TEST_NAME: 'ryu-openflow' - #IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' + TEST_NAME: 'ryu-openflow' + IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' #stage: end2end_test # Disable to force running it after all other tasks #needs: -- GitLab From cb1fc9ed0516a8bdacebf134cb29399d4dad9a58 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:29:01 +0000 Subject: [PATCH 023/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d394c7681..23e653ec2 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,7 +55,7 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test ryu_openflow: +end2end_test ryu-openflow: timeout: 90m variables: TEST_NAME: 'ryu-openflow' -- GitLab From ba49d86d61c5f407fa3bfffd69e8753ba852771c Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:30:44 +0000 Subject: [PATCH 024/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 23e653ec2..b34f292f9 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,11 +55,11 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test ryu-openflow: - timeout: 90m - variables: - TEST_NAME: 'ryu-openflow' - IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' +#end2end_test ryu-openflow: +# timeout: 90m +# variables: +# TEST_NAME: 'ryu-openflow' +# IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' #stage: end2end_test # Disable to force running it after all other tasks #needs: -- GitLab From 68c651e6f72f760fdcde8f604e3d3a8bd7132041 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:32:26 +0000 Subject: [PATCH 025/638] add --- src/tests/ryu-openflow/.gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index b34f292f9..23e653ec2 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,11 +55,11 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -#end2end_test ryu-openflow: -# timeout: 90m -# variables: -# TEST_NAME: 'ryu-openflow' -# IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' +end2end_test ryu-openflow: + timeout: 90m + variables: + TEST_NAME: 'ryu-openflow' + IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' #stage: end2end_test # Disable to force running it after all other tasks #needs: -- GitLab From fe57292f3192b1822c3d258100a8f5daba17d24f Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:35:48 +0000 Subject: [PATCH 026/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 23e653ec2..e61312254 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -56,10 +56,10 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test end2end_test ryu-openflow: - timeout: 90m - variables: - TEST_NAME: 'ryu-openflow' - IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' + #timeout: 90m + #variables: + # TEST_NAME: 'ryu-openflow' + # IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' #stage: end2end_test # Disable to force running it after all other tasks #needs: -- GitLab From adac956f787c453986dba96d07bc3a6e0cec99bb Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 10:36:16 +0000 Subject: [PATCH 027/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index e61312254..dafafe3d9 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,7 +55,7 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test -end2end_test ryu-openflow: + end2end_test ryu-openflow: #timeout: 90m #variables: # TEST_NAME: 'ryu-openflow' -- GitLab From f8a94d53431ec3219c6cd2164ab657725f15f2c1 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:07:53 +0000 Subject: [PATCH 028/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index dafafe3d9..adbeeaa06 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -55,7 +55,7 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test - end2end_test ryu-openflow: +end2end_test ryu-openflow: #timeout: 90m #variables: # TEST_NAME: 'ryu-openflow' @@ -70,7 +70,7 @@ build ryu-openflow: # #- containerlab destroy --all --cleanup || true # # cleanup mininet # - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c - #script: + script: ## Download Docker images to run the test #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -- GitLab From 714c08d53cda15a15d7184b4a42229c142653d6f Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:10:28 +0000 Subject: [PATCH 029/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 65 +++++++++++---------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index adbeeaa06..624b35d35 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -56,49 +56,38 @@ build ryu-openflow: # Deploy TeraFlowSDN and Execute end-2-end test end2end_test ryu-openflow: - #timeout: 90m - #variables: - # TEST_NAME: 'ryu-openflow' - # IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' - #stage: end2end_test - # Disable to force running it after all other tasks - #needs: - # - build ryu-openflow - #before_script: - # - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - # - docker ps -aq | xargs -r docker rm -f - # #- containerlab destroy --all --cleanup || true - # # cleanup mininet - # - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c + timeout: 90m + variables: + TEST_NAME: 'ryu-openflow' + IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' + stage: end2end_test + Disable to force running it after all other tasks + needs: + - build ryu-openflow + before_script: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + - docker ps -aq | xargs -r docker rm -f + #- containerlab destroy --all --cleanup || true + # cleanup mininet + - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c script: ## Download Docker images to run the test - #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" # Check MicroK8s is ready - #- microk8s status --wait-ready - #- kubectl get pods --all-namespaces + - microk8s status --wait-ready + - kubectl get pods --all-namespaces + #run ryu and mininet + - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -# # Deploy ContainerLab Scenario -# - RUNNER_PATH=`pwd` -# #- cd $PWD/src/tests/${TEST_NAME} -# - mkdir -p /tmp/clab/${TEST_NAME} -# - cp -R src/tests/${TEST_NAME}/clab/* /tmp/clab/${TEST_NAME} -# - tree -la /tmp/clab/${TEST_NAME} -# - cd /tmp/clab/${TEST_NAME} -# - containerlab deploy --reconfigure --topo ryu-openflow.clab.yml -# - cd $RUNNER_PATH - - #- docker network rm tfs-test-net || true - #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - #- docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - #- docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -# -# # # Wait for initialization of Device NOSes - #- sleep 10 - #- docker ps -a -## + # Wait for initialization of Device NOSes + - sleep 10 + - docker ps -a +# # Configure TeraFlowSDN deployment ## Uncomment if DEBUG log level is needed for the components #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml -- GitLab From 76869645c23fd3075d12f0a655e2e577f1da848b Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:12:39 +0000 Subject: [PATCH 030/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 624b35d35..5babf4998 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -71,22 +71,25 @@ end2end_test ryu-openflow: # cleanup mininet - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c script: + - echo "Starting script section" ## Download Docker images to run the test - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" + #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" - # Check MicroK8s is ready - - microk8s status --wait-ready - - kubectl get pods --all-namespaces - #run ryu and mininet - - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - # Wait for initialization of Device NOSes - - sleep 10 - - docker ps -a + ## Check MicroK8s is ready + #- microk8s status --wait-ready + #- kubectl get pods --all-namespaces + ##run ryu and mininet + #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + #- docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + #- docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" +# + ## Wait for initialization of Device NOSes + #- sleep 10 + #- docker ps -a + - echo "Finishing script section" # # Configure TeraFlowSDN deployment ## Uncomment if DEBUG log level is needed for the components -- GitLab From d91f6d0a6f7c925bf2bb721d4f78a202ce35f5af Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:13:33 +0000 Subject: [PATCH 031/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 5babf4998..d153ef2b4 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -61,7 +61,7 @@ end2end_test ryu-openflow: TEST_NAME: 'ryu-openflow' IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' stage: end2end_test - Disable to force running it after all other tasks + #Disable to force running it after all other tasks needs: - build ryu-openflow before_script: -- GitLab From bfd6337b06b2d4f38ba307da373b55e4d3888bd4 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:14:57 +0000 Subject: [PATCH 032/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d153ef2b4..16e5528db 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -73,9 +73,9 @@ end2end_test ryu-openflow: script: - echo "Starting script section" ## Download Docker images to run the test - #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" - #- docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" ## Check MicroK8s is ready -- GitLab From c2cb05501e0829a2a47ec1a6e8cdf1890d4e4337 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:15:42 +0000 Subject: [PATCH 033/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 16e5528db..e75535e92 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -79,16 +79,16 @@ end2end_test ryu-openflow: ## Check MicroK8s is ready - #- microk8s status --wait-ready - #- kubectl get pods --all-namespaces + - microk8s status --wait-ready + - kubectl get pods --all-namespaces ##run ryu and mininet - #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - #- docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - #- docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes - #- sleep 10 - #- docker ps -a + - sleep 10 + - docker ps -a - echo "Finishing script section" # # Configure TeraFlowSDN deployment -- GitLab From dc2ad01005262b322da001c804baca736d6f00a4 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:26:57 +0000 Subject: [PATCH 034/638] adding switches configuration --- src/tests/ryu-openflow/.gitlab-ci.yml | 50 +++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index e75535e92..bf7f8acb3 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -100,19 +100,19 @@ end2end_test ryu-openflow: #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml ## - #- source src/tests/${TEST_NAME}/deploy_specs.sh - #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" - #- export TFS_SKIP_BUILD="YES" - #- export TFS_IMAGE_TAG="latest" - #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" -# - # Deploy TeraFlowSDN - # - ./deploy/crdb.sh - # - ./deploy/nats.sh - # - ./deploy/kafka.sh - # - ./deploy/qdb.sh - # - ./deploy/tfs.sh - # - ./deploy/show.sh + - source src/tests/${TEST_NAME}/deploy_specs.sh + - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" + - export TFS_SKIP_BUILD="YES" + - export TFS_IMAGE_TAG="latest" + - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" +# + Deploy TeraFlowSDN + - ./deploy/crdb.sh + - ./deploy/nats.sh + - ./deploy/kafka.sh + - ./deploy/qdb.sh + - ./deploy/tfs.sh + - ./deploy/show.sh # # ## Wait for Context to be subscribed to NATS # ## WARNING: this loop is infinite if there is no subscriber (such as monitoring). @@ -131,17 +131,23 @@ end2end_test ryu-openflow: # # break # # fi # # done - #- kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server + - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server ## Run end-to-end test: onboard scenario - #- > - # docker run -t --rm --name ${TEST_NAME} --network=host - # --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" - # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" - # $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh -# -# # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) -# + - > + docker run -t --rm --name ${TEST_NAME} --network=host + --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" + --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" + $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh + +# Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s2 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s3 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s4 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s5 + + # # Run end-to-end test: configure service IETF # - > # docker run -t --rm --name ${TEST_NAME} --network=host -- GitLab From 4227158cef351cde37eb4fb1fdb6e959d1e75564 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:28:58 +0000 Subject: [PATCH 035/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 48 +++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index bf7f8acb3..6eed537ed 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -100,19 +100,19 @@ end2end_test ryu-openflow: #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml ## - - source src/tests/${TEST_NAME}/deploy_specs.sh - - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" - - export TFS_SKIP_BUILD="YES" - - export TFS_IMAGE_TAG="latest" - - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" -# - Deploy TeraFlowSDN - - ./deploy/crdb.sh - - ./deploy/nats.sh - - ./deploy/kafka.sh - - ./deploy/qdb.sh - - ./deploy/tfs.sh - - ./deploy/show.sh + #- source src/tests/${TEST_NAME}/deploy_specs.sh + #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" + #- export TFS_SKIP_BUILD="YES" + #- export TFS_IMAGE_TAG="latest" + #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" +## + # Deploy TeraFlowSDN + #- ./deploy/crdb.sh + #- ./deploy/nats.sh + #- ./deploy/kafka.sh + #- ./deploy/qdb.sh + #- ./deploy/tfs.sh + #- ./deploy/show.sh # # ## Wait for Context to be subscribed to NATS # ## WARNING: this loop is infinite if there is no subscriber (such as monitoring). @@ -131,21 +131,21 @@ end2end_test ryu-openflow: # # break # # fi # # done - - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server + #- kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server ## Run end-to-end test: onboard scenario - - > - docker run -t --rm --name ${TEST_NAME} --network=host - --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" - --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" - $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh + #- > + # docker run -t --rm --name ${TEST_NAME} --network=host + # --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" + # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" + # $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s2 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s3 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s4 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s5 + #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 + #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s2 + #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s3 + #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s4 + #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s5 # # Run end-to-end test: configure service IETF -- GitLab From cd6a36db2c44c93398d81eab57115a8cce89641a Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:30:23 +0000 Subject: [PATCH 036/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 6eed537ed..79bfbb3be 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -100,11 +100,11 @@ end2end_test ryu-openflow: #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml ## - #- source src/tests/${TEST_NAME}/deploy_specs.sh - #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" - #- export TFS_SKIP_BUILD="YES" - #- export TFS_IMAGE_TAG="latest" - #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" + - source src/tests/${TEST_NAME}/deploy_specs.sh + - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" + - export TFS_SKIP_BUILD="YES" + - export TFS_IMAGE_TAG="latest" + - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" ## # Deploy TeraFlowSDN #- ./deploy/crdb.sh -- GitLab From 7fc724046961d96ffc92f1e659d1ef49df7eaf23 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:34:22 +0000 Subject: [PATCH 037/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 79bfbb3be..72ccbf74e 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -82,6 +82,8 @@ end2end_test ryu-openflow: - microk8s status --wait-ready - kubectl get pods --all-namespaces ##run ryu and mininet + - docker rm -f ryu mininet || true + - docker network rm tfs-test-ryu || true - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" @@ -107,12 +109,12 @@ end2end_test ryu-openflow: - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" ## # Deploy TeraFlowSDN - #- ./deploy/crdb.sh - #- ./deploy/nats.sh - #- ./deploy/kafka.sh - #- ./deploy/qdb.sh - #- ./deploy/tfs.sh - #- ./deploy/show.sh + - ./deploy/crdb.sh + - ./deploy/nats.sh + - ./deploy/kafka.sh + - ./deploy/qdb.sh + - ./deploy/tfs.sh + - ./deploy/show.sh # # ## Wait for Context to be subscribed to NATS # ## WARNING: this loop is infinite if there is no subscriber (such as monitoring). -- GitLab From a36567dd48b7a1f3c3a34681d74d7c563895d7a1 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 11:39:02 +0000 Subject: [PATCH 038/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 72ccbf74e..e366ea854 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -133,14 +133,14 @@ end2end_test ryu-openflow: # # break # # fi # # done - #- kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server + - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server ## Run end-to-end test: onboard scenario - #- > - # docker run -t --rm --name ${TEST_NAME} --network=host - # --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" - # --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" - # $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh + - > + docker run -t --rm --name ${TEST_NAME} --network=host + --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" + --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" + $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 -- GitLab From 25228cc81637d207dc4878154b32aea1a3b79f13 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 12:10:27 +0000 Subject: [PATCH 039/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index e366ea854..cc74d00b4 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -137,7 +137,7 @@ end2end_test ryu-openflow: ## Run end-to-end test: onboard scenario - > - docker run -t --rm --name ${TEST_NAME} --network=host + docker run -t --rm --name ${TEST_NAME}-test --network=host --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh -- GitLab From a6fdac6d15cf156987c60b19053cecf369d55d2d Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 12:25:11 +0000 Subject: [PATCH 040/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index cc74d00b4..5e389aac2 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -137,10 +137,10 @@ end2end_test ryu-openflow: ## Run end-to-end test: onboard scenario - > - docker run -t --rm --name ${TEST_NAME}-test --network=host + docker run -t --rm --name ${TEST_NAME}-test --network=host --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" - $CI_REGISTRY_IMAGE/${TEST_NAME}:${IMAGE_TAG} /var/teraflow/run-onboarding.sh + $CI_REGISTRY_IMAGE/${TEST_NAME}-test :${IMAGE_TAG} /var/teraflow/run-onboarding.sh # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 -- GitLab From 6b884554e97bb7ebaa898e522e47d06063347b71 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 12:38:54 +0000 Subject: [PATCH 041/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 5e389aac2..6263b9f82 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -137,10 +137,10 @@ end2end_test ryu-openflow: ## Run end-to-end test: onboard scenario - > - docker run -t --rm --name ${TEST_NAME}-test --network=host + docker run -t --rm --name ${TEST_NAME} --network=host --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" - $CI_REGISTRY_IMAGE/${TEST_NAME}-test :${IMAGE_TAG} /var/teraflow/run-onboarding.sh + "${CI_REGISTRY_IMAGE}/${TEST_NAME}-test:${IMAGE_TAG}" /var/teraflow/run-onboarding.sh # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 -- GitLab From 0bc68ddb40707a98e597536e662949af6e8af33e Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 13:02:23 +0000 Subject: [PATCH 042/638] Update file tfs-topology.json --- src/tests/ryu-openflow/data/tfs-topology.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/data/tfs-topology.json b/src/tests/ryu-openflow/data/tfs-topology.json index e427f16ea..fda873aa9 100644 --- a/src/tests/ryu-openflow/data/tfs-topology.json +++ b/src/tests/ryu-openflow/data/tfs-topology.json @@ -14,7 +14,7 @@ { "device_id": {"device_uuid": {"uuid": "RYU"}}, "device_type": "openflow-ryu-controller", "device_drivers": ["DEVICEDRIVER_RYU"], "device_config": {"config_rules": [ - {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.254.254.10"}}, {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8080"}}, {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} ]} -- GitLab From 381c2c8006f8c3af18bef7cdb3aafe725bc96605 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 19:41:30 +0000 Subject: [PATCH 043/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 6263b9f82..eb7c37465 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -84,7 +84,8 @@ end2end_test ryu-openflow: ##run ryu and mininet - docker rm -f ryu mininet || true - docker network rm tfs-test-ryu || true - - docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + - docker network create -d bridge --subnet=172.20.0.0/24 --gateway=172.20.0.1 tfs-test-ryu - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # -- GitLab From 20f7194c4a90c7e2623e31539cb639ec74c6eb21 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 20:32:05 +0000 Subject: [PATCH 044/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index eb7c37465..e71f0e29a 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -86,7 +86,7 @@ end2end_test ryu-openflow: - docker network rm tfs-test-ryu || true #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - docker network create -d bridge --subnet=172.20.0.0/24 --gateway=172.20.0.1 tfs-test-ryu - - docker run -d --name ryu --network tfs-test-ryu --ip 172.254.254.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - docker run -d --name ryu --network tfs-test-ryu --ip 172.20.0.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes -- GitLab From 0379381c8e87e20cdd31df6bfe97f846d03a3ec8 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 20:43:04 +0000 Subject: [PATCH 045/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index e71f0e29a..b46eb3208 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -84,7 +84,7 @@ end2end_test ryu-openflow: ##run ryu and mininet - docker rm -f ryu mininet || true - docker network rm tfs-test-ryu || true - #- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + ##- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - docker network create -d bridge --subnet=172.20.0.0/24 --gateway=172.20.0.1 tfs-test-ryu - docker run -d --name ryu --network tfs-test-ryu --ip 172.20.0.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -- GitLab From d77c1287c632c7d2adfaff99e708229b5b61af24 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 20:51:48 +0000 Subject: [PATCH 046/638] Update file tfs-topology.json --- src/tests/ryu-openflow/data/tfs-topology.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/data/tfs-topology.json b/src/tests/ryu-openflow/data/tfs-topology.json index fda873aa9..d7823d4bb 100644 --- a/src/tests/ryu-openflow/data/tfs-topology.json +++ b/src/tests/ryu-openflow/data/tfs-topology.json @@ -14,7 +14,7 @@ { "device_id": {"device_uuid": {"uuid": "RYU"}}, "device_type": "openflow-ryu-controller", "device_drivers": ["DEVICEDRIVER_RYU"], "device_config": {"config_rules": [ - {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.254.254.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.20.0.10"}}, {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8080"}}, {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} ]} -- GitLab From 13db3625541a1b3de8614c998efd8b5bf5b27955 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 21:00:01 +0000 Subject: [PATCH 047/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index b46eb3208..d24b4ce9b 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -84,7 +84,7 @@ end2end_test ryu-openflow: ##run ryu and mininet - docker rm -f ryu mininet || true - docker network rm tfs-test-ryu || true - ##- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu + ###- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - docker network create -d bridge --subnet=172.20.0.0/24 --gateway=172.20.0.1 tfs-test-ryu - docker run -d --name ryu --network tfs-test-ryu --ip 172.20.0.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -- GitLab From 35669c02c497f84147a197a3240f4a616f923797 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 21:20:03 +0000 Subject: [PATCH 048/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d24b4ce9b..8042ea003 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -113,7 +113,7 @@ end2end_test ryu-openflow: - ./deploy/crdb.sh - ./deploy/nats.sh - ./deploy/kafka.sh - - ./deploy/qdb.sh + #- ./deploy/qdb.sh - ./deploy/tfs.sh - ./deploy/show.sh # -- GitLab From 00cd26b643fc16aeafbb2bca63e16c0ee96c5fe0 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 21:36:55 +0000 Subject: [PATCH 049/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 8042ea003..f0abeb1da 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -93,15 +93,21 @@ end2end_test ryu-openflow: - sleep 10 - docker ps -a - echo "Finishing script section" -# +# Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s2 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s3 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s4 + - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s5 + # Configure TeraFlowSDN deployment ## Uncomment if DEBUG log level is needed for the components - #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml - #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml - #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml - #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml - #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml - #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml + - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml ## - source src/tests/${TEST_NAME}/deploy_specs.sh - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" -- GitLab From 8cc04e0497caac63057dd8c197faaf69e08a75f0 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 21:48:57 +0000 Subject: [PATCH 050/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index f0abeb1da..d14793681 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -94,11 +94,11 @@ end2end_test ryu-openflow: - docker ps -a - echo "Finishing script section" # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s1 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s2 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s3 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s4 - - docker exec ryu-openflow-mininet ovs-ofctl dump-flows s5 + - docker exec mininet ovs-ofctl dump-flows s1 + - docker exec mininet ovs-ofctl dump-flows s2 + - docker exec mininet ovs-ofctl dump-flows s3 + - docker exec mininet ovs-ofctl dump-flows s4 + - docker exec mininet ovs-ofctl dump-flows s5 # Configure TeraFlowSDN deployment ## Uncomment if DEBUG log level is needed for the components -- GitLab From f30acc7916f5094969df2ab19caf803348f9a519 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 22:13:48 +0000 Subject: [PATCH 051/638] Update file custom_pentagon_topology.py --- src/tests/ryu-openflow/custom_pentagon_topology.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/custom_pentagon_topology.py index 03605f24a..e6a305555 100644 --- a/src/tests/ryu-openflow/custom_pentagon_topology.py +++ b/src/tests/ryu-openflow/custom_pentagon_topology.py @@ -18,6 +18,7 @@ from mininet.net import Mininet from mininet.node import RemoteController from mininet.cli import CLI from mininet.link import TCLink +import time class PentagonTopo(Topo): def build(self): @@ -51,5 +52,7 @@ if __name__ == '__main__': net.staticArp() print('Custom Pentagon Topology is up with static ARP.') - CLI(net) + #CLI(net) + while True: + time.sleep(60) net.stop() -- GitLab From 9f82b9d2c60652501c5bf848f23b2ee2a128437a Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 22:19:56 +0000 Subject: [PATCH 052/638] Update file custom_pentagon_topology.py --- src/tests/ryu-openflow/custom_pentagon_topology.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/custom_pentagon_topology.py index e6a305555..970bfd58c 100644 --- a/src/tests/ryu-openflow/custom_pentagon_topology.py +++ b/src/tests/ryu-openflow/custom_pentagon_topology.py @@ -53,6 +53,13 @@ if __name__ == '__main__': print('Custom Pentagon Topology is up with static ARP.') #CLI(net) + try: while True: - time.sleep(60) - net.stop() + time.sleep(60) + except KeyboardInterrupt: + print("Stopping topology.") + finally: + net.stop() + #while True: + #time.sleep(60) + #net.stop() -- GitLab From ca437f088875463953f4347c601a5a540d0392b6 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 22:40:15 +0000 Subject: [PATCH 053/638] Update file custom_pentagon_topology.py --- src/tests/ryu-openflow/custom_pentagon_topology.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/custom_pentagon_topology.py index 970bfd58c..9f3efbcda 100644 --- a/src/tests/ryu-openflow/custom_pentagon_topology.py +++ b/src/tests/ryu-openflow/custom_pentagon_topology.py @@ -54,8 +54,8 @@ if __name__ == '__main__': print('Custom Pentagon Topology is up with static ARP.') #CLI(net) try: - while True: - time.sleep(60) + while True: + time.sleep(60) except KeyboardInterrupt: print("Stopping topology.") finally: -- GitLab From 4ccce6ef4abaf0042e8d293592bad65898ece3d3 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 2 Jun 2025 22:45:33 +0000 Subject: [PATCH 054/638] Update 2 files - /src/tests/ryu-openflow/custom_pentagon_topology.py - /src/tests/ryu-openflow/.gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 ++ src/tests/ryu-openflow/custom_pentagon_topology.py | 9 ++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d14793681..52cc38c76 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -94,6 +94,8 @@ end2end_test ryu-openflow: - docker ps -a - echo "Finishing script section" # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) + - docker exec mininet ovs-vsctl show + - docker logs mininet - docker exec mininet ovs-ofctl dump-flows s1 - docker exec mininet ovs-ofctl dump-flows s2 - docker exec mininet ovs-ofctl dump-flows s3 diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/custom_pentagon_topology.py index 9f3efbcda..616890dad 100644 --- a/src/tests/ryu-openflow/custom_pentagon_topology.py +++ b/src/tests/ryu-openflow/custom_pentagon_topology.py @@ -53,13 +53,8 @@ if __name__ == '__main__': print('Custom Pentagon Topology is up with static ARP.') #CLI(net) - try: - while True: - time.sleep(60) - except KeyboardInterrupt: - print("Stopping topology.") - finally: - net.stop() + while True: + time.sleep(60) #while True: #time.sleep(60) #net.stop() -- GitLab From f6928d6c488d270ea55386c8666156b9f2c2f0b0 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 10:47:10 +0000 Subject: [PATCH 055/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 52cc38c76..8a833db5a 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -92,6 +92,8 @@ end2end_test ryu-openflow: ## Wait for initialization of Device NOSes - sleep 10 - docker ps -a + - docker logs ryu + - docker logs mininet - echo "Finishing script section" # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) - docker exec mininet ovs-vsctl show -- GitLab From aa1ee7023727e1003db8810cd211dc0183508e8b Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 11:06:31 +0000 Subject: [PATCH 056/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 8a833db5a..91759effa 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -87,6 +87,7 @@ end2end_test ryu-openflow: ###- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - docker network create -d bridge --subnet=172.20.0.0/24 --gateway=172.20.0.1 tfs-test-ryu - docker run -d --name ryu --network tfs-test-ryu --ip 172.20.0.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" + - sleep 30 - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes -- GitLab From e0121a0ad6a873cf22a2cdf93fa4d95d9c1dbc30 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 12:09:51 +0000 Subject: [PATCH 057/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 91759effa..474e24642 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -87,7 +87,13 @@ end2end_test ryu-openflow: ###- docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 tfs-test-ryu - docker network create -d bridge --subnet=172.20.0.0/24 --gateway=172.20.0.1 tfs-test-ryu - docker run -d --name ryu --network tfs-test-ryu --ip 172.20.0.10 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-ryu:${IMAGE_TAG}" - - sleep 30 + - | + echo "Waiting for Ryu to be ready..." + until curl -s http://172.20.0.10:8080 >/dev/null; do + echo "Still waiting..." + sleep 5 + done + echo "Ryu is ready!" - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes -- GitLab From 67aa32fa6fcc9fb78cab558471da5e46b9e1699b Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 12:21:45 +0000 Subject: [PATCH 058/638] Update file custom_pentagon_topology.py --- src/tests/ryu-openflow/custom_pentagon_topology.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/custom_pentagon_topology.py index 616890dad..310cb4dc9 100644 --- a/src/tests/ryu-openflow/custom_pentagon_topology.py +++ b/src/tests/ryu-openflow/custom_pentagon_topology.py @@ -46,7 +46,7 @@ class PentagonTopo(Topo): if __name__ == '__main__': topo = PentagonTopo() - net = Mininet(topo=topo, controller=lambda name: RemoteController(name, ip='127.0.0.1'), link=TCLink) + net = Mininet(topo=topo, controller=lambda name: RemoteController(name, ip='172.20.0.10'), link=TCLink) net.start() net.staticArp() -- GitLab From 3c1f6a1571ffa689308c35f7ae759ddb609f2ab1 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 12:39:44 +0000 Subject: [PATCH 059/638] Update file custom_pentagon_topology.py --- src/tests/ryu-openflow/custom_pentagon_topology.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/custom_pentagon_topology.py index 310cb4dc9..5d9012866 100644 --- a/src/tests/ryu-openflow/custom_pentagon_topology.py +++ b/src/tests/ryu-openflow/custom_pentagon_topology.py @@ -46,7 +46,7 @@ class PentagonTopo(Topo): if __name__ == '__main__': topo = PentagonTopo() - net = Mininet(topo=topo, controller=lambda name: RemoteController(name, ip='172.20.0.10'), link=TCLink) + net = Mininet(topo=topo, controller=lambda name: RemoteController(name, ip='172.20.0.10', port=6653), link=TCLink) net.start() net.staticArp() -- GitLab From d18e25bc9649b60a047ac9bc6fb130773010387e Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 13:35:05 +0000 Subject: [PATCH 060/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 474e24642..c3c52ef9a 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -94,7 +94,7 @@ end2end_test ryu-openflow: sleep 5 done echo "Ryu is ready!" - - docker run -d --name mininet --network tfs-test-ryu "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes - sleep 10 -- GitLab From 6281d306ab0356e30ac16b35870f0c6666f3dabb Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 13:42:51 +0000 Subject: [PATCH 061/638] Update file docker-compose.yml --- src/tests/ryu-openflow/docker-compose.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests/ryu-openflow/docker-compose.yml b/src/tests/ryu-openflow/docker-compose.yml index 611129592..5d1204b7d 100644 --- a/src/tests/ryu-openflow/docker-compose.yml +++ b/src/tests/ryu-openflow/docker-compose.yml @@ -18,3 +18,15 @@ services: build: context: . dockerfile: Ryu.Dockerfile + +version: '3' +services: + mininet: + build: + context: . + image: mininet + tty: true + privileged: true + network_mode: "host" + volumes: + - /lib/modules:/lib/modules \ No newline at end of file -- GitLab From cbcb9bd3b413176672ce19b5b3ca96ba0cc87a6d Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 15:10:32 +0000 Subject: [PATCH 062/638] Update 2 files - /src/tests/ryu-openflow/docker-compose.yml - /src/tests/ryu-openflow/.gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 1 + src/tests/ryu-openflow/docker-compose.yml | 13 +------------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index c3c52ef9a..ae44c1762 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -99,6 +99,7 @@ end2end_test ryu-openflow: ## Wait for initialization of Device NOSes - sleep 10 - docker ps -a + - docker inspect mininet - docker logs ryu - docker logs mininet - echo "Finishing script section" diff --git a/src/tests/ryu-openflow/docker-compose.yml b/src/tests/ryu-openflow/docker-compose.yml index 5d1204b7d..b4892184a 100644 --- a/src/tests/ryu-openflow/docker-compose.yml +++ b/src/tests/ryu-openflow/docker-compose.yml @@ -18,15 +18,4 @@ services: build: context: . dockerfile: Ryu.Dockerfile - -version: '3' -services: - mininet: - build: - context: . - image: mininet - tty: true - privileged: true - network_mode: "host" - volumes: - - /lib/modules:/lib/modules \ No newline at end of file + -- GitLab From 6bcf93aa3dbe337edaa18589234368a57621cbaf Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 15:53:46 +0000 Subject: [PATCH 063/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index ae44c1762..bfc7340a3 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -94,7 +94,13 @@ end2end_test ryu-openflow: sleep 5 done echo "Ryu is ready!" - - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 \ + --privileged \ + --ulimit memlock=-1:-1 \ + --ulimit nofile=65536:65536 \ + --ulimit nproc=65536:65536 \ + mininet-image-name + # - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes - sleep 10 -- GitLab From 201f9ddf42620f9356c8a22d60d1cb0ec9754cab Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 15:57:07 +0000 Subject: [PATCH 064/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index bfc7340a3..524aba2d8 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -94,12 +94,8 @@ end2end_test ryu-openflow: sleep 5 done echo "Ryu is ready!" - - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 \ - --privileged \ - --ulimit memlock=-1:-1 \ - --ulimit nofile=65536:65536 \ - --ulimit nproc=65536:65536 \ - mininet-image-name + + - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 --privileged --ulimit memlock=-1:-1 --ulimit nofile=65536:65536 --ulimit nproc=65536:65536 mininet-image-name # - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes -- GitLab From 553d8c3f7fc0d1858e0d62b5a126d0f2ebecf324 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 16:01:11 +0000 Subject: [PATCH 065/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 524aba2d8..ba38db4bf 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -95,7 +95,7 @@ end2end_test ryu-openflow: done echo "Ryu is ready!" - - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 --privileged --ulimit memlock=-1:-1 --ulimit nofile=65536:65536 --ulimit nproc=65536:65536 mininet-image-name + - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 --privileged --ulimit memlock=-1:-1 --ulimit nofile=65536:65536 --ulimit nproc=65536:65536 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # ## Wait for initialization of Device NOSes -- GitLab From 3019b226bd0dca9cd2bf0f2ca0d6fbc927e3ab8e Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 10 Jun 2025 16:08:04 +0000 Subject: [PATCH 066/638] Update file Mininet.Dockerfile --- src/tests/ryu-openflow/Mininet.Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/Mininet.Dockerfile b/src/tests/ryu-openflow/Mininet.Dockerfile index 0a829bb49..4b6bee010 100644 --- a/src/tests/ryu-openflow/Mininet.Dockerfile +++ b/src/tests/ryu-openflow/Mininet.Dockerfile @@ -24,4 +24,7 @@ RUN apt-get update && \ COPY src/tests/ryu-openflow/custom_pentagon_topology.py /opt/custom_pentagon_topology.py -CMD ["python3", "/opt/custom_pentagon_topology.py"] +CMD sh -c "/usr/share/openvswitch/scripts/ovs-ctl start && python3 /opt/custom_pentagon_topology.py" + + +#CMD ["python3", "/opt/custom_pentagon_topology.py"] -- GitLab From 34c6ff0c23bd79eba4b64d4b8540a16dd5f5d9d1 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Wed, 11 Jun 2025 09:37:38 +0000 Subject: [PATCH 067/638] Update file Mininet.Dockerfile --- src/tests/ryu-openflow/Mininet.Dockerfile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tests/ryu-openflow/Mininet.Dockerfile b/src/tests/ryu-openflow/Mininet.Dockerfile index 4b6bee010..5fb95e6d0 100644 --- a/src/tests/ryu-openflow/Mininet.Dockerfile +++ b/src/tests/ryu-openflow/Mininet.Dockerfile @@ -23,8 +23,4 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* COPY src/tests/ryu-openflow/custom_pentagon_topology.py /opt/custom_pentagon_topology.py - -CMD sh -c "/usr/share/openvswitch/scripts/ovs-ctl start && python3 /opt/custom_pentagon_topology.py" - - -#CMD ["python3", "/opt/custom_pentagon_topology.py"] +CMD ["python3", "/opt/custom_pentagon_topology.py"] -- GitLab From 7c89ed58fc3f703cb875cefd864106e9773d8147 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 26 Jun 2025 17:34:33 +0000 Subject: [PATCH 068/638] Ryu-OpenFlow CI/CD test - Fixed docker exec commands --- src/tests/ryu-openflow/.gitlab-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index ba38db4bf..073e5c29f 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -106,13 +106,13 @@ end2end_test ryu-openflow: - docker logs mininet - echo "Finishing script section" # Dump configuration of the switches (OpenFlow rules configured) (before configure IETF service) - - docker exec mininet ovs-vsctl show + - docker exec mininet bash -c "ovs-vsctl show" - docker logs mininet - - docker exec mininet ovs-ofctl dump-flows s1 - - docker exec mininet ovs-ofctl dump-flows s2 - - docker exec mininet ovs-ofctl dump-flows s3 - - docker exec mininet ovs-ofctl dump-flows s4 - - docker exec mininet ovs-ofctl dump-flows s5 + - docker exec mininet bash -c "ovs-ofctl dump-flows s1" + - docker exec mininet bash -c "ovs-ofctl dump-flows s2" + - docker exec mininet bash -c "ovs-ofctl dump-flows s3" + - docker exec mininet bash -c "ovs-ofctl dump-flows s4" + - docker exec mininet bash -c "ovs-ofctl dump-flows s5" # Configure TeraFlowSDN deployment ## Uncomment if DEBUG log level is needed for the components -- GitLab From b2e882ec5a61edeac987ceafde1f7a298f3a24ec Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 26 Jun 2025 17:44:39 +0000 Subject: [PATCH 069/638] Ryu-OpenFlow CI/CD test - Corrected mininet dockerfile --- src/tests/ryu-openflow/Mininet.Dockerfile | 11 +++++++++-- .../{ => mininet}/custom_pentagon_topology.py | 0 src/tests/ryu-openflow/mininet/mininet-entrypoint.sh | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) rename src/tests/ryu-openflow/{ => mininet}/custom_pentagon_topology.py (100%) create mode 100644 src/tests/ryu-openflow/mininet/mininet-entrypoint.sh diff --git a/src/tests/ryu-openflow/Mininet.Dockerfile b/src/tests/ryu-openflow/Mininet.Dockerfile index 5fb95e6d0..1d6328554 100644 --- a/src/tests/ryu-openflow/Mininet.Dockerfile +++ b/src/tests/ryu-openflow/Mininet.Dockerfile @@ -14,6 +14,9 @@ FROM ubuntu:22.04 +USER root +WORKDIR /root + ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y --no-install-recommends iproute2 net-tools openvswitch-switch ca-certificates && \ @@ -22,5 +25,9 @@ RUN apt-get update && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -COPY src/tests/ryu-openflow/custom_pentagon_topology.py /opt/custom_pentagon_topology.py -CMD ["python3", "/opt/custom_pentagon_topology.py"] +COPY src/tests/ryu-openflow/mininet/custom_pentagon_topology.py /opt/custom_pentagon_topology.py +COPY src/tests/ryu-openflow/mininet/mininet-entrypoint.sh /mininet-entrypoint.sh + +EXPOSE 6633 6653 6640 + +ENTRYPOINT ["/mininet-entrypoint.sh"] diff --git a/src/tests/ryu-openflow/custom_pentagon_topology.py b/src/tests/ryu-openflow/mininet/custom_pentagon_topology.py similarity index 100% rename from src/tests/ryu-openflow/custom_pentagon_topology.py rename to src/tests/ryu-openflow/mininet/custom_pentagon_topology.py diff --git a/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh b/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh new file mode 100644 index 000000000..b5eb4066f --- /dev/null +++ b/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +service openvswitch-switch start +ovs-vsctl set-manager ptcp:6640 + +python3 /opt/custom_pentagon_topology.py + +service openvswitch-switch stop -- GitLab From 97b3c55a7a4cebde7792457316cec4b149556138 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 26 Jun 2025 17:47:11 +0000 Subject: [PATCH 070/638] Ryu-OpenFlow CI/CD test - Corrected mininet dockerfile entrypoint permissions --- src/tests/ryu-openflow/mininet/mininet-entrypoint.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/tests/ryu-openflow/mininet/mininet-entrypoint.sh diff --git a/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh b/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh old mode 100644 new mode 100755 -- GitLab From 199ceb30c8b0ae10747ccbe10576743a61596fb7 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 26 Jun 2025 17:54:47 +0000 Subject: [PATCH 071/638] Ryu-OpenFlow CI/CD test - Added ACK - Corrected mininet instantiation --- src/tests/ryu-openflow/.gitlab-ci.yml | 6 +++--- .../ryu-openflow/{ => mininet}/Mininet.Dockerfile | 2 ++ src/tests/ryu-openflow/mininet/README.md | 3 +++ .../ryu-openflow/mininet/mininet-entrypoint.sh | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) rename src/tests/ryu-openflow/{ => mininet}/Mininet.Dockerfile (95%) create mode 100644 src/tests/ryu-openflow/mininet/README.md diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 073e5c29f..e3181fb76 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -24,7 +24,7 @@ build ryu-openflow: script: - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Ryu.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-ryu:${IMAGE_TAG}" - - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Mininet.Dockerfile . + - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/mininet/Mininet.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-mininet:${IMAGE_TAG}" - docker buildx build -t "$CI_REGISTRY_IMAGE/${TEST_NAME}-test:${IMAGE_TAG}" -f ./src/tests/${TEST_NAME}/Test.Dockerfile . - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}-test:${IMAGE_TAG}" @@ -95,9 +95,9 @@ end2end_test ryu-openflow: done echo "Ryu is ready!" - - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 --privileged --ulimit memlock=-1:-1 --ulimit nofile=65536:65536 --ulimit nproc=65536:65536 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" + - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 --privileged --ulimit memlock=-1:-1 --ulimit nofile=65536:65536 --ulimit nproc=65536:65536 --volume /lib/modules:/lib/modules "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" # - docker run -d --name mininet --network tfs-test-ryu --ip 172.20.0.11 "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" -# + ## Wait for initialization of Device NOSes - sleep 10 - docker ps -a diff --git a/src/tests/ryu-openflow/Mininet.Dockerfile b/src/tests/ryu-openflow/mininet/Mininet.Dockerfile similarity index 95% rename from src/tests/ryu-openflow/Mininet.Dockerfile rename to src/tests/ryu-openflow/mininet/Mininet.Dockerfile index 1d6328554..ea18a3dd8 100644 --- a/src/tests/ryu-openflow/Mininet.Dockerfile +++ b/src/tests/ryu-openflow/mininet/Mininet.Dockerfile @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Based on: https://github.com/iwaseyusuke/docker-mininet + FROM ubuntu:22.04 USER root diff --git a/src/tests/ryu-openflow/mininet/README.md b/src/tests/ryu-openflow/mininet/README.md new file mode 100644 index 000000000..8cc106555 --- /dev/null +++ b/src/tests/ryu-openflow/mininet/README.md @@ -0,0 +1,3 @@ +# Docker-containerized Mininet environment + +- Based on: https://github.com/iwaseyusuke/docker-mininet diff --git a/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh b/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh index b5eb4066f..525e89d0a 100755 --- a/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh +++ b/src/tests/ryu-openflow/mininet/mininet-entrypoint.sh @@ -1,4 +1,19 @@ #!/bin/bash +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + +# Based on: https://github.com/iwaseyusuke/docker-mininet service openvswitch-switch start ovs-vsctl set-manager ptcp:6640 -- GitLab From ed3162863dfa808d2e4cf5a0435d2fd843b30b4f Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 30 Jun 2025 13:13:00 +0000 Subject: [PATCH 072/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index e3181fb76..d20d038af 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -32,7 +32,7 @@ build ryu-openflow: - docker images --filter="dangling=true" --quiet | xargs -r docker rmi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' - #- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' + ##- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - changes: - src/common/**/*.py - proto/*.proto -- GitLab From d4e94f13b4bcb7b3349aa1b1c163066feea38ada Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 1 Jul 2025 15:01:24 +0000 Subject: [PATCH 073/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d20d038af..532f2cc96 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -32,7 +32,7 @@ build ryu-openflow: - docker images --filter="dangling=true" --quiet | xargs -r docker rmi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' - ##- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' + ###- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - changes: - src/common/**/*.py - proto/*.proto -- GitLab From d97308ea2dcf5b5b83b16f13465712e2bca3fe5f Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 8 Aug 2025 13:22:38 +0000 Subject: [PATCH 074/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 532f2cc96..2b6f82cdd 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -14,7 +14,7 @@ # Build, tag, and push the Docker image to the GitLab Docker registry build ryu-openflow: - variables: + variables: TEST_NAME: 'ryu-openflow' IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' stage: build @@ -40,7 +40,7 @@ build ryu-openflow: - src/tests/${TEST_NAME}/Dockerfile - .gitlab-ci.yml - +# # - docker rm -f na-t1 na-t2 na-r1 na-r2 # - docker network rm -f na-br # -- GitLab From 4622ac2e30f5a0b8c543382d8cb3a758749d2afe Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 11 Aug 2025 11:12:42 +0000 Subject: [PATCH 075/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 2b6f82cdd..a62fd7dce 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -69,7 +69,7 @@ end2end_test ryu-openflow: - docker ps -aq | xargs -r docker rm -f #- containerlab destroy --all --cleanup || true # cleanup mininet - - docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c + #- docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c script: - echo "Starting script section" ## Download Docker images to run the test -- GitLab From 0afea6987f9d9aafb0b968fac88d4213a54707bc Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 11 Aug 2025 11:31:37 +0000 Subject: [PATCH 076/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index a62fd7dce..6f7031743 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -116,12 +116,12 @@ end2end_test ryu-openflow: # Configure TeraFlowSDN deployment ## Uncomment if DEBUG log level is needed for the components - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml - - yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml + #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml ## - source src/tests/${TEST_NAME}/deploy_specs.sh - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" @@ -171,12 +171,12 @@ end2end_test ryu-openflow: #- docker exec ryu-openflow-mininet ovs-ofctl dump-flows s5 -# # Run end-to-end test: configure service IETF -# - > -# docker run -t --rm --name ${TEST_NAME} --network=host -# --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" -# --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" -# $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-ietf-create.sh + # Run end-to-end test: configure service IETF + - > + docker run -t --rm --name ${TEST_NAME} --network=host + --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh" + --volume "$PWD/src/tests/${TEST_NAME}:/opt/results" + $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-service-ietf-create.sh # # # Dump configuration of the switches (OpenFlow rules configured) (after configure IETF service) # -- GitLab From 94c3f9ec8e7494c8e885892c1cb35bdac5234391 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 11 Aug 2025 15:20:56 +0000 Subject: [PATCH 077/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 6f7031743..16271301b 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -122,20 +122,21 @@ end2end_test ryu-openflow: #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/monitoringservice.yaml -## + - source src/tests/${TEST_NAME}/deploy_specs.sh - - export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" - - export TFS_SKIP_BUILD="YES" - - export TFS_IMAGE_TAG="latest" - - echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" -## + #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}" + #- export TFS_SKIP_BUILD="YES" + #- export TFS_IMAGE_TAG="latest" + #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}" + # Deploy TeraFlowSDN - ./deploy/crdb.sh - ./deploy/nats.sh - ./deploy/kafka.sh - #- ./deploy/qdb.sh + - ./deploy/qdb.sh - ./deploy/tfs.sh - ./deploy/show.sh + # # ## Wait for Context to be subscribed to NATS # ## WARNING: this loop is infinite if there is no subscriber (such as monitoring). -- GitLab From 021355ec42340e126130793ee5ba8ae101a79ec8 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Tue, 12 Aug 2025 10:29:13 +0000 Subject: [PATCH 078/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 16271301b..d574ff670 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -67,7 +67,6 @@ end2end_test ryu-openflow: before_script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - docker ps -aq | xargs -r docker rm -f - #- containerlab destroy --all --cleanup || true # cleanup mininet #- docker run --rm "${CI_REGISTRY_IMAGE}/${TEST_NAME}-mininet:${IMAGE_TAG}" mn -c script: -- GitLab From e9ad6c8e9a766c24064c207dad7449520c850560 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 25 Aug 2025 11:10:57 +0000 Subject: [PATCH 079/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index d574ff670..a111dec69 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -40,7 +40,7 @@ build ryu-openflow: - src/tests/${TEST_NAME}/Dockerfile - .gitlab-ci.yml -# + # - docker rm -f na-t1 na-t2 na-r1 na-r2 # - docker network rm -f na-br # -- GitLab From 344b68b51c78f91e5a174f8fa473f3aba33c38fc Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 25 Aug 2025 13:26:04 +0000 Subject: [PATCH 080/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index a111dec69..56b1a235b 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -39,8 +39,6 @@ build ryu-openflow: - src/tests/${TEST_NAME}/**/*.{py,in,sh,yml} - src/tests/${TEST_NAME}/Dockerfile - .gitlab-ci.yml - - # - docker rm -f na-t1 na-t2 na-r1 na-r2 # - docker network rm -f na-br # -- GitLab From 5d59451b663fa867b1931eccad7bf513bbea14df Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Tue, 26 Aug 2025 08:08:25 +0000 Subject: [PATCH 081/638] Ryu E2E Integration Test: - Resolve merge conflict in CI/CD pipeline descriptors --- .gitlab-ci.yml | 40 +---------------------- src/tests/.gitlab-ci.yml | 22 ++----------- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- src/tests/ryu-openflow/docker-compose.yml | 1 - 4 files changed, 5 insertions(+), 60 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 823dfd753..c8fcd83a6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,13 +27,13 @@ workflow: # include the individual .gitlab-ci.yml of each micro-service and tests include: -<<<<<<< HEAD # #- local: '/manifests/.gitlab-ci.yml' # - local: '/src/monitoring/.gitlab-ci.yml' # - local: '/src/nbi/.gitlab-ci.yml' # - local: '/src/context/.gitlab-ci.yml' # - local: '/src/device/.gitlab-ci.yml' # - local: '/src/service/.gitlab-ci.yml' +# - local: '/src/qkd_app/.gitlab-ci.yml' # - local: '/src/dbscanserving/.gitlab-ci.yml' # - local: '/src/opticalattackmitigator/.gitlab-ci.yml' # - local: '/src/opticalattackdetector/.gitlab-ci.yml' @@ -63,44 +63,6 @@ include: # - local: '/src/e2e_orchestrator/.gitlab-ci.yml' # - local: '/src/ztp_server/.gitlab-ci.yml' # - local: '/src/osm_client/.gitlab-ci.yml' -======= - #- local: '/manifests/.gitlab-ci.yml' - - local: '/src/monitoring/.gitlab-ci.yml' - - local: '/src/nbi/.gitlab-ci.yml' - - local: '/src/context/.gitlab-ci.yml' - - local: '/src/device/.gitlab-ci.yml' - - local: '/src/service/.gitlab-ci.yml' - - local: '/src/qkd_app/.gitlab-ci.yml' - - local: '/src/dbscanserving/.gitlab-ci.yml' - - local: '/src/opticalattackmitigator/.gitlab-ci.yml' - - local: '/src/opticalattackdetector/.gitlab-ci.yml' - - local: '/src/opticalattackmanager/.gitlab-ci.yml' - - local: '/src/opticalcontroller/.gitlab-ci.yml' - - local: '/src/ztp/.gitlab-ci.yml' - - local: '/src/policy/.gitlab-ci.yml' - - local: '/src/automation/.gitlab-ci.yml' - - local: '/src/forecaster/.gitlab-ci.yml' - #- local: '/src/webui/.gitlab-ci.yml' - #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml' - #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml' - #- local: '/src/l3_attackmitigator/.gitlab-ci.yml' - - local: '/src/slice/.gitlab-ci.yml' - #- local: '/src/interdomain/.gitlab-ci.yml' - - local: '/src/pathcomp/.gitlab-ci.yml' - #- local: '/src/dlt/.gitlab-ci.yml' - - local: '/src/load_generator/.gitlab-ci.yml' - - local: '/src/bgpls_speaker/.gitlab-ci.yml' - - local: '/src/kpi_manager/.gitlab-ci.yml' - - local: '/src/kpi_value_api/.gitlab-ci.yml' - #- local: '/src/kpi_value_writer/.gitlab-ci.yml' - #- local: '/src/telemetry/.gitlab-ci.yml' - - local: '/src/analytics/.gitlab-ci.yml' - - local: '/src/qos_profile/.gitlab-ci.yml' - - local: '/src/vnt_manager/.gitlab-ci.yml' - - local: '/src/e2e_orchestrator/.gitlab-ci.yml' - - local: '/src/ztp_server/.gitlab-ci.yml' - - local: '/src/osm_client/.gitlab-ci.yml' ->>>>>>> e3f502c37e9ed4060edf0d3af0a22857867233b3 # This should be last one: end-to-end integration tests - local: '/src/tests/.gitlab-ci.yml' diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml index 4a5788147..98c0c1eb6 100644 --- a/src/tests/.gitlab-ci.yml +++ b/src/tests/.gitlab-ci.yml @@ -14,7 +14,6 @@ # include the individual .gitlab-ci.yml of each end-to-end integration test include: -<<<<<<< HEAD # - local: '/src/tests/ofc22/.gitlab-ci.yml' # #- local: '/src/tests/oeccpsc22/.gitlab-ci.yml' # - local: '/src/tests/ecoc22/.gitlab-ci.yml' @@ -26,23 +25,8 @@ include: # #- local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml' # #- local: '/src/tests/ofc25/.gitlab-ci.yml' - local: '/src/tests/ryu-openflow/.gitlab-ci.yml' +# - local: '/src/tests/qkd_end2end/.gitlab-ci.yml' # - local: '/src/tests/tools/mock_tfs_nbi_dependencies/.gitlab-ci.yml' -======= - - local: '/src/tests/ofc22/.gitlab-ci.yml' - #- local: '/src/tests/oeccpsc22/.gitlab-ci.yml' - - local: '/src/tests/ecoc22/.gitlab-ci.yml' - #- local: '/src/tests/nfvsdn22/.gitlab-ci.yml' - #- local: '/src/tests/ofc23/.gitlab-ci.yml' - - local: '/src/tests/ofc24/.gitlab-ci.yml' - - local: '/src/tests/eucnc24/.gitlab-ci.yml' - #- local: '/src/tests/ofc25-camara-agg-net-controller/.gitlab-ci.yml' - #- local: '/src/tests/ofc25-camara-e2e-controller/.gitlab-ci.yml' - #- local: '/src/tests/ofc25/.gitlab-ci.yml' - #- local: '/src/tests/ryu-openflow/.gitlab-ci.yml' - - local: '/src/tests/qkd_end2end/.gitlab-ci.yml' - - - local: '/src/tests/tools/mock_tfs_nbi_dependencies/.gitlab-ci.yml' - - local: '/src/tests/tools/mock_qkd_node/.gitlab-ci.yml' - - local: '/src/tests/tools/mock_osm_nbi/.gitlab-ci.yml' ->>>>>>> e3f502c37e9ed4060edf0d3af0a22857867233b3 +# - local: '/src/tests/tools/mock_qkd_node/.gitlab-ci.yml' +# - local: '/src/tests/tools/mock_osm_nbi/.gitlab-ci.yml' diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 56b1a235b..18e35f454 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -14,7 +14,7 @@ # Build, tag, and push the Docker image to the GitLab Docker registry build ryu-openflow: - variables: + variables: TEST_NAME: 'ryu-openflow' IMAGE_TAG: 'mr$CI_MERGE_REQUEST_IID' stage: build diff --git a/src/tests/ryu-openflow/docker-compose.yml b/src/tests/ryu-openflow/docker-compose.yml index b4892184a..611129592 100644 --- a/src/tests/ryu-openflow/docker-compose.yml +++ b/src/tests/ryu-openflow/docker-compose.yml @@ -18,4 +18,3 @@ services: build: context: . dockerfile: Ryu.Dockerfile - -- GitLab From cdd2bb5df4ec86de8b9372969b93a9a47cd544fc Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Wed, 17 Sep 2025 07:37:06 +0000 Subject: [PATCH 082/638] check if its working --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index 18e35f454..a5da61d8d 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -51,7 +51,7 @@ build ryu-openflow: # --volume "$PWD/src/tests/${TEST_NAME}/node-agents-config/platform_t1.xml:/confd/examples.confd/OC23/platform.xml" # asgamb1/oc23bgp.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh - +# # Deploy TeraFlowSDN and Execute end-2-end test end2end_test ryu-openflow: timeout: 90m -- GitLab From 37d8abe35ca98a98c849a92c44b643d776964d38 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Wed, 17 Sep 2025 10:24:21 +0000 Subject: [PATCH 083/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 763d7da17..880386368 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -37,6 +37,7 @@ def test_scenario_onboarding( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) + time.sleep(4) descriptor_loader.validate() # Verify the scenario has no services/slices -- GitLab From eca86d1f73bd20d8b75452dcde0315bbc5258ad3 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Wed, 17 Sep 2025 10:36:16 +0000 Subject: [PATCH 084/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 880386368..22124e66d 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -37,7 +37,22 @@ def test_scenario_onboarding( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) - time.sleep(4) + # replace: time.sleep(4) + def wait_for_devices(ctx, expected, timeout=20.0, interval=0.5): + deadline = time.time() + timeout + last = -1 + while time.time() < deadline: + n = len(ctx.ListDevices(Empty()).devices) + if n == expected: + return + last = n + time.sleep(interval) + raise AssertionError(f"Timeout waiting for devices: expected {expected}, got {last}") + + # Wait until Context service actually shows all devices, then run validate() + wait_for_devices(context_client, descriptor_loader.num_devices) + descriptor_loader.validate() + descriptor_loader.validate() # Verify the scenario has no services/slices -- GitLab From 9eb127fd67418b2582fd4a588db79262210579eb Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Thu, 18 Sep 2025 10:28:12 +0000 Subject: [PATCH 085/638] Update file .gitlab-ci.yml --- src/tests/ryu-openflow/.gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/.gitlab-ci.yml b/src/tests/ryu-openflow/.gitlab-ci.yml index a5da61d8d..18e35f454 100644 --- a/src/tests/ryu-openflow/.gitlab-ci.yml +++ b/src/tests/ryu-openflow/.gitlab-ci.yml @@ -51,7 +51,7 @@ build ryu-openflow: # --volume "$PWD/src/tests/${TEST_NAME}/node-agents-config/platform_t1.xml:/confd/examples.confd/OC23/platform.xml" # asgamb1/oc23bgp.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh -# + # Deploy TeraFlowSDN and Execute end-2-end test end2end_test ryu-openflow: timeout: 90m -- GitLab From 6e84608dab08ee581701029347d517a54a7b373b Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 19 Sep 2025 10:25:55 +0000 Subject: [PATCH 086/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 22124e66d..763d7da17 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -37,22 +37,6 @@ def test_scenario_onboarding( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) - # replace: time.sleep(4) - def wait_for_devices(ctx, expected, timeout=20.0, interval=0.5): - deadline = time.time() + timeout - last = -1 - while time.time() < deadline: - n = len(ctx.ListDevices(Empty()).devices) - if n == expected: - return - last = n - time.sleep(interval) - raise AssertionError(f"Timeout waiting for devices: expected {expected}, got {last}") - - # Wait until Context service actually shows all devices, then run validate() - wait_for_devices(context_client, descriptor_loader.num_devices) - descriptor_loader.validate() - descriptor_loader.validate() # Verify the scenario has no services/slices -- GitLab From d3cfbade4fcf3b9c4cca0b5d8cb98d77616c260d Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 19 Sep 2025 12:45:27 +0000 Subject: [PATCH 087/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 763d7da17..5d484d7a2 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -37,6 +37,9 @@ def test_scenario_onboarding( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) + logging.info("Devices currently in context: %d", len(response.devices)) + for d in response.devices: + logging.info("Device ID: %s, Type: %s", d.device_id.device_uuid.uuid, d.device_type) descriptor_loader.validate() # Verify the scenario has no services/slices -- GitLab From bb2f7b13e44ef9f275579fadc78f43ec4ee95974 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Fri, 19 Sep 2025 12:57:51 +0000 Subject: [PATCH 088/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 5d484d7a2..3265f768a 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -37,9 +37,11 @@ def test_scenario_onboarding( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) + response = context_client.ListDevices(Empty()) + logging.info("DescriptorLoader expects %d devices", descriptor_loader.num_devices) logging.info("Devices currently in context: %d", len(response.devices)) for d in response.devices: - logging.info("Device ID: %s, Type: %s", d.device_id.device_uuid.uuid, d.device_type) + logging.info("Device ID: %s", d.device_id.device_uuid.uuid) descriptor_loader.validate() # Verify the scenario has no services/slices -- GitLab From 5bb776328dadfb6acce82fa660ac257edcc695ae Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 22 Sep 2025 08:38:37 +0000 Subject: [PATCH 089/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 3265f768a..13ae1ffdb 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -32,16 +32,14 @@ def test_scenario_onboarding( device_client : DeviceClient, # pylint: disable=redefined-outer-name ) -> None: validate_empty_scenario(context_client) + resp = context_client.ListDevices(Empty()) + LOGGER.info('Num Devices enabled:{:d}'.format(resp.devices)) descriptor_loader = DescriptorLoader( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) response = context_client.ListDevices(Empty()) - logging.info("DescriptorLoader expects %d devices", descriptor_loader.num_devices) - logging.info("Devices currently in context: %d", len(response.devices)) - for d in response.devices: - logging.info("Device ID: %s", d.device_id.device_uuid.uuid) descriptor_loader.validate() # Verify the scenario has no services/slices -- GitLab From 466d80e3db10ed0081632b3023bdadaf9d6c0121 Mon Sep 17 00:00:00 2001 From: Mohamad Rahhal Date: Mon, 22 Sep 2025 08:46:36 +0000 Subject: [PATCH 090/638] Update file test_onboarding.py --- src/tests/ryu-openflow/tests/test_onboarding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ryu-openflow/tests/test_onboarding.py b/src/tests/ryu-openflow/tests/test_onboarding.py index 13ae1ffdb..9dfec4b47 100644 --- a/src/tests/ryu-openflow/tests/test_onboarding.py +++ b/src/tests/ryu-openflow/tests/test_onboarding.py @@ -33,7 +33,7 @@ def test_scenario_onboarding( ) -> None: validate_empty_scenario(context_client) resp = context_client.ListDevices(Empty()) - LOGGER.info('Num Devices enabled:{:d}'.format(resp.devices)) + LOGGER.info('Num Devices enabled: %d', len(resp.devices)) descriptor_loader = DescriptorLoader( descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client) -- GitLab From 830ce1265d2787cbe97fab7e17714671fa7fd053 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Thu, 23 Oct 2025 23:05:28 +0200 Subject: [PATCH 091/638] polimi flexgrid working+ preliminary band protection --- deploy/all.sh | 2 +- src/opticalcontroller/OpticalController.py | 31 +- src/opticalcontroller/RSA.py | 185 ++++++++++-- .../service/ServiceServiceServicerImpl.py | 283 +++++++++++++----- .../service/task_scheduler/TaskScheduler.py | 193 ++++++++++-- src/service/service/tools/OpticalTools.py | 155 +++++++++- src/service/tests/test_recon.py | 101 +++++++ 7 files changed, 815 insertions(+), 135 deletions(-) create mode 100644 src/service/tests/test_recon.py diff --git a/deploy/all.sh b/deploy/all.sh index 764ec7dbc..25f8de7b1 100755 --- a/deploy/all.sh +++ b/deploy/all.sh @@ -213,7 +213,7 @@ export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} ./deploy/qdb.sh # Deploy Apache Kafka -#./deploy/kafka.sh +./deploy/kafka.sh #Deploy Monitoring (Prometheus, Mimir, Grafana) #./deploy/monitoring.sh diff --git a/src/opticalcontroller/OpticalController.py b/src/opticalcontroller/OpticalController.py index e859e3ba1..075c8a42b 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -80,10 +80,10 @@ class AddFlexLightpath(Resource): @staticmethod def put(src, dst, bitrate, bidir=1, band=None): - print("INFO: New FlexLightpath request from {} to {} with rate {} ".format(src, dst, bitrate)) + print("INFO: New FlexLightpath request from {} to {} with rate {} and band {}".format(src, dst, bitrate, band)) t0 = time.time()*1000.0 - if debug: - rsa.g.printGraph() + #if debug: + # rsa.g.printGraph() if rsa is not None: flow_id, optical_band_id = rsa.rsa_fs_computation(src, dst, bitrate, bidir, band) @@ -106,6 +106,7 @@ class AddFlexLightpath(Resource): return rsa.optical_bands[optical_band_id], 200 else: return "Error", 404 + # @optical.route('/DelFlexLightpath////') @optical.route('/DelFlexLightpath////') @optical.route('/DelFlexLightpath/////') @@ -280,7 +281,7 @@ class DelLightpath(Resource): match1 = flow["src"] == src and flow["dst"] == dst and flow["bitrate"] == bitrate match2 = flow["src"] == dst and flow["dst"] == src and flow["bitrate"] == bitrate if match1 or match2: - rsa.del_flow(flow) + rsa.del_flow(flow, flow_id) rsa.db_flows[flow_id]["is_active"] = False if debug: print(rsa.links_dict) @@ -331,6 +332,28 @@ class GetBand(Resource): return rsa.optical_bands[ob_idx], 200 return {}, 404 +@optical.route('/ReconfigFlexLightpath/') +@optical.response(200, 'Success') +@optical.response(404, 'Error, not found') +class ReconfigFlexLightpath(Resource): + @staticmethod + def put(flow_id_val): + print("INFO: Reconfiguring optical {}".format(flow_id_val)) + t0 = time.time()*1000.0 + if rsa is not None: + flow_idx, optical_band_id = rsa.rsa_fs_recomputation(flow_id_val) + if flow_idx is not None: + if rsa.db_flows[flow_idx]["op-mode"] == 0: + return 'No path found', 404 + t1 = time.time() * 1000.0 + elapsed = t1 - t0 + print("INFO: time elapsed = {} ms".format(elapsed)) + print(flow_idx, optical_band_id) + return rsa.db_flows[flow_idx], 200 + else: + return "Error", 404 + else: + return "Error", 404 @optical.route('/GetLinks') @optical.response(200, 'Success') diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index 95a49113e..861afeb01 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -17,6 +17,8 @@ from opticalcontroller.dijkstra import * from opticalcontroller.tools import * from opticalcontroller.variables import * debug = 1 + + ''' LOGGER = logging.getLogger(__name__) @@ -256,14 +258,14 @@ class RSA(): if "l_slots" in self.optical_bands[optical_band_id].keys(): if len(self.optical_bands[optical_band_id]["l_slots"]) > 0: a_l = l_sts - b_l = consecutives(self.optical_bands[optical_band_id]["l_slots"], val_c) + b_l = consecutives(self.optical_bands[optical_band_id]["l_slots"], val_l) l_sts = common_slots(a_l, b_l) else: l_sts = [] if "s_slots" in self.optical_bands[optical_band_id].keys(): if len(self.optical_bands[optical_band_id]["s_slots"]) > 0: a_s = s_sts - b_s = consecutives(str_list_to_int(self.optical_bands[optical_band_id]["s_slots"].keys()), val_c) + b_s = consecutives(self.optical_bands[optical_band_id]["s_slots"], val_s) s_sts = common_slots(a_s, b_s) else: s_sts = [] @@ -480,8 +482,7 @@ class RSA(): print(f"delete band del_band") self.del_band(flow,flow_id,o_b_id=o_b_id) else : - self.del_flow(flow,flow_id=flow_id,o_b_id=o_b_id) - + self.del_flow(flow,flow_id=flow_id,o_b_id=o_b_id) def get_fibers_forward(self, links, slots, band): @@ -652,16 +653,17 @@ class RSA(): print(self.links_dict) band, slots = slot_selection(c, l, s, n_slots, self.c_slot_number, self.l_slot_number, self.s_slot_number) if band is None: - print("No slots available in the three bands") + print("ERROR: No slots available in the three bands") return None, None, None, None, None if debug: - print(band, slots) + print(f"INFO: XXXX {band}, {slots}") self.get_fibers_forward(links, slots, band) if bidir: self.get_fibers_backward(links, slots, band) #fibers_f = self.get_fibers_forward(links, slots, band) self.update_optical_band(o_band_id, slots, band) + print("INFO: 1") #fibers_b = [] #if bidir: # fibers_b = self.get_fibers_backward(links, fibers_f, slots, band) @@ -690,7 +692,8 @@ class RSA(): #r_inport = self.links_dict[add]['fibers'][f]["local_peer_port"] r_inport = lx["local_peer_port"] t_flows[src]["b"] = {"in": r_inport, "out": port_0} - + print("INFO: 2") + #R1 rules t_flows[dst] = {} t_flows[dst]["f"] = {} @@ -737,12 +740,13 @@ class RSA(): #r_inport = self.links_dict[drop]['fibers'][f]["remote_peer_port"] r_inport = ly["remote_peer_port"] t_flows[dst]["b"] = {"in": port_0, "out": r_inport} - - if debug: - print(self.links_dict) - - if debug: - print(t_flows) + print("INFO: 3") + + #if debug: + # print(self.links_dict) + print("INFO: 4") + #if debug: + # print(t_flows) print("INFO: Flow matrix computed for Flex Lightpath") return t_flows, band, slots, {}, {} @@ -832,8 +836,8 @@ class RSA(): self.optical_bands[ob_id]["s_slots"] = [] self.optical_bands[ob_id]["served_lightpaths"] = [] self.optical_bands[ob_id]["reverse_optical_band_id"] = 0 - self.db_flows[self.flow_id]["parent_opt_band"] = 0 - self.db_flows[self.flow_id]["new_optical_band"] = 0 + #self.db_flows[flow_id]["parent_opt_band"] = 0 + #self.db_flows[flow_id]["new_optical_band"] = 0 def create_optical_band(self, links, path, bidir, num_slots): print("INFO: Creating optical-band of {} slots".format(num_slots)) @@ -899,7 +903,7 @@ class RSA(): print(f0, band) print("INFO: RSA completed for optical band") if flow_list is None: - self.null_values(self.flow_id) + self.null_values_ob(self.opt_band_id) return self.flow_id, [] #slots_i = [] #for i in slots: @@ -988,16 +992,17 @@ class RSA(): return result def rsa_fs_computation(self, src, dst, rate, bidir, band): - num_slots_ob = "full_band" if band is not None: num_slots_ob = map_band_to_slot(band) print(band, num_slots_ob) + else: + num_slots_ob = "full_band" if self.nodes_dict[src]["type"] == "OC-ROADM" and self.nodes_dict[dst]["type"] == "OC-ROADM": print("INFO: ROADM to ROADM connection") links, path = self.compute_path(src, dst) if len(path) < 1: self.null_values_ob(self.opt_band_id) - return self.flow_id, [] + return self.opt_band_id, [] optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob) return None, optical_band_id print("INFO: TP to TP connection") @@ -1008,6 +1013,9 @@ class RSA(): self.flow_id += 2 else: self.flow_id += 1 + if band is not None: + num_slots_ob = map_band_to_slot(band) + print(band, num_slots_ob) self.db_flows[self.flow_id] = {} self.db_flows[self.flow_id]["flow_id"] = self.flow_id self.db_flows[self.flow_id]["src"] = src @@ -1086,7 +1094,7 @@ class RSA(): ''' if bidir: rev_ob_id = self.optical_bands[ob_id]["reverse_optical_band_id"] - self.optical_bands[rev_ob_id]["served_lightpaths"].append(self.flow_id) + self.optical_bands[rev_ob_id]["served_lightpaths"].append(flow_id) ''' return self.flow_id, ob_id else: @@ -1147,13 +1155,13 @@ class RSA(): self.db_flows[self.flow_id]["freq"] = f0 self.db_flows[self.flow_id]["is_active"] = True self.db_flows[self.flow_id]["parent_opt_band"] = ob_id - #self.db_flows[self.flow_id]["new_optical_band"] = 1 + #self.db_flows[flow_id]["new_optical_band"] = 1 self.db_flows[self.flow_id]["new_optical_band"] = 2 self.optical_bands[ob_id]["served_lightpaths"].append(self.flow_id) ''' if bidir: rev_ob_id = self.optical_bands[ob_id]["reverse_optical_band_id"] - self.optical_bands[rev_ob_id]["served_lightpaths"].append(self.flow_id) + self.optical_bands[rev_ob_id]["served_lightpaths"].append(flow_id) ''' return self.flow_id, ob_id else: @@ -1184,7 +1192,7 @@ class RSA(): print("INFO: RSA completed for FLex Lightpath with new OB") if flow_list is None: self.null_values(self.flow_id) - return self.flow_id, optical_band_id + return flow_id, optical_band_id slots_i = [] for i in slots: slots_i.append(int(i)) @@ -1207,11 +1215,142 @@ class RSA(): ''' if bidir: rev_ob_id = self.optical_bands[optical_band_id]["reverse_optical_band_id"] - self.optical_bands[rev_ob_id]["served_lightpaths"].append(self.flow_id) + self.optical_bands[rev_ob_id]["served_lightpaths"].append(flow_id) ''' return self.flow_id, optical_band_id + def move_flow(self, flow_id, slots, band, links, bidir, o_b_id = None): + for l in links: + link = self.get_link_by_name(l) + fib = link["optical_details"] + #self.restore_link(fib, slots, band) + self.restore_link_2(fib, slots, band, link=link) + if o_b_id is not None: + if debug: + print("restoring OB") + print(f"invoking restore_optical_band o_b_id: {o_b_id} , slots {slots} , band {band} ") + self.restore_optical_band(o_b_id, slots, band) + if flow_id in self.optical_bands[o_b_id]["served_lightpaths"]: + if flow_id in self.optical_bands[o_b_id]["served_lightpaths"]: + self.optical_bands[o_b_id]["served_lightpaths"].remove(flow_id) + + #self.restore_optical_band_2(o_b_id, slots, band,links) + if bidir: + for l in links: + r_l = reverse_link(l) + if debug: + print(r_l) + rlink = self.get_link_by_name(r_l) + fib = rlink["optical_details"] + #fib = self.get_link_by_name(r_l)["optical_details"] + if list_in_list(slots, str_list_to_int(fib[band].keys())): + #self.restore_link(fib, slots, band, link=l) + self.restore_link_2(fib, slots, band, link=rlink) + if debug: + print(fib[band]) + + return True + + def rsa_fs_recomputation(self, flow_idy): + flow_idx = int(flow_idy) + print(f"INFO: Reconifguring connection {flow_idx}") + if flow_idx not in self.db_flows.keys(): + print(f"ERROR: key not present {flow_idx}") + else: + print(self.db_flows[flow_idx]) + #self.db_flows[flow_idx] = {} + src = self.db_flows[flow_idx]["src"] + dst = self.db_flows[flow_idx]["dst"] + rate = self.db_flows[flow_idx]["bitrate"] + bidir = self.db_flows[flow_idx]["bidir"] + flow_list = self.db_flows[flow_idx]["flows"] + band_type = self.db_flows[flow_idx]["band_type"] + slots_init = self.db_flows[flow_idx]["slots"] + fiber_f = self.db_flows[flow_idx]["fiber_forward"] + fiber_b = self.db_flows[flow_idx]["fiber_backward"] + op = self.db_flows[flow_idx]["op-mode"] + num_slots = self.db_flows[flow_idx]["n_slots"] + links = self.db_flows[flow_idx]["links"] + path = self.db_flows[flow_idx]["path"] + band = self.db_flows[flow_idx]["band"] + f0 = self.db_flows[flow_idx]["freq"] + ob_idx = self.db_flows[flow_idx]["parent_opt_band"] + + r1 = "" + r2 = "" + if len(links) == 2: + [t1, r1] = links[0].split("-") + [r2, t2] = links[1].split("-") + else: + return 0, 0 + existing_ob = self.get_optical_bands(r1, r2) + if len(existing_ob) > 0: + print("INFO: Trying to move connection to an existing OB") + #first checking in existing OB + for ob_id in existing_ob: + if "is_active" in self.optical_bands[ob_id].keys(): + is_active = self.optical_bands[ob_id]["is_active"] + if not is_active: + continue + op, num_slots = map_rate_to_slot(rate) + if debug: + print(links) + + c_slots, l_slots, s_slots = self.get_slots(links, num_slots, ob_id) + if debug: + print(c_slots) + print(l_slots) + print(s_slots) + if band_type == "c_slots": + c_slots = [] + elif band_type == "l_slots": + l_slots = [] + elif band_type == "s_slots": + s_slots = [] + if len(c_slots) >= num_slots or len(l_slots) >= num_slots or len(s_slots) >= num_slots: + flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports_fs(links, num_slots, + c_slots, + l_slots, s_slots, bidir, + ob_id) + + f0, band = frequency_converter(band_range, slots) + if debug: + print(f0, band) + print("INFO: RSA completed for Flex Lightpath with OB already in place") + if flow_list is None: + continue + slots_i = [] + for i in slots: + slots_i.append(int(i)) + self.db_flows[flow_idx]["flows"] = flow_list + self.db_flows[flow_idx]["band_type"] = band_range + self.db_flows[flow_idx]["slots"] = slots_i + self.db_flows[flow_idx]["fiber_forward"] = fiber_f + self.db_flows[flow_idx]["fiber_backward"] = fiber_b + self.db_flows[flow_idx]["op-mode"] = op + self.db_flows[flow_idx]["n_slots"] = num_slots + #self.db_flows[flow_idx]["links"] = temp_links2 + #self.db_flows[flow_idx]["path"] = temp_path + self.db_flows[flow_idx]["band"] = band + self.db_flows[flow_idx]["freq"] = f0 + self.db_flows[flow_idx]["is_active"] = True + self.db_flows[flow_idx]["parent_opt_band"] = ob_id + self.db_flows[flow_idx]["new_optical_band"] = 0 + self.optical_bands[ob_id]["served_lightpaths"].append(flow_idx) + ''' + if bidir: + rev_ob_id = self.optical_bands[ob_id]["reverse_optical_band_id"] + self.optical_bands[rev_ob_id]["served_lightpaths"].append(flow_id) + ''' + self.move_flow(flow_idx, slots_init, band_type, links, bidir, ob_idx) + return flow_idx, ob_id + else: + continue + print("not enough slots") + return None, 0 + + def extend_optical_band(self, ob_id, band=None): ob = self.optical_bands[ob_id] links = ob["links"] diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index 48cb93c6b..eeb2cd4a6 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -44,8 +44,8 @@ from .task_scheduler.TaskScheduler import TasksScheduler from .tools.GeodesicDistance import gps_distance from .tools.OpticalTools import ( add_flex_lightpath, add_lightpath, delete_lightpath, adapt_reply, get_device_name_from_uuid, - get_optical_band, refresh_opticalcontroller, DelFlexLightpath , extend_optical_band - + get_optical_band, refresh_opticalcontroller, DelFlexLightpath , extend_optical_band, + reconfig_flex_lightpath, adapt_reply_ob ) @@ -276,7 +276,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): ports = [] for endpoint_id in service.service_endpoint_ids: endpoint_device_uuid = endpoint_id.device_id.device_uuid.uuid - if "." in endpoint_device_uuid: + if "." or "MGON" in endpoint_device_uuid: endpoint_device_name = endpoint_device_uuid else: endpoint_device_name = device_names[endpoint_device_uuid] @@ -310,10 +310,24 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): else: reply_txt = add_flex_lightpath(src, dst, bitrate, bidir, ob_band) logging.info(f"TEEEEEEEEEEEEEEST {oc_type}") + logging.info(f"POLIMI {reply_txt}") + if reply_txt == None: + return service_with_uuids.service_id reply_json = json.loads(reply_txt) LOGGER.info('[optical] reply_json[{:s}]={:s}'.format(str(type(reply_json)), str(reply_json))) optical_band_txt = "" + if "optical_band_id" in reply_json.keys(): + optical_band_txt = reply_txt + + optical_reply = adapt_reply_ob( + devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt + ) + + tasks_scheduler.compose_from_opticalcontroller_reply( + optical_reply, is_delete=False) + tasks_scheduler.execute_all() + return service_with_uuids.service_id if "new_optical_band" in reply_json.keys(): if reply_json["new_optical_band"] == 1: if reply_json["parent_opt_band"]: @@ -452,6 +466,27 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): tasks_scheduler.compose_from_optical_service(service, params=params, is_delete=True) tasks_scheduler.execute_all() return Empty() + elif oc_type ==2 : + if len(service.service_config.config_rules) > 0: + c_rules_dict = json.loads( + service.service_config.config_rules[0].custom.resource_value) + ob_id=None + flow_id=None + + if ("flow_id" in c_rules_dict): + flow_id = c_rules_dict["flow_id"] + #if ("ob_id" in c_rules_dict): + # ob_id = c_rules_dict["ob_id"] + params['bitrate']=bitrate + params['dst']=dst + params['src']=src + params['flow_id']=flow_id + params['bidir'] = bidir + tasks_scheduler = TasksScheduler(self.service_handler_factory) + tasks_scheduler.compose_from_optical_service(service, params=params, is_delete=True) + tasks_scheduler.execute_all() + return Empty() + # Normal service # Feed TaskScheduler with this service and the sub-services and sub-connections related to this service. @@ -514,9 +549,11 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): updated_service_with_uuids = get_service_by_id( context_client, updated_service_id_with_uuids, rw_copy=True, include_config_rules=True, include_constraints=True, include_endpoint_ids=True) + LOGGER.info('WYY:{}'.format(updated_service_with_uuids)) # Get active connection connections = context_client.ListConnections(updated_service_id_with_uuids) + LOGGER.info('WWWW:{}'.format(connections)) if len(connections.connections) == 0: MSG = 'Service({:s}) has no connections' str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) @@ -538,83 +575,173 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): str_connection = grpc_message_to_json_string(old_connection) str_extra_details = MSG.format(str_service_id, str_connection_id, str_connection) raise NotImplementedException('service-connection-with-subservices', extra_details=str_extra_details) + + if updated_service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: + LOGGER.info('WWWW:{}'.format("is optical")) + context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) + topology_id_x = json_topology_id( + DEFAULT_TOPOLOGY_NAME, context_id_x) + topology_details = context_client.GetTopologyDetails( + TopologyId(**topology_id_x)) + + str_old_connection = connection_to_string(old_connection) + LOGGER.info('WWW old_connection={}'.format(grpc_message_to_json_string(old_connection))) + LOGGER.info('WWW0={}'.format(updated_service_with_uuids.service_config.config_rules)) + if len(updated_service_with_uuids.service_config.config_rules)> 0: + #if len(updated_service.service_config.config_rules) > 0: + c_rules_dict = json.loads( + updated_service_with_uuids.service_config.config_rules[0].custom.resource_value) + + #c_rules_dict = json.loads( + # updated_service.service_config.config_rules[0].custom.resource_value) + LOGGER.info('WWW1:{}'.format(c_rules_dict)) + flow_id=None + #if "ob_id" in c_rules_dict: + # ob_id = c_rules_dict["ob_id"] + if ("flow_id" in c_rules_dict): + flow_id = c_rules_dict["flow_id"] + reply_txt = "" + # to get the reply form the optical module + #multi-granular + reply_txt = reconfig_flex_lightpath(flow_id) + reply_json = json.loads(reply_txt) + LOGGER.info('[optical] reply_json[{:s}]={:s}'.format(str(type(reply_json)), str(reply_json))) + devices = topology_details.devices + context_uuid_x = topology_details.topology_id.context_id.context_uuid.uuid + topology_uuid_x = topology_details.topology_id.topology_uuid.uuid + + device_names : Dict[str, str] = dict() + for device in devices: + device_uuid = device.device_id.device_uuid.uuid + device_names[device_uuid] = device.name + + if reply_txt is not "": + optical_reply = adapt_reply(devices, updated_service, reply_json, context_uuid_x, topology_uuid_x, "") + new_connection = optical_reply.connections[0] + #for candidate_new_connection in pathcomp_reply.connections: + str_candidate_new_connection = connection_to_string(new_connection) + # Change UUID of new connection to prevent collisions + tmp_connection = Connection() + tmp_connection.CopyFrom(new_connection) + tmp_connection.connection_id.connection_uuid.uuid = str(uuid.uuid4()) + new_connection = tmp_connection + service_new = optical_reply.services[0] + LOGGER.info('QQQQ:{}'.format(service_new)) + + ''' + if len(service.service_config.config_rules) > 0: + c_rules_dict = json.loads( + service.service_config.config_rules[0].custom.resource_value) + ob_id=None + flow_id=None + if "ob_id" in c_rules_dict: + ob_id = c_rules_dict["ob_id"] + if ("flow_id" in c_rules_dict): + flow_id = c_rules_dict["flow_id"] + #if ("ob_id" in c_rules_dict): + # ob_id = c_rules_dict["ob_id"] + params['bitrate']=bitrate + params['dst']=dst + params['src']=src + params['ob_id']=ob_id + params['flow_id']=flow_id + params['bidir'] = bidir + + + tasks_scheduler = TasksScheduler(self.service_handler_factory) + tasks_scheduler.compose_from_optical_service(service, params=params, is_delete=True) + tasks_scheduler.execute_all() + + ''' + + # Feed TaskScheduler with the service to update, the old connection to + # deconfigure and the new connection to configure. It will produce a + # schedule of tasks (an ordered list of tasks to be executed) to + # implement the requested changes. + tasks_scheduler = TasksScheduler(self.service_handler_factory) + #tasks_scheduler.compose_optical_service_update( + # updated_service, old_connection, service_new, new_connection) + tasks_scheduler.compose_optical_service_update( + service_new, old_connection, new_connection) + tasks_scheduler.execute_all() - # Find alternative connections - # pylint: disable=no-member - pathcomp_request = PathCompRequest() - pathcomp_request.services.append(updated_service_with_uuids) - #pathcomp_request.k_disjoint_path.num_disjoint = 100 - pathcomp_request.k_shortest_path.k_inspection = 100 - pathcomp_request.k_shortest_path.k_return = 3 - - LOGGER.debug('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) - pathcomp = PathCompClient() - pathcomp_reply = pathcomp.Compute(pathcomp_request) - pathcomp.close() - LOGGER.debug('pathcomp_reply={:s}'.format(grpc_message_to_json_string(pathcomp_reply))) - - if len(pathcomp_reply.services) == 0: - MSG = 'KDisjointPath reported no services for Service({:s}): {:s}' - str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) - str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) - str_extra_details = MSG.format(str_service_id, str_pathcomp_reply) - raise NotImplementedException('kdisjointpath-no-services', extra_details=str_extra_details) + else: + # Find alternative connections + # pylint: disable=no-member + pathcomp_request = PathCompRequest() + pathcomp_request.services.append(updated_service_with_uuids) + #pathcomp_request.k_disjoint_path.num_disjoint = 100 + pathcomp_request.k_shortest_path.k_inspection = 100 + pathcomp_request.k_shortest_path.k_return = 3 + + LOGGER.debug('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request))) + pathcomp = PathCompClient() + pathcomp_reply = pathcomp.Compute(pathcomp_request) + pathcomp.close() + LOGGER.debug('pathcomp_reply={:s}'.format(grpc_message_to_json_string(pathcomp_reply))) + + if len(pathcomp_reply.services) == 0: + MSG = 'KDisjointPath reported no services for Service({:s}): {:s}' + str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) + str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) + str_extra_details = MSG.format(str_service_id, str_pathcomp_reply) + raise NotImplementedException('kdisjointpath-no-services', extra_details=str_extra_details) + + if len(pathcomp_reply.services) > 1: + MSG = 'KDisjointPath reported subservices for Service({:s}): {:s}' + str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) + str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) + str_extra_details = MSG.format(str_service_id, str_pathcomp_reply) + raise NotImplementedException('kdisjointpath-subservices', extra_details=str_extra_details) + + if len(pathcomp_reply.connections) == 0: + MSG = 'KDisjointPath reported no connections for Service({:s}): {:s}' + str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) + str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) + str_extra_details = MSG.format(str_service_id, str_pathcomp_reply) + raise NotImplementedException('kdisjointpath-no-connections', extra_details=str_extra_details) + + # compute a string representing the old connection + str_old_connection = connection_to_string(old_connection) + + LOGGER.debug('old_connection={:s}'.format(grpc_message_to_json_string(old_connection))) + + candidate_new_connections = list() + for candidate_new_connection in pathcomp_reply.connections: + str_candidate_new_connection = connection_to_string(candidate_new_connection) + if str_candidate_new_connection == str_old_connection: continue + candidate_new_connections.append(candidate_new_connection) + + if len(candidate_new_connections) == 0: + MSG = 'Unable to find a new suitable path: pathcomp_request={:s} pathcomp_reply={:s} old_connection={:s}' + str_pathcomp_request = grpc_message_to_json_string(pathcomp_request) + str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) + str_old_connection = grpc_message_to_json_string(old_connection) + extra_details = MSG.format(str_pathcomp_request, str_pathcomp_reply, str_old_connection) + raise OperationFailedException('no-new-path-found', extra_details=extra_details) + + str_candidate_new_connections = [ + grpc_message_to_json_string(candidate_new_connection) + for candidate_new_connection in candidate_new_connections + ] + LOGGER.debug('candidate_new_connections={:s}'.format(str(str_candidate_new_connections))) - if len(pathcomp_reply.services) > 1: - MSG = 'KDisjointPath reported subservices for Service({:s}): {:s}' - str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) - str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) - str_extra_details = MSG.format(str_service_id, str_pathcomp_reply) - raise NotImplementedException('kdisjointpath-subservices', extra_details=str_extra_details) + new_connection = random.choice(candidate_new_connections) + LOGGER.debug('new_connection={:s}'.format(grpc_message_to_json_string(new_connection))) - if len(pathcomp_reply.connections) == 0: - MSG = 'KDisjointPath reported no connections for Service({:s}): {:s}' - str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) - str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) - str_extra_details = MSG.format(str_service_id, str_pathcomp_reply) - raise NotImplementedException('kdisjointpath-no-connections', extra_details=str_extra_details) - - # compute a string representing the old connection - str_old_connection = connection_to_string(old_connection) - - LOGGER.debug('old_connection={:s}'.format(grpc_message_to_json_string(old_connection))) - - candidate_new_connections = list() - for candidate_new_connection in pathcomp_reply.connections: - str_candidate_new_connection = connection_to_string(candidate_new_connection) - if str_candidate_new_connection == str_old_connection: continue - candidate_new_connections.append(candidate_new_connection) - - if len(candidate_new_connections) == 0: - MSG = 'Unable to find a new suitable path: pathcomp_request={:s} pathcomp_reply={:s} old_connection={:s}' - str_pathcomp_request = grpc_message_to_json_string(pathcomp_request) - str_pathcomp_reply = grpc_message_to_json_string(pathcomp_reply) - str_old_connection = grpc_message_to_json_string(old_connection) - extra_details = MSG.format(str_pathcomp_request, str_pathcomp_reply, str_old_connection) - raise OperationFailedException('no-new-path-found', extra_details=extra_details) - - str_candidate_new_connections = [ - grpc_message_to_json_string(candidate_new_connection) - for candidate_new_connection in candidate_new_connections - ] - LOGGER.debug('candidate_new_connections={:s}'.format(str(str_candidate_new_connections))) - - new_connection = random.choice(candidate_new_connections) - LOGGER.debug('new_connection={:s}'.format(grpc_message_to_json_string(new_connection))) - - # Change UUID of new connection to prevent collisions - tmp_connection = Connection() - tmp_connection.CopyFrom(new_connection) - tmp_connection.connection_id.connection_uuid.uuid = str(uuid.uuid4()) - new_connection = tmp_connection - - # Feed TaskScheduler with the service to update, the old connection to - # deconfigure and the new connection to configure. It will produce a - # schedule of tasks (an ordered list of tasks to be executed) to - # implement the requested changes. - tasks_scheduler = TasksScheduler(self.service_handler_factory) - tasks_scheduler.compose_service_connection_update( - updated_service_with_uuids, old_connection, new_connection) - tasks_scheduler.execute_all() + # Change UUID of new connection to prevent collisions + tmp_connection = Connection() + tmp_connection.CopyFrom(new_connection) + tmp_connection.connection_id.connection_uuid.uuid = str(uuid.uuid4()) + new_connection = tmp_connection + + # Feed TaskScheduler with the service to update, the old connection to + # deconfigure and the new connection to configure. It will produce a + # schedule of tasks (an ordered list of tasks to be executed) to + # implement the requested changes. + tasks_scheduler = TasksScheduler(self.service_handler_factory) + tasks_scheduler.compose_service_connection_update( + updated_service_with_uuids, old_connection, new_connection) + tasks_scheduler.execute_all() return Empty() diff --git a/src/service/service/task_scheduler/TaskScheduler.py b/src/service/service/task_scheduler/TaskScheduler.py index 7f47f65fb..919fcb63e 100644 --- a/src/service/service/task_scheduler/TaskScheduler.py +++ b/src/service/service/task_scheduler/TaskScheduler.py @@ -34,7 +34,8 @@ from .tasks.Task_ServiceDelete import Task_ServiceDelete from .tasks.Task_ServiceSetStatus import Task_ServiceSetStatus from .TaskExecutor import CacheableObjectType, TaskExecutor from .tasks.Task_OpticalServiceConfigDelete import Task_OpticalServiceConfigDelete -from service.service.tools.OpticalTools import delete_lightpath +from service.service.tools.OpticalTools import DelFlexLightpath, delete_lightpath +from common.Constants import OpticalServiceType if TYPE_CHECKING: from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory @@ -176,6 +177,30 @@ class TasksScheduler: return optical_connection_configure_key + def _optical_connection_configure_simple(self, connection_id : ConnectionId + , service_id : ServiceId , + has_media_channel : bool, has_optical_band = True) -> str: + optical_connection_configure_key = self._add_task_if_not_exists(Task_OpticalConnectionConfigure( + self._executor, connection_id)) + + ''' + # the connection configuration depends on its connection's service being in planning state + service_planned_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PLANNED)) + self._dag.add(optical_connection_configure_key, service_planned_key) + ''' + + + # the connection's service depends on the connection configuration to transition to active state + service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE)) + self._dag.add(service_active_key, optical_connection_configure_key) + + + return optical_connection_configure_key + + + def _optical_connection_deconfigure( self, connection_id : ConnectionId, service_id : ServiceId, has_media_channel : bool, has_optical_band = True @@ -196,6 +221,30 @@ class TasksScheduler: self._dag.add(service_delete_key, connection_deconfigure_key) return connection_deconfigure_key + + def _optical_connection_deconfigure_simple( + self, connection_id : ConnectionId, service_id : ServiceId, + has_media_channel : bool, has_optical_band = True + ) -> str: + connection_deconfigure_key = self._add_task_if_not_exists(Task_OpticalConnectionDeconfigure( + self._executor, connection_id, has_media_channel=has_media_channel + )) + ''' + # the connection deconfiguration depends on its connection's service being in removing state + service_pending_removal_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE + )) + self._dag.add(connection_deconfigure_key, service_pending_removal_key) + + + service_delete_key = self._add_task_if_not_exists(Task_OpticalServiceDelete( + self._executor, service_id, has_media_channel, has_optical_band + )) + self._dag.add(service_delete_key, connection_deconfigure_key) + ''' + + return connection_deconfigure_key + def _optical_service_config_remove( self, connection_id : ConnectionId, service_id : ServiceId @@ -396,20 +445,26 @@ class TasksScheduler: if str_item_key in explored_items: continue connections = self._context_client.ListConnections(item.service_id) has_media_channel,has_optical_band=self.check_service_for_media_channel(connections=connections,item=item.service_id) - + oc_type = 1 if len(service.service_config.config_rules) > 0: - - - reply,code = delete_lightpath( - params['src'] - ,params ['dst'] - , params['bitrate'] - , params['ob_id'] - ,delete_band=not has_media_channel - , flow_id= params['flow_id'] - ) + for constraint in service.service_constraints: + if "type" in constraint.custom.constraint_type: + oc_type = OpticalServiceType(str(constraint.custom.constraint_value)) + if oc_type == 2 : + #flow_id, src, dst, bitrate + reply,code = delete_lightpath(params['flow_id'], params['src'], params['dst'], params['bitrate']) - + else: + reply,code = DelFlexLightpath( + params['src'] + , params ['dst'] + , params['bitrate'] + , params['ob_id'] + , delete_band=not has_media_channel + , flow_id= params['flow_id'] + ) + + if code == 400 and reply_not_allowed in reply : MSG = 'Deleteion for the service is not Allowed , Served Lightpaths is not empty' raise Exception(MSG) @@ -443,22 +498,19 @@ class TasksScheduler: self._add_connection_to_executor_cache(connection) pending_items_to_explore.put(connection) - - - - + explored_items.add(str_item_key) elif isinstance(item, Connection): - - if code == 400 and reply_not_allowed in reply:break - str_item_key = grpc_message_to_json_string(item.connection_id) if str_item_key in explored_items: continue - connection_key = include_connection(item.connection_id, item.service_id,has_media_channel=has_media_channel,has_optical_band=has_optical_band) + connection_key = include_connection( item.connection_id + , item.service_id + , has_media_channel=has_media_channel + , has_optical_band=has_optical_band ) self._add_connection_to_executor_cache(connection) if include_service_config is not None : @@ -469,9 +521,7 @@ class TasksScheduler: if has_optical_band and is_media_channel: include_service_config(item.connection_id - , item.service_id - - ) + , item.service_id ) self._executor.get_service(item.service_id) @@ -479,7 +529,9 @@ class TasksScheduler: for sub_service_id in item.sub_service_ids: - _,service_key_done = include_service(sub_service_id,has_media_channel=has_media_channel,has_optical_band=has_optical_band) + _,service_key_done = include_service(sub_service_id + ,has_media_channel=has_media_channel + ,has_optical_band=has_optical_band) self._executor.get_service(sub_service_id) self._dag.add(service_key_done, connection_key) pending_items_to_explore.put(sub_service_id) @@ -497,6 +549,7 @@ class TasksScheduler: LOGGER.debug('[compose_from_service] elapsed_time: {:f} sec'.format(t1-t0)) + def compose_from_service(self, service : Service, is_delete : bool = False) -> None: t0 = time.time() include_service = self._service_remove if is_delete else self._service_create @@ -560,6 +613,96 @@ class TasksScheduler: t1 = time.time() LOGGER.debug('[compose_from_service] elapsed_time: {:f} sec'.format(t1-t0)) + + def compose_optical_service_update( + self, service : Service, old_connection : Connection, new_connection : Connection + ) -> None: + t0 = time.time() + + self._add_service_to_executor_cache(service) + self._add_connection_to_executor_cache(old_connection) + self._add_connection_to_executor_cache(new_connection) + + service_updating_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service.service_id, ServiceStatusEnum.SERVICESTATUS_UPDATING + )) + + old_connection_deconfigure_key = self._add_task_if_not_exists(Task_OpticalConnectionDeconfigure( + self._executor, old_connection.connection_id, old_connection.service_id + )) + + new_connection_configure_key = self._add_task_if_not_exists(Task_OpticalConnectionConfigure( + self._executor, new_connection.connection_id + )) + + service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service.service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE + )) + + # the old connection deconfiguration depends on service being in updating state + self._dag.add(old_connection_deconfigure_key, service_updating_key) + + # the new connection configuration depends on service being in updating state + self._dag.add(new_connection_configure_key, service_updating_key) + + # the new connection configuration depends on the old connection having been deconfigured + self._dag.add(new_connection_configure_key, old_connection_deconfigure_key) + + # re-activating the service depends on the service being in updating state before + self._dag.add(service_active_key, service_updating_key) + + # re-activating the service depends on the new connection having been configured + self._dag.add(service_active_key, new_connection_configure_key) + + t1 = time.time() + LOGGER.debug('[RRERRSF] elapsed_time: {:f} sec'.format(t1-t0)) + + + def compose_optical_service_update1( + self, service : Service, old_connection : Connection, new_connection : Connection + ) -> None: + LOGGER.debug('[ttttttttttt] elapsed_time inside update1') + t0 = time.time() + + self._add_service_to_executor_cache(service) + #self._add_connection_to_executor_cache(old_connection) + self._add_connection_to_executor_cache(new_connection) + + service_updating_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service.service_id, ServiceStatusEnum.SERVICESTATUS_UPDATING + )) + + #old_connection_deconfigure_key = self._add_task_if_not_exists(Task_OpticalConnectionDeconfigure( + # self._executor, old_connection.connection_id, old_connection.service_id + #)) + + new_connection_configure_key = self._add_task_if_not_exists(Task_OpticalConnectionConfigure( + self._executor, new_connection.connection_id + )) + + service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus( + self._executor, service.service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE + )) + + # the old connection deconfiguration depends on service being in updating state + #self._dag.add(old_connection_deconfigure_key, service_updating_key) + + # the new connection configuration depends on service being in updating state + self._dag.add(new_connection_configure_key, service_updating_key) + + # the new connection configuration depends on the old connection having been deconfigured + #self._dag.add(new_connection_configure_key, old_connection_deconfigure_key) + + # re-activating the service depends on the service being in updating state before + self._dag.add(service_active_key, service_updating_key) + + # re-activating the service depends on the new connection having been configured + self._dag.add(service_active_key, new_connection_configure_key) + + t1 = time.time() + LOGGER.debug('[RRERRSF] elapsed_time: {:f} sec'.format(t1-t0)) + + def compose_service_connection_update( self, service : Service, old_connection : Connection, new_connection : Connection ) -> None: diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py index 55bb6d242..1a44f4812 100644 --- a/src/service/service/tools/OpticalTools.py +++ b/src/service/service/tools/OpticalTools.py @@ -120,6 +120,23 @@ def refresh_opticalcontroller(topology_id : dict): log.debug(f"GetTopology Response {res}") +def reconfig_flex_lightpath(flow_id) -> str: + if not TESTING: + urlx = "" + headers = {"Content-Type": "application/json"} + base_url = get_optical_controller_base_url() + urlx = "{:s}/ReconfigFlexLightpath/{}".format(base_url, flow_id) + r = requests.put(urlx, headers=headers) + print(f"reconfig {r}") + reply = r.text + return reply + else: + if bidir is not None: + if bidir == 0: + return reply_uni_txt + return reply_bid_txt + + def add_flex_lightpath(src, dst, bitrate, bidir, ob_band) -> str: if not TESTING: urlx = "" @@ -177,7 +194,7 @@ def get_optical_band(idx) -> str: return optical_band_uni_txt -def delete_lightpath( src, dst, bitrate, ob_id, delete_band, flow_id=None) -> str: +def DelFlexLightpath( src, dst, bitrate, ob_id, delete_band, flow_id=None) -> str: reply = "200" delete_band = 1 if delete_band else 0 base_url = get_optical_controller_base_url() @@ -194,15 +211,16 @@ def delete_lightpath( src, dst, bitrate, ob_id, delete_band, flow_id=None) -> st code = r.status_code return (reply, code) -def DelFlexLightpath (flow_id, src, dst, bitrate, o_band_id): +def delete_lightpath(flow_id, src, dst, bitrate): reply = "200" base_url = get_optical_controller_base_url() if not TESTING: - urlx = "{:s}/DelFlexLightpath/{}/{}/{}/{}/{}".format(base_url, flow_id, src, dst, bitrate, o_band_id) + urlx = "{:s}/DelLightpath/{}/{}/{}/{}".format(base_url, flow_id, src, dst, bitrate) headers = {"Content-Type": "application/json"} r = requests.delete(urlx, headers=headers) reply = r.text - return reply + code = r.status_code + return (reply, code) def get_lightpaths() -> str: base_url = get_optical_controller_base_url() @@ -213,6 +231,135 @@ def get_lightpaths() -> str: reply = r.text return reply +def adapt_reply_ob(devices, service, reply_json, context_id, topology_id, optical_band_txt) -> PathCompReply: + opt_reply = PathCompReply() + topo = TopologyId( + context_id=ContextId(context_uuid=Uuid(uuid=context_id)), + topology_uuid=Uuid(uuid=topology_id) + ) + #add optical band connection first + rules_ob= [] + ob_id = 0 + connection_ob=None + + r = reply_json + if "optical_band_id" in r.keys(): + ob_id = r["optical_band_id"] + if "bidir" in r.keys(): + bidir_f = r["bidir"] + else: + bidir_f = False + if optical_band_txt != "": + ob_json = json.loads(optical_band_txt) + ob = ob_json + connection_ob = add_connection_to_reply(opt_reply) + uuuid_x = str(uuid.uuid4()) + connection_ob.connection_id.connection_uuid.uuid = uuuid_x + connection_ob.service_id.CopyFrom(service.service_id) + obt = ob["band_type"] + if obt == "l_slots": + band_type = "L_BAND" + elif obt == "s_slots": + band_type = "S_BAND" + else: + band_type = "C_BAND" + + freq = ob["freq"] + bx = ob["band"] + #+1 is added to avoid overlap in the WSS of MGONs + lf = int(int(freq)-int(bx/2))+1 + uf = int(int(freq)+int(bx/2)) + val_ob = { + "band_type" : band_type, + "low-freq" : lf, + "up-freq" : uf, + "frequency" : freq, + "band" : bx, + "ob_id" : ob_id, + "bidir" : bidir_f + } + rules_ob.append(ConfigRule_Custom(resource_key="/settings-ob_{}".format(uuuid_x), resource_value=json.dumps(val_ob))) + bidir_ob = ob["bidir"] + # in case the service is built upon existed optical band , don't clacluate the endpoints of it + for devxb in ob["flows"].keys(): + log.debug("optical-band device {}".format(devxb)) + in_end_point_b = "0" + out_end_point_b = "0" + in_end_point_f = ob["flows"][devxb]["f"]["in"] + out_end_point_f = ob["flows"][devxb]["f"]["out"] + log.debug("optical-band ports {}, {}".format(in_end_point_f, out_end_point_f)) + if bidir_ob: + in_end_point_b = ob["flows"][devxb]["b"]["in"] + out_end_point_b = ob["flows"][devxb]["b"]["out"] + log.debug("optical-band ports {}, {}".format(in_end_point_b, out_end_point_b)) + #if (in_end_point_f == "0" or out_end_point_f == "0") and (in_end_point_b == "0" or out_end_point_b == "0"): + if in_end_point_f != "0": + d_ob, p_ob = get_uuids_from_names(devices, devxb, in_end_point_f) + if d_ob != "" and p_ob != "": + end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) + connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) + else: + log.info("no map device port for device {} port {}".format(devxb, in_end_point_f)) + + if out_end_point_f != "0": + d_ob, p_ob = get_uuids_from_names(devices, devxb, out_end_point_f) + if d_ob != "" and p_ob != "": + end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) + connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) + else: + log.info("no map device port for device {} port {}".format(devxb, out_end_point_f)) + if in_end_point_b != "0": + d_ob, p_ob = get_uuids_from_names(devices, devxb, in_end_point_b) + if d_ob != "" and p_ob != "": + end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) + connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) + else: + log.info("no map device port for device {} port {}".format(devxb, in_end_point_b)) + if out_end_point_b != "0": + d_ob, p_ob = get_uuids_from_names(devices, devxb, out_end_point_b) + if d_ob != "" and p_ob != "": + end_point_b = EndPointId(topology_id=topo, device_id=DeviceId(device_uuid=Uuid(uuid=d_ob)), endpoint_uuid=Uuid(uuid=p_ob)) + connection_ob.path_hops_endpoint_ids.add().CopyFrom(end_point_b) + else: + log.info("no map device port for device {} port {}".format(devxb, out_end_point_b)) + log.debug("optical-band connection {}".format(connection_ob)) + #check that list of endpoints is not empty + if connection_ob is not None and len(connection_ob.path_hops_endpoint_ids) == 0: + log.debug("deleting empty optical-band connection") + opt_reply.connections.remove(connection_ob) + + ''' + #inizialize custom optical parameters + band = r["band"] if "band" in r else None + op_mode = r["op-mode"] if "op-mode" in r else None + frequency = r["freq"] if "freq" in r else None + flow_id = r["flow_id"] if "flow_id" in r else None + r_type = r["band_type"] if "band_type" in r else None + if r_type == "l_slots": + band_type = "L_BAND" + elif r_type == "s_slots": + band_type = "S_BAND" + else: + band_type = "C_BAND" + if ob_id != 0: + val = {"target-output-power": "1.0", "frequency": frequency, "operational-mode": op_mode, "band": band, "flow_id": flow_id, "ob_id": ob_id, "band_type": band_type, "bidir": bidir_f} + else: + val = {"target-output-power": "1.0", "frequency": frequency, "operational-mode": op_mode, "band": band, "flow_id": flow_id, "band_type": band_type, "bidir": bidir_f} + custom_rule = ConfigRule_Custom(resource_key="/settings", resource_value=json.dumps(val)) + rule = ConfigRule(action=ConfigActionEnum.CONFIGACTION_SET, custom=custom_rule) + service.service_config.config_rules.add().CopyFrom(rule) + ''' + + if len(rules_ob) > 0: + for rulex in rules_ob: + rule_ob = ConfigRule(action=ConfigActionEnum.CONFIGACTION_SET, custom=rulex) + service.service_config.config_rules.add().CopyFrom(rule_ob) + + opt_reply.services.add().CopyFrom(service) + return opt_reply + + + def adapt_reply(devices, service, reply_json, context_id, topology_id, optical_band_txt) -> PathCompReply: opt_reply = PathCompReply() topo = TopologyId( diff --git a/src/service/tests/test_recon.py b/src/service/tests/test_recon.py new file mode 100644 index 000000000..97acdf7e2 --- /dev/null +++ b/src/service/tests/test_recon.py @@ -0,0 +1,101 @@ +# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + +import logging, pytest +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, Service +#from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario +from common.tools.grpc.Tools import grpc_message_to_json_string +from common.tools.object_factory.Context import json_context_id +from context.client.ContextClient import ContextClient +from device.client.DeviceClient import DeviceClient +from service.client.ServiceClient import ServiceClient + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +DESCRIPTOR_FILE = 'src/service/tests/descriptors_recompute_conns.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) + +@pytest.fixture(scope='session') +def context_client(): + _client = ContextClient() + yield _client + _client.close() + +@pytest.fixture(scope='session') +def device_client(): + _client = DeviceClient() + yield _client + _client.close() + +@pytest.fixture(scope='session') +def service_client(): + _client = ServiceClient() + yield _client + _client.close() + + +def test_service_recompute_connection( + context_client : ContextClient, # pylint: disable=redefined-outer-name + device_client : DeviceClient, # pylint: disable=redefined-outer-name + service_client : ServiceClient, # pylint: disable=redefined-outer-name +) -> None: + + # ===== Setup scenario ============================================================================================= + #validate_empty_scenario(context_client) + + # Load descriptors and validate the base scenario + #descriptor_loader = DescriptorLoader( + # descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client, + # service_client=service_client) + #results = descriptor_loader.process() + #check_descriptor_load_results(results, descriptor_loader) + #descriptor_loader.validate() + + + # ===== Recompute Connection ======================================================================================= + response = context_client.ListServices(ADMIN_CONTEXT_ID) + print('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) + #assert len(response.services) == 1 + for service in response.services: + #service = response.services[0] + service_id = service.service_id + name = service.name + print(name) + + if name == "optical-connection1": + response = context_client.ListConnections(service_id) + print("AAAAAAAAA") + print(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( + grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) + assert len(response.connections) == 1 # 1 connection per service + str_old_connections = grpc_message_to_json_string(response) + + # Change path first time + request = Service() + request.CopyFrom(service) + del request.service_endpoint_ids[:] # pylint: disable=no-member + del request.service_constraints[:] # pylint: disable=no-member + del request.service_config.config_rules[:] # pylint: disable=no-member + service_client.RecomputeConnections(request) + + response = context_client.ListConnections(service_id) + print(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( + grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) + assert len(response.connections) == 1 # 1 connection per service + str_new_connections = grpc_message_to_json_string(response) + print(' new connection => {:s}'.format(str_new_connections)) + + -- GitLab From 6ef57ac5534c91fe68fdaba47edc04677f903850 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Thu, 23 Oct 2025 23:19:59 +0200 Subject: [PATCH 092/638] bugfix delete empty service --- src/service/service/ServiceServiceServicerImpl.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index eeb2cd4a6..5aa56c7e7 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -416,7 +416,8 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): 'flow_id' : None } devs = [] - + src = "" + dst = "" context_id_x = json_context_id(DEFAULT_CONTEXT_NAME) topology_id_x = json_topology_id( DEFAULT_TOPOLOGY_NAME, context_id_x) @@ -425,8 +426,11 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): devices = topology_details.devices for endpoint_id in service.service_endpoint_ids: devs.append(endpoint_id.device_id.device_uuid.uuid) - src = get_device_name_from_uuid(devices, devs[0]) - dst = get_device_name_from_uuid(devices, devs[1]) + if len(devs) == 2: + src = get_device_name_from_uuid(devices, devs[0]) + dst = get_device_name_from_uuid(devices, devs[1]) + else: + print("empty service") bitrate = 100 bidir = 0 oc_type = 1 -- GitLab From dfa3e03563c1eb92acb832967dc669648d7e48dc Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Fri, 31 Oct 2025 17:06:32 +0100 Subject: [PATCH 093/638] working with disjoint and multiple bands --- src/opticalcontroller/OpticalController.py | 14 +- src/opticalcontroller/RSA.py | 62 ++++++- src/opticalcontroller/dijkstra.py | 169 ++++++++++++++++-- .../service/ServiceServiceServicerImpl.py | 14 +- src/service/service/tools/OpticalTools.py | 8 +- 5 files changed, 233 insertions(+), 34 deletions(-) diff --git a/src/opticalcontroller/OpticalController.py b/src/opticalcontroller/OpticalController.py index 075c8a42b..042461f5e 100644 --- a/src/opticalcontroller/OpticalController.py +++ b/src/opticalcontroller/OpticalController.py @@ -70,23 +70,25 @@ class AddLightpath(Resource): #@optical.route('/AddFlexLightpath///') @optical.route('/AddFlexLightpath///', - defaults={"bidir": 1, "band": None}) + defaults={"bidir": 1, "band": None, "obx_idx": None}) @optical.route('/AddFlexLightpath////', - defaults={"band": None}) -@optical.route('/AddFlexLightpath/////',) + defaults={"band": None, "obx_idx": None}) +@optical.route('/AddFlexLightpath/////', + defaults={"obx_idx": None}) +@optical.route('/AddFlexLightpath//////') @optical.response(200, 'Success') @optical.response(404, 'Error, not found') class AddFlexLightpath(Resource): @staticmethod - def put(src, dst, bitrate, bidir=1, band=None): + def put(src, dst, bitrate, bidir=1, band=None, obx_idx = None): - print("INFO: New FlexLightpath request from {} to {} with rate {} and band {}".format(src, dst, bitrate, band)) + print("INFO: New MGON request from {} to {} with rate {} and band {}".format(src, dst, bitrate, band)) t0 = time.time()*1000.0 #if debug: # rsa.g.printGraph() if rsa is not None: - flow_id, optical_band_id = rsa.rsa_fs_computation(src, dst, bitrate, bidir, band) + flow_id, optical_band_id = rsa.rsa_fs_computation(src, dst, bitrate, bidir, band, obx_idx) if flow_id is not None: if rsa.db_flows[flow_id]["op-mode"] == 0: return 'No path found', 404 diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index 861afeb01..1dedc2b77 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -147,7 +147,31 @@ class RSA(): self.g.reset_graph() return links, path - def get_slots(self, links, slots, optical_band_id=None): + def compute_disjoint_path(self, src, dst, path1=None): + if path1 == None: + path1 = shortest_path(self.g, self.g.get_vertex(src), self.g.get_vertex(dst)) + path = disjoint_path(self.g, src, dst, path1, False) + print("INFO: Path from {} to {} with distance: {}".format(src, dst, self.g.get_vertex(dst).get_distance())) + if debug: + print(path) + links = [] + for i in range(0, len(path) - 1): + s = path[i] + if debug: + print(s) + if i < len(path) - 1: + d = path[i + 1] + link_id = "{}-{}".format(s, d) + if debug: + #print(link_id, self.links_dict[link_id]) + print(link_id, self.get_link_by_name(link_id)) + + links.append(link_id) + self.g.reset_graph() + return links, path + + + def get_slots(self, links, slots, optical_band_id=None, old_band_x=None): if isinstance(slots, int): val_c = slots @@ -246,6 +270,7 @@ class RSA(): l_slots[l] = combine(l_slots[l], consecutives(fib["l_slots"], val_l)) l_found = 1''' if optical_band_id is not None: + print(f"NEW_DISJOINT: {self.optical_bands[optical_band_id]}") if "c_slots" in self.optical_bands[optical_band_id].keys(): if len(self.optical_bands[optical_band_id]["c_slots"]) > 0: a_c = c_sts @@ -269,7 +294,15 @@ class RSA(): s_sts = common_slots(a_s, b_s) else: s_sts = [] - + if old_band_x == "c_slots": + c_sts = [] + l_sts = [] + if old_band_x == "l_slots": + c_sts = [] + l_sts = [] + if old_band_x == "s_slots": + s_sts = [] + return c_sts, l_sts, s_sts def update_link(self, fib, slots, band): @@ -336,7 +369,7 @@ class RSA(): #update_optical_band(optical_bands=self.optical_bands,optical_band_id=optical_band_id,band=band,link=link) - def del_flow(self, flow,flow_id, o_b_id = None): + def del_flow(self, flow, flow_id, o_b_id = None): flows = flow["flows"] band = flow["band_type"] slots = flow["slots"] @@ -839,7 +872,7 @@ class RSA(): #self.db_flows[flow_id]["parent_opt_band"] = 0 #self.db_flows[flow_id]["new_optical_band"] = 0 - def create_optical_band(self, links, path, bidir, num_slots): + def create_optical_band(self, links, path, bidir, num_slots, old_band_x=None): print("INFO: Creating optical-band of {} slots".format(num_slots)) if self.opt_band_id == 0: self.opt_band_id += 1 @@ -888,8 +921,7 @@ class RSA(): if bidir: self.optical_bands[back_opt_band_id]["src"] = path[-1] ''' - - c_slots, l_slots, s_slots = self.get_slots(links, num_slots) + c_slots, l_slots, s_slots = self.get_slots(links, num_slots, optical_band_id=None, old_band_x=old_band_x) if debug: print(c_slots) print(l_slots) @@ -991,7 +1023,7 @@ class RSA(): result.append(ob_id) return result - def rsa_fs_computation(self, src, dst, rate, bidir, band): + def rsa_fs_computation(self, src, dst, rate, bidir, band, bandx_id): if band is not None: num_slots_ob = map_band_to_slot(band) print(band, num_slots_ob) @@ -999,11 +1031,23 @@ class RSA(): num_slots_ob = "full_band" if self.nodes_dict[src]["type"] == "OC-ROADM" and self.nodes_dict[dst]["type"] == "OC-ROADM": print("INFO: ROADM to ROADM connection") - links, path = self.compute_path(src, dst) + old_band_x = None + if bandx_id != None: + if bandx_id in self.optical_bands.keys(): + path_x = self.optical_bands[bandx_id]["path"] + old_band_x = self.optical_bands[bandx_id]["band_type"] + links, path = self.compute_disjoint_path(src, dst, path_x) + else: + links, path = self.compute_disjoint_path(src, dst, None) + if len(path) < 1: + print("INFO: no disjoint path found, installing in the shortest path") + links, path = self.compute_path(src, dst) + else: + links, path = self.compute_path(src, dst) if len(path) < 1: self.null_values_ob(self.opt_band_id) return self.opt_band_id, [] - optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob) + optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob, old_band_x) return None, optical_band_id print("INFO: TP to TP connection") if self.flow_id == 0: diff --git a/src/opticalcontroller/dijkstra.py b/src/opticalcontroller/dijkstra.py index 2657990cf..68180e427 100644 --- a/src/opticalcontroller/dijkstra.py +++ b/src/opticalcontroller/dijkstra.py @@ -129,9 +129,20 @@ class Graph: self.vert_dict[frm].add_neighbor(self.vert_dict[to], [port_frm, w]) self.vert_dict[to].add_neighbor(self.vert_dict[frm], [port_to, w]) + ''' def del_edge(self, frm, to, cost = 0): self.vert_dict[frm].del_neighbor(self.vert_dict[to]) self.vert_dict[to].del_neighbor(self.vert_dict[frm]) + ''' + + def del_edge(self, frm, to, cost=0): + if frm in self.vert_dict and to in self.vert_dict: + v_from = self.vert_dict[frm] + v_to = self.vert_dict[to] + if v_to in v_from.adjacent: + v_from.del_neighbor(v_to) + if v_from in v_to.adjacent: + v_to.del_neighbor(v_from) def get_vertices(self): return self.vert_dict.keys() @@ -142,6 +153,45 @@ class Graph: def get_previous(self, current): return self.previous + def copy(self): + """ + Returns a deep copy of the graph (vertices, edges, ports, and weights). + """ + new_graph = Graph() + + # First, create all vertices + for node_id in self.vert_dict: + new_graph.add_vertex(node_id) + + # Then, add all edges with the same attributes + for v in self: + for neighbor in v.get_connections(): + frm = v.get_id() + to = neighbor.get_id() + port_frm = v.get_port(neighbor) + port_to = neighbor.get_port(v) + weight = v.get_weight(neighbor) + + # To avoid adding the same undirected edge twice + if frm < to: + new_graph.add_edge(frm, to, port_frm, port_to, weight) + + return new_graph + + def copy2(self): + new_g = Graph() + # Copy vertices + for node_id in self.vert_dict: + new_g.add_vertex(node_id) + # Copy edges + for frm in self.vert_dict: + for to in self.vert_dict[frm].adjacent: + port_frm, weight = self.vert_dict[frm].adjacent[to] + port_to, _ = self.vert_dict[to].adjacent[frm] + if not new_g.get_vertex(frm).adjacent.get(new_g.get_vertex(to)): + new_g.add_edge(frm, to.get_id(), port_frm, port_to, weight) + return new_g + def shortest(v, path): if v.previous: path.append(v.previous.get_id()) @@ -198,6 +248,90 @@ def shortest_path(graph, src, dst): shortest(target, path) return path[::-1] + +def compute_disjoint_paths(graph, src, dst, k=2, disjoint_type="link", debug=False): + """ + Compute up to k disjoint shortest paths between src and dst using Dijkstra. + disjoint_type: "link" (edge-disjoint) or "node" (vertex-disjoint) + """ + + paths = [] + removed_edges = [] # Keep track of removed edges + removed_nodes = [] # Keep track of removed nodes + + for i in range(k): + # Compute shortest path using the existing Dijkstra-based function + path = shortest_path(graph, src, dst) + + # Stop if no valid path found + if not path or len(path) < 2: + if debug: + print(f"[INFO] No more disjoint paths found after {i} iterations.") + break + + paths.append(path) + if debug: + print(f"[INFO] Path {i+1}: {path}") + + # Depending on disjointness type, remove edges or nodes from graph + if disjoint_type == "link": + for u, v in zip(path[:-1], path[1:]): + if debug: + print(f" Removing edge {u}-{v}") + removed_edges.append((u, v)) + # Remove edge in both directions + graph.del_edge(u, v) + + elif disjoint_type == "node": + # Remove intermediate nodes (not source or destination) + for n in path[1:-1]: + if debug: + print(f" Removing node {n}") + removed_nodes.append(n) + # Remove all edges involving this node + v = graph.get_vertex(n) + if v is not None: + for neighbor in list(v.get_connections()): + graph.del_edge(n, neighbor.get_id()) + graph.del_Vertex(n) + else: + raise ValueError("disjoint_type must be 'link' or 'node'") + + # Reset distances & visited flags for the next run + graph.reset_graph() + + if debug: + print(f"[INFO] Found {len(paths)} disjoint paths.") + + return paths + +def disjoint_path(graph, src_id, dst_id, pathz, debug=False): + g2 = graph.copy() + src = g2.get_vertex(src_id) + dst = g2.get_vertex(dst_id) + removed_edges = [] # Keep track of removed edges + removed_nodes = [] # Keep track of removed nodes + for u, v in zip(pathz[:-1], pathz[1:]): + if debug: + print(f" Removing edge {u}-{v}") + removed_edges.append((u, v)) + # Remove edge in both directions + g2.del_edge(u, v) + # Compute shortest path using the existing Dijkstra-based function + g2.reset_graph() + pathx = shortest_path(g2, src, dst) + + # Stop if no valid path found + if not pathx or len(pathx) < 2: + if debug: + print(f"[INFO] No more disjoint paths found.") + return [] + + g2.reset_graph() + + return pathx + + if __name__ == '__main__': print("Testing Algo") @@ -210,15 +344,15 @@ if __name__ == '__main__': g.add_vertex('e') g.add_vertex('f') - g.add_edge('a', 'b', 7) - g.add_edge('a', 'c', 9) - g.add_edge('a', 'f', 14) - g.add_edge('b', 'c', 10) - g.add_edge('b', 'd', 15) - g.add_edge('c', 'd', 11) - g.add_edge('c', 'f', 2) - g.add_edge('d', 'e', 6) - g.add_edge('e', 'f', 9) + g.add_edge('a', 'b', 1, 1, 7) + g.add_edge('a', 'c', 2, 1, 9) + g.add_edge('a', 'f', 3, 1, 14) + g.add_edge('b', 'c', 2, 2, 10) + g.add_edge('b', 'd', 3, 1, 15) + g.add_edge('c', 'd', 3, 2, 11) + g.add_edge('c', 'f', 4, 2, 2) + g.add_edge('d', 'e', 4, 1, 6) + g.add_edge('e', 'f', 2, 3, 9) """print ('Graph data:') @@ -235,6 +369,17 @@ if __name__ == '__main__': path = [target.get_id()] shortest(target, path) print ('The shortest path : %s' %(path[::-1]))""" - - p = shortest_path(g, g.get_vertex('a'), g.get_vertex('e')) - print(p) + #print(g.printGraph()) + pat = shortest_path(g, g.get_vertex('a'), g.get_vertex('e')) + print(pat) + + #paths = compute_disjoint_paths(g, g.get_vertex('a'), g.get_vertex('e'), k=2, disjoint_type="link", debug=False) + #paths = compute_disjoint_paths(g, g.get_vertex('a'), g.get_vertex('e'), k=2, disjoint_type="link", debug=False) + #print(paths) + path2 = compute_disjoint_path(g, 'a', 'e', pat, False) + print(path2) + + pat = shortest_path(g, g.get_vertex('a'), g.get_vertex('d')) + print(pat) + path2 = compute_disjoint_path(g, 'a', 'd', pat, False) + print(path2) \ No newline at end of file diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index 5aa56c7e7..0c0f0f0dc 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -288,6 +288,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): ob_band = None oc_type = 1 bitrate = 100 + dj_optical_band_id = None for constraint in service.service_constraints: if "bandwidth" in constraint.custom.constraint_type: bitrate = int(float(constraint.custom.constraint_value)) @@ -296,19 +297,22 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): elif "optical-band-width" in constraint.custom.constraint_type: ob_band = int(constraint.custom.constraint_value) elif "type" in constraint.custom.constraint_type: - logging.info(f"TEEEEEEEEEEEEEEST {constraint.custom.constraint_type}={constraint.custom.constraint_value}") + logging.info(f"{constraint.custom.constraint_type}={constraint.custom.constraint_value}") oc_type = OpticalServiceType(str(constraint.custom.constraint_value)) - logging.info(f"TEEEEEEEEEEEEEEST {oc_type}") - + logging.info(f"{oc_type}") + elif "disjoint_optical_band_id" in constraint.custom.constraint_type: + logging.info(f"{constraint.custom.constraint_type}={constraint.custom.constraint_value}") + dj_optical_band_id = int(constraint.custom.constraint_value) + logging.info(f"{dj_optical_band_id}") reply_txt = "" # to get the reply form the optical module #multi-granular if oc_type == 1: - reply_txt = add_flex_lightpath(src, dst, bitrate, bidir, ob_band) + reply_txt = add_flex_lightpath(src, dst, bitrate, bidir, ob_band, dj_optical_band_id) elif oc_type == 2: reply_txt = add_lightpath(src, dst, bitrate, bidir) else: - reply_txt = add_flex_lightpath(src, dst, bitrate, bidir, ob_band) + reply_txt = add_flex_lightpath(src, dst, bitrate, bidir, ob_band, dj_optical_band_id) logging.info(f"TEEEEEEEEEEEEEEST {oc_type}") logging.info(f"POLIMI {reply_txt}") if reply_txt == None: diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py index 1a44f4812..d5219fe52 100644 --- a/src/service/service/tools/OpticalTools.py +++ b/src/service/service/tools/OpticalTools.py @@ -137,11 +137,12 @@ def reconfig_flex_lightpath(flow_id) -> str: return reply_bid_txt -def add_flex_lightpath(src, dst, bitrate, bidir, ob_band) -> str: +def add_flex_lightpath(src, dst, bitrate, bidir, ob_band, dj_optical_band_id) -> str: if not TESTING: urlx = "" headers = {"Content-Type": "application/json"} base_url = get_optical_controller_base_url() + if ob_band is None: if bidir is None: bidir = 1 @@ -149,7 +150,10 @@ def add_flex_lightpath(src, dst, bitrate, bidir, ob_band) -> str: else: if bidir is None: bidir = 1 - urlx = "{:s}/AddFlexLightpath/{:s}/{:s}/{:s}/{:s}/{:s}".format(base_url, src, dst, str(bitrate), str(bidir), str(ob_band)) + if dj_optical_band_id is None: + urlx = "{:s}/AddFlexLightpath/{:s}/{:s}/{:s}/{:s}/{:s}".format(base_url, src, dst, str(bitrate), str(bidir), str(ob_band)) + else: + urlx = "{:s}/AddFlexLightpath/{:s}/{:s}/{:s}/{:s}/{:s}/{:s}".format(base_url, src, dst, str(bitrate), str(bidir), str(ob_band), str(dj_optical_band_id)) r = requests.put(urlx, headers=headers) print(f"addpathlight {r}") reply = r.text -- GitLab From 71b2c55f7dae0c43dece90282fb21d6784fbfc37 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Sun, 2 Nov 2025 21:05:52 +0100 Subject: [PATCH 094/638] working unidir with bug fix --- src/opticalcontroller/RSA.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index 1dedc2b77..38dee2e92 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -1236,7 +1236,7 @@ class RSA(): print("INFO: RSA completed for FLex Lightpath with new OB") if flow_list is None: self.null_values(self.flow_id) - return flow_id, optical_band_id + return self.flow_id, optical_band_id slots_i = [] for i in slots: slots_i.append(int(i)) -- GitLab From 0cd1a98366c986001b79449ca8b06171a127b6a8 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Tue, 4 Nov 2025 09:38:59 +0100 Subject: [PATCH 095/638] not working bidir --- my_deploy.sh | 4 +-- src/context/Dockerfile | 2 +- src/opticalcontroller/RSA.py | 30 ++++++++++++------ src/service/Dockerfile | 2 +- .../service/ServiceServiceServicerImpl.py | 31 ++++--------------- .../service_handlers/oc/OCServiceHandler.py | 1 + .../service/task_scheduler/TaskScheduler.py | 14 ++++++--- src/service/service/tools/OpticalTools.py | 8 ++--- 8 files changed, 45 insertions(+), 47 deletions(-) diff --git a/my_deploy.sh b/my_deploy.sh index 86c1a86f4..90fe39c75 100644 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -20,7 +20,7 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. -export TFS_COMPONENTS="context device pathcomp service nbi webui" +export TFS_COMPONENTS="context device pathcomp opticalcontroller service nbi webui" # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -140,7 +140,7 @@ export CRDB_PASSWORD="tfs123" export CRDB_DEPLOY_MODE="single" # Disable flag for dropping database, if it exists. -export CRDB_DROP_DATABASE_IF_EXISTS="" +export CRDB_DROP_DATABASE_IF_EXISTS="YES" # Disable flag for re-deploying CockroachDB from scratch. export CRDB_REDEPLOY="" diff --git a/src/context/Dockerfile b/src/context/Dockerfile index add63fe65..09c4b6115 100644 --- a/src/context/Dockerfile +++ b/src/context/Dockerfile @@ -28,7 +28,7 @@ ENV PYTHONUNBUFFERED=0 # chmod +x /bin/grpc_health_probe # Get generic Python packages -RUN python3 -m pip install --upgrade pip +RUN python3 -m pip install --upgrade 'pip==25.2' RUN python3 -m pip install --upgrade setuptools wheel RUN python3 -m pip install --upgrade pip-tools diff --git a/src/opticalcontroller/RSA.py b/src/opticalcontroller/RSA.py index 04f67bf0e..f1d2a1a0b 100644 --- a/src/opticalcontroller/RSA.py +++ b/src/opticalcontroller/RSA.py @@ -16,10 +16,13 @@ import logging from opticalcontroller.dijkstra import * from opticalcontroller.tools import * from opticalcontroller.variables import * + +''' LOGGER = logging.getLogger(__name__) def print(*args) -> None: LOGGER.info(' '.join([str(a) for a in args])) +''' class RSA(): def __init__(self, nodes, links): @@ -470,9 +473,9 @@ class RSA(): print(f"del_flow_fib {fib } and band {band}") print(f"del_flow { str_list_to_int(fib[band].keys())}") - print(f"invoking restore_link_2 fib: {fib} , slots {slots} , band {band} ") - #self.restore_link(fib, slots, band) - self.restore_link_2(fib, slots, band, link = link) + print(f"invoking restore_link fib: {fib} , slots {slots} , band {band} ") + self.restore_link(fib, slots, band) + #self.restore_link_2(fib, slots, band, link = link) self.optical_bands[o_b_id]["is_active"]=False @@ -492,7 +495,8 @@ class RSA(): fib = rlink["optical_details"] #fib = self.get_link_by_name(r_l)["optical_details"] if list_in_list(slots, str_list_to_int(fib[band].keys())): - self.restore_link_2(fib, slots, band, link=rlink) + self.restore_link(fib, slots, band) + #self.restore_link_2(fib, slots, band, link=rlink) if debug: print(fib[band]) #changed according to TFS development @@ -1261,8 +1265,8 @@ class RSA(): for l in links: link = self.get_link_by_name(l) fib = link["optical_details"] - #self.restore_link(fib, slots, band) - self.restore_link_2(fib, slots, band, link=link) + self.restore_link(fib, slots, band) + #self.restore_link_2(fib, slots, band, link=link) if o_b_id is not None: if debug: print("restoring OB") @@ -1282,8 +1286,8 @@ class RSA(): fib = rlink["optical_details"] #fib = self.get_link_by_name(r_l)["optical_details"] if list_in_list(slots, str_list_to_int(fib[band].keys())): - #self.restore_link(fib, slots, band, link=l) - self.restore_link_2(fib, slots, band, link=rlink) + self.restore_link(fib, slots, band) + #self.restore_link_2(fib, slots, band, link=rlink) if debug: print(fib[band]) @@ -1291,7 +1295,7 @@ class RSA(): def rsa_fs_recomputation(self, flow_idy): flow_idx = int(flow_idy) - print(f"INFO: Reconifguring connection {flow_idx}") + print(f"INFO: Reconfiguring connection {flow_idx}") if flow_idx not in self.db_flows.keys(): print(f"ERROR: key not present {flow_idx}") else: @@ -1336,15 +1340,23 @@ class RSA(): c_slots, l_slots, s_slots = self.get_slots(links, num_slots, ob_id) if debug: + print("OFC26 available slots pre") print(c_slots) print(l_slots) print(s_slots) if band_type == "c_slots": c_slots = [] + l_slots =[] elif band_type == "l_slots": + c_slots = [] l_slots = [] elif band_type == "s_slots": s_slots = [] + if debug: + print("OFC26 available slots after reset due to band") + print(c_slots) + print(l_slots) + print(s_slots) if len(c_slots) >= num_slots or len(l_slots) >= num_slots or len(s_slots) >= num_slots: flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports_fs(links, num_slots, c_slots, diff --git a/src/service/Dockerfile b/src/service/Dockerfile index 493094769..8b5101877 100644 --- a/src/service/Dockerfile +++ b/src/service/Dockerfile @@ -28,7 +28,7 @@ ENV PYTHONUNBUFFERED=0 # chmod +x /bin/grpc_health_probe # Get generic Python packages -RUN python3 -m pip install --upgrade pip +RUN python3 -m pip install --upgrade 'pip==25.2' RUN python3 -m pip install --upgrade setuptools wheel RUN python3 -m pip install --upgrade pip-tools diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index a346a134b..ac5e8afd8 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -454,6 +454,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): ''' #multi-granular if oc_type == 1: + LOGGER.info(f"DEVELOP: deleting multi-granular service") if len(service.service_config.config_rules) > 0: c_rules_dict = json.loads( service.service_config.config_rules[0].custom.resource_value @@ -472,12 +473,12 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): params['ob_id' ] = ob_id params['flow_id'] = flow_id params['bidir' ] = bidir - - + LOGGER.info(f"DEVELOP mg: {params}") tasks_scheduler = TasksScheduler(self.service_handler_factory) tasks_scheduler.compose_from_optical_service(service, params=params, is_delete=True) tasks_scheduler.execute_all() return Empty() + #flexigrid elif oc_type ==2 : if len(service.service_config.config_rules) > 0: @@ -493,31 +494,9 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): params['bitrate']=bitrate params['dst']=dst params['src']=src - params['ob_id']=ob_id params['flow_id']=flow_id params['bidir'] = bidir - - - tasks_scheduler = TasksScheduler(self.service_handler_factory) - tasks_scheduler.compose_from_optical_service(service, params=params, is_delete=True) - tasks_scheduler.execute_all() - return Empty() - elif oc_type ==2 : - if len(service.service_config.config_rules) > 0: - c_rules_dict = json.loads( - service.service_config.config_rules[0].custom.resource_value) - ob_id=None - flow_id=None - - if ("flow_id" in c_rules_dict): - flow_id = c_rules_dict["flow_id"] - #if ("ob_id" in c_rules_dict): - # ob_id = c_rules_dict["ob_id"] - params['bitrate']=bitrate - params['dst']=dst - params['src']=src - params['flow_id']=flow_id - params['bidir'] = bidir + LOGGER.info(f"DEVELOP flexgrid: {params}") tasks_scheduler = TasksScheduler(self.service_handler_factory) tasks_scheduler.compose_from_optical_service(service, params=params, is_delete=True) tasks_scheduler.execute_all() @@ -656,6 +635,8 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): new_connection = optical_reply.connections[0] #for candidate_new_connection in pathcomp_reply.connections: str_candidate_new_connection = connection_to_string(new_connection) + LOGGER.info('QQQQ_old:{}'.format(str_old_connection)) + LOGGER.info('QQQQ_new:{}'.format(str_candidate_new_connection)) # Change UUID of new connection to prevent collisions tmp_connection = Connection() tmp_connection.CopyFrom(new_connection) diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index 8aad5b17a..127f29c75 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -167,6 +167,7 @@ class OCServiceHandler(_ServiceHandler): flows = convert_or_endpoints_to_flows(endpoints, bidir) else: flows = endpoints_to_flows(endpoints, bidir, is_opticalband) + LOGGER.info(f'RERF:{flows}') for device_uuid, dev_flows in flows.items(): try: diff --git a/src/service/service/task_scheduler/TaskScheduler.py b/src/service/service/task_scheduler/TaskScheduler.py index cb09e553f..c9eaff31c 100644 --- a/src/service/service/task_scheduler/TaskScheduler.py +++ b/src/service/service/task_scheduler/TaskScheduler.py @@ -430,7 +430,7 @@ class TasksScheduler: if len(service.service_config.config_rules) > 0: for constraint in service.service_constraints: if "type" in constraint.custom.constraint_type: - oc_type = OpticalServiceType(str(constraint.custom.constraint_value)) + oc_type = OpticalServiceType(str(constraint.custom.constraint_value)) if oc_type == 2 : reply,code = delete_lightpath( params['src'] @@ -444,8 +444,7 @@ class TasksScheduler: , params ['dst'] , params['bitrate'] , params['ob_id'] - , delete_band=not has_media_channel - , flow_id= params['flow_id'] + , flow_id=params['flow_id'] ) if code == 400 and reply_not_allowed in reply : MSG = 'Deleteion for the service is not Allowed , Served Lightpaths is not empty' @@ -609,10 +608,15 @@ class TasksScheduler: self._executor, service.service_id, ServiceStatusEnum.SERVICESTATUS_UPDATING )) + #old_connection_deconfigure_key = self._add_task_if_not_exists(Task_OpticalConnectionDeconfigure( + # self._executor, old_connection.connection_id, old_connection.service_id + #)) + old_connection_deconfigure_key = self._add_task_if_not_exists(Task_OpticalConnectionDeconfigure( - self._executor, old_connection.connection_id, old_connection.service_id + self._executor, old_connection.connection_id, True )) + new_connection_configure_key = self._add_task_if_not_exists(Task_OpticalConnectionConfigure( self._executor, new_connection.connection_id )) @@ -739,7 +743,7 @@ class TasksScheduler: task = self._tasks.get(task_key) succeeded = True if dry_run else task.execute() results.append(succeeded) - LOGGER.debug('[execute_all] finished task {:s} ; succeeded={:s}'.format(str_task_name, str(succeeded))) + LOGGER.debug('[execute_allRRRR] finished task {:s} ; succeeded={:s}'.format(str_task_name, str(succeeded))) LOGGER.debug('[execute_all] results={:s}'.format(str(results))) return zip(ordered_task_keys, results) diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py index 4afa15f9c..4fb09718e 100644 --- a/src/service/service/tools/OpticalTools.py +++ b/src/service/service/tools/OpticalTools.py @@ -198,14 +198,14 @@ def get_optical_band(idx) -> str: return optical_band_uni_txt -def DelFlexLightpath( src, dst, bitrate, ob_id, delete_band, flow_id=None) -> str: - reply = "200" - delete_band = 1 if delete_band else 0 +def DelFlexLightpath( src, dst, bitrate, ob_id, flow_id=None) -> str: + reply = {} + code = 200 base_url = get_optical_controller_base_url() if not TESTING: if flow_id is not None: if ob_id is not None : - urlx = "{:s}/DelFlexLightpath/{}/{}/{}/{}/{}".format(base_url, src, dst, bitrate, flow_id,ob_id) + urlx = "{:s}/DelFlexLightpath/{}/{}/{}/{}/{}".format(base_url, src, dst, bitrate, flow_id, ob_id) else : #urlx = "http://{}:{}/OpticalTFS/DelOpticalBand/{}/{}/{}".format(OPTICAL_IP, OPTICAL_PORT, src, dst, ob_id) -- GitLab From 43c6e7a998d688e43bb313813e1921c8a6455a35 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Wed, 5 Nov 2025 21:41:50 +0100 Subject: [PATCH 096/638] BIDIR Bugs Fixed --- src/device/service/drivers/oc_driver/OCDriver.py | 2 +- .../service_handlers/oc/OCServiceHandler.py | 5 ++++- .../service/service_handlers/oc/OCTools.py | 15 +++++++++++---- .../service/task_scheduler/TaskExecutor.py | 1 + 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index f7c093ba3..e1757b4ef 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -180,7 +180,7 @@ def edit_config( str_config_messages=delete_optical_band(resources) else : str_config_messages=disable_media_channel(resources) - + logger.info(f"messages ,{str_config_messages} ") for str_config_message in str_config_messages: # configuration of the received templates if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG") diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py index 127f29c75..27fc89563 100644 --- a/src/service/service/service_handlers/oc/OCServiceHandler.py +++ b/src/service/service/service_handlers/oc/OCServiceHandler.py @@ -98,7 +98,8 @@ class OCServiceHandler(_ServiceHandler): if not is_opticalband: LOGGER.info(f"ob-expanded bvalue is: {ob_expansion} and is_opticalband {is_opticalband}") return results - + LOGGER.info(f"is_opticalband {is_opticalband}") + LOGGER.info(f"set_Opticalconfig_endpoints is:{endpoints}") flows = endpoints_to_flows(endpoints, bidir, is_opticalband) #new cycle for setting optical devices @@ -166,6 +167,8 @@ class OCServiceHandler(_ServiceHandler): if is_openroadm: flows = convert_or_endpoints_to_flows(endpoints, bidir) else: + LOGGER.info(f"is_opticalband {is_opticalband}") + LOGGER.info(f'RERF endpoints :{endpoints}') flows = endpoints_to_flows(endpoints, bidir, is_opticalband) LOGGER.info(f'RERF:{flows}') diff --git a/src/service/service/service_handlers/oc/OCTools.py b/src/service/service/service_handlers/oc/OCTools.py index 14cd7cbed..e3fcac3c4 100644 --- a/src/service/service/service_handlers/oc/OCTools.py +++ b/src/service/service/service_handlers/oc/OCTools.py @@ -302,8 +302,15 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): #if bidir reading 4 endpoints per node if bidir: log.info(f"i starts with {i} ") - i = i + 1 - while(i < end-2): + device0 , endpoint0=endpoints[0][0:2] + device1 , endpoint1=endpoints[1][0:2] + finalend=end-2 + if device0 ==device1: + i = i + 1 + + else : + finalend=end-1 + while(i < finalend): #i endpoint = endpoints[i] device_uuid, endpoint_uuid = endpoint[0:2] @@ -317,7 +324,7 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): entry_tuple = endpoint_uuid, next_endpoint_uuid entries[device_uuid].append(entry_tuple) else: - + log.info(f"error : next_dev {next_device_uuid} dev {device_uuid} for i {i} ") return {} #i+2 @@ -333,7 +340,7 @@ def conn_flows(endpoints : List[Tuple[str, str, Optional[str]]], bidir : int): entries[device_uuid].append(entry_tuple) i = i + 4 else: - + log.info(f"error : next_2_dev {next_2_device_uuid} next_3_device{next_3_device_uuid} dev {device_uuid} for i {i} ") return {} else: while(i < end-1): diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index ff97fd931..2855a9170 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -148,6 +148,7 @@ class TaskExecutor: self, device : Device, settings : str, flows : list, is_opticalband : bool, connection_uuid:str ): + LOGGER.info(f"service optical config {settings}") device_key = get_device_key(device.device_id) optical_config_id = OpticalConfigId() optical_config_id.opticalconfig_uuid = opticalconfig_get_uuid(device.device_id) -- GitLab From 421eda139fcc23f8f4000b60c752b677a9a2ea46 Mon Sep 17 00:00:00 2001 From: Waleed Akbar Date: Fri, 7 Nov 2025 18:04:53 +0000 Subject: [PATCH 097/638] Refactor imports and enhance gNMI collector functionality - Updated import paths for _Collector in INTCollector.py. - Added missing scapy dependency in requirements.in. - Changed return types to Optional in HelperMethods.py. - Improved disconnect handling in GnmiOpenConfigCollector.py. - Added TOTAL_POWER KPI in KPI.py. - Enhanced PathMapper.py for wavelength router support. - Refined SubscriptionNew.py with graceful stop and response parsing. - Updated test cases in messages.py and test_unit_GnmiOpenConfigCollector.py for better logging and parameter handling. --- .../collectors/intcollector/INTCollector.py | 2 +- src/telemetry/backend/requirements.in | 1 + .../backend/service/HelperMethods.py | 7 +- .../gnmi_oc/GnmiOpenConfigCollector.py | 44 +++++-- .../backend/service/collectors/gnmi_oc/KPI.py | 1 + .../service/collectors/gnmi_oc/PathMapper.py | 26 +++- .../collectors/gnmi_oc/SubscriptionNew.py | 121 +++++++++++++++--- .../backend/tests/gnmi_oc/messages.py | 71 ++++++---- .../test_unit_GnmiOpenConfigCollector.py | 13 +- 9 files changed, 220 insertions(+), 66 deletions(-) diff --git a/src/telemetry/backend/collectors/intcollector/INTCollector.py b/src/telemetry/backend/collectors/intcollector/INTCollector.py index 9d89827f4..5931f33f3 100644 --- a/src/telemetry/backend/collectors/intcollector/INTCollector.py +++ b/src/telemetry/backend/collectors/intcollector/INTCollector.py @@ -20,7 +20,7 @@ from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.executors.pool import ThreadPoolExecutor from datetime import datetime -from telemetry.backend.collector_api._Collector import _Collector +from telemetry.backend.service.collector_api._Collector import _Collector from scapy.all import * import struct diff --git a/src/telemetry/backend/requirements.in b/src/telemetry/backend/requirements.in index 3b1fd8b35..51ea6b906 100644 --- a/src/telemetry/backend/requirements.in +++ b/src/telemetry/backend/requirements.in @@ -20,3 +20,4 @@ kafka-python==2.0.6 numpy==2.0.1 pygnmi==0.8.14 pytz>=2025.2 +scapy==2.6.1 # TODO: UBI need to confirm the version (This depencdency was missing) diff --git a/src/telemetry/backend/service/HelperMethods.py b/src/telemetry/backend/service/HelperMethods.py index db56c9a76..0afd712c1 100644 --- a/src/telemetry/backend/service/HelperMethods.py +++ b/src/telemetry/backend/service/HelperMethods.py @@ -14,6 +14,7 @@ import uuid import logging +from typing import Optional from .collector_api._Collector import _Collector from .collector_api.DriverInstanceCache import get_driver from common.proto.kpi_manager_pb2 import KpiId @@ -24,7 +25,7 @@ LOGGER = logging.getLogger(__name__) def get_subscription_parameters( kpi_id : str, kpi_manager_client, context_client, duration, interval - ) -> list[tuple] | None: + ) -> Optional[list[tuple]]: """ Method to get subscription parameters based on KPI ID. Returns a list of tuples with subscription parameters. @@ -95,12 +96,12 @@ def get_subscription_parameters( def get_collector_by_kpi_id(kpi_id: str, kpi_manager_client, context_client, driver_instance_cache - ) -> _Collector | None: + ) -> Optional[_Collector]: """ Method to get a collector instance based on KPI ID. Preconditions: - A KPI Descriptor must be added in KPI DB with correct device_id. - - The device must be available in the context. + - The device must be available in the context DB. Returns: - Collector instance if found, otherwise None. Raises: diff --git a/src/telemetry/backend/service/collectors/gnmi_oc/GnmiOpenConfigCollector.py b/src/telemetry/backend/service/collectors/gnmi_oc/GnmiOpenConfigCollector.py index 44b169135..f84ba993f 100644 --- a/src/telemetry/backend/service/collectors/gnmi_oc/GnmiOpenConfigCollector.py +++ b/src/telemetry/backend/service/collectors/gnmi_oc/GnmiOpenConfigCollector.py @@ -75,12 +75,31 @@ class GNMIOpenConfigCollector(_Collector): def Disconnect(self) -> bool: """ Disconnect from the gNMI target device. + Stops all active subscriptions before closing the connection. """ + # Stop all active subscriptions first + if self._subscriptions: + self.logger.info("Stopping %d active subscription(s) before disconnect...", + len(self._subscriptions)) + # Create a list of subscription IDs to avoid dictionary size change during iteration + sub_ids = list(self._subscriptions.keys()) + for sub_id in sub_ids: + try: + self.UnsubscribeState(sub_id) + except Exception as exc: + self.logger.warning("Error stopping subscription %s during disconnect: %s", + sub_id, exc) + if self.connected and self.client: - self.client.close() - self.connected = False - self.logger.info("Disconnected from gNMI target %s:%s", self.address, self.port) - return True + try: + self.client.close() + self.connected = False + self.logger.info("Disconnected from gNMI target %s:%s", self.address, self.port) + return True + except Exception as exc: + self.logger.error("Error during disconnect: %s", exc) + self.connected = False # Mark as disconnected even if close fails + return False else: self.logger.warning("Not connected to any gNMI target.") return True @@ -129,18 +148,19 @@ class GNMIOpenConfigCollector(_Collector): return response def UnsubscribeState(self, resource_key: str) -> bool: - """Stop the given subscription.""" + """Stop the given subscription gracefully.""" sub = self._subscriptions.pop(resource_key, None) if not sub: - self.logger.error("Attempt to unsubscribe unknown id=%s", resource_key) - # raise KeyError(f"Unknown subscription id '{resource_key}'.") + self.logger.warning("Attempt to unsubscribe unknown id=%s", resource_key) return False - try: sub.stop() - except: - self.logger.exception("Error stopping subscription %s. ", resource_key) + + try: + sub.stop() + self.logger.info("Unsubscribed from state: %s", resource_key) + return True + except Exception as exc: + self.logger.error("Error stopping subscription %s: %s", resource_key, exc) return False - self.logger.info("Unsubscribed from state: %s", resource_key) - return True def GetState(self, duration : float, blocking : bool = True, terminate: Optional[queue.Queue] = None ) -> Iterator[Tuple[float, str, Any]]: diff --git a/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py b/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py index 7281c8a2e..9ac80dff0 100644 --- a/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py +++ b/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py @@ -25,4 +25,5 @@ class KPI(IntEnum): # TODO: verify KPI names and codes with KPI proto fi BYTES_RECEIVED = 202 BYTES_DROPPED = 203 INBAND_POWER = 301 + TOTAL_POWER = 302 # TODO: Add more KPIs as needed, diff --git a/src/telemetry/backend/service/collectors/gnmi_oc/PathMapper.py b/src/telemetry/backend/service/collectors/gnmi_oc/PathMapper.py index b02ca5598..a2c65c861 100644 --- a/src/telemetry/backend/service/collectors/gnmi_oc/PathMapper.py +++ b/src/telemetry/backend/service/collectors/gnmi_oc/PathMapper.py @@ -67,6 +67,13 @@ class PathMapper: KPI.INBAND_POWER: [ "inband-power", "inband-power-state" ], + + # ---- total power (optical wavelength router) ---------------- + # For optical devices using flex-scale-mg-on YANG model + # Path format: optical-power-total-input/instant or optical-power-total-output/instant + KPI.TOTAL_POWER: [ + "optical-power-total-input/instant", + ], } # --------------------------------------------------------------# @@ -78,6 +85,12 @@ class PathMapper: 'interfaces/interface[name={endpoint}]/state/counters/{leaf}', # 'interfaces/interface[name="{endpoint}"]/state/{leaf}', ] + + # Wavelength router prefixes (for optical devices) + # Uses oc-wave-router and fsmgon module prefixes to avoid origin extraction issues + _WAVELENGTH_ROUTER_PREFIXES = [ + 'oc-wave-router:wavelength-router/fsmgon:optical-bands/optical-band[index={endpoint}]/state/{leaf}', + ] # --------------------------------------------------------------# # Public helper # # --------------------------------------------------------------# @@ -88,9 +101,9 @@ class PathMapper: """ Return **a list** of path strings. - :param endpoint: Interface name, e.g. 'Ethernet0' + :param endpoint: Interface name (e.g. 'Ethernet0') or optical band index (e.g. '1') :param kpi: KPI enum - :param resource: Interface parameter + :param resource: Resource type: 'interface' or 'wavelength-router' """ try: kpi_enum = KPI(kpi) @@ -104,11 +117,16 @@ class PathMapper: paths: List[str] = [] for leaf in leaves: if resource == "interface": + # Use standard interface prefixes for prefix in cls._PREFIXES: paths.append(prefix.format(endpoint=endpoint, leaf=leaf)) + elif resource == "wavelength-router": + # Use wavelength router prefixes with module prefixes to avoid origin extraction + for prefix in cls._WAVELENGTH_ROUTER_PREFIXES: + paths.append(prefix.format(endpoint=endpoint, leaf=leaf)) else: raise ValueError(f"Unsupported resource: {resource}") - logger.debug("Built %d candidate path(s) for %s on %s", - len(paths), kpi_enum.name, endpoint) + logger.debug("Built %d candidate path(s) for %s on %s (resource=%s)", + len(paths), kpi_enum.name, endpoint, resource) return paths diff --git a/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py b/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py index e34b2e472..789f5ec1c 100644 --- a/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py +++ b/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py @@ -13,11 +13,11 @@ # limitations under the License. -from google.protobuf.json_format import MessageToDict from pygnmi.client import gNMIclient # type: ignore from queue import Queue -from typing import Callable, Tuple, Optional, List +from typing import Callable, Tuple, Optional, List, Any import grpc +import json import logging import threading @@ -39,10 +39,10 @@ class Subscription: gnmi_client: gNMIclient, path_list: List[str], metric_queue: Queue, - mode: str = "stream", - sample_interval_ns: int = 10_000_000_000, - heartbeat_interval_ns: int | None = None, # ← NEW - encoding: str = "json_ietf", + mode: str = "stream", + sample_interval_ns: int = 10_000_000_000, + heartbeat_interval_ns: Optional[int] = None, + encoding: str = "json_ietf", on_update: Optional[Callable[[dict], None]] = None, ) -> None: @@ -70,10 +70,83 @@ class Subscription: return self._queue.get(timeout=timeout) def stop(self) -> None: + """Gracefully stop the subscription thread.""" + if not self._thread.is_alive(): + logger.debug("Subscription %s thread already stopped", self.sub_id) + return + + logger.debug("Stopping subscription %s...", self.sub_id) self._stop_event.set() - self._thread.join(2) - logger.info("Stopped subscription %s", self.sub_id) + self._thread.join(timeout=3) + + if self._thread.is_alive(): + logger.warning("Subscription %s thread did not stop within timeout", self.sub_id) + else: + logger.info("Stopped subscription %s", self.sub_id) + # --------------------------------------------------------------# + # Internal loop # + # --------------------------------------------------------------# + def _parse_subscribe_response(self, stream_msg) -> dict: + """ + Parse gNMI SubscribeResponse protobuf message. + Mimics pygnmi's telemetryParser but simplified for our needs. + Properly decodes json_ietf_val by directly accessing protobuf bytes. + """ + response = {} + + if stream_msg.HasField("update"): + response["update"] = { + "timestamp": stream_msg.update.timestamp if stream_msg.update.timestamp else 0, + "update": [] + } + + # Process updates + for update_msg in stream_msg.update.update: + update_container = { + "path": self._gnmi_path_to_string(update_msg.path) if update_msg.path else None + } + + # Decode the value - THIS IS THE KEY PART + if update_msg.HasField("val"): + if update_msg.val.HasField("json_ietf_val"): + # Access raw bytes and decode directly (like pygnmi does) + decoded_val = json.loads(update_msg.val.json_ietf_val) + update_container["val"] = decoded_val + elif update_msg.val.HasField("json_val"): + update_container["val"] = json.loads(update_msg.val.json_val) + elif update_msg.val.HasField("string_val"): + update_container["val"] = update_msg.val.string_val + elif update_msg.val.HasField("int_val"): + update_container["val"] = update_msg.val.int_val + elif update_msg.val.HasField("uint_val"): + update_container["val"] = update_msg.val.uint_val + elif update_msg.val.HasField("bool_val"): + update_container["val"] = update_msg.val.bool_val + elif update_msg.val.HasField("float_val"): + update_container["val"] = update_msg.val.float_val + else: + update_container["val"] = None + + response["update"]["update"].append(update_container) + + elif stream_msg.HasField("sync_response"): + response["sync_response"] = stream_msg.sync_response + + return response + + def _gnmi_path_to_string(self, path_msg) -> str: + """Convert gNMI Path protobuf to string representation.""" + path_parts = [] + for elem in path_msg.elem: + part = elem.name + if elem.key: + # Add keys in sorted order for consistency + for key_name, key_val in sorted(elem.key.items()): + part += f"[{key_name}={key_val}]" + path_parts.append(part) + return "/".join(path_parts) + # --------------------------------------------------------------# # Internal loop # # --------------------------------------------------------------# @@ -82,13 +155,12 @@ class Subscription: path_list: List[str], mode: str, sample_interval_ns: int, - heartbeat_interval_ns: int | None, + heartbeat_interval_ns: Optional[int], encoding: str, on_update: Optional[Callable[[dict], None]], ) -> None: # pragma: no cover """ Try each candidate path until the Subscribe RPC succeeds. - * Top level mode: STREAM / ONCE / POLL (here we always stream) * Per entry mode: SAMPLE / ON_CHANGE """ @@ -103,7 +175,7 @@ class Subscription: entry: dict = {"path": path} if entry_mode == "sample": - entry["mode"] = "sample" + entry["mode"] = "sample" entry["sample_interval"] = sample_interval_ns elif entry_mode == "on_change": entry["mode"] = "on_change" @@ -121,19 +193,23 @@ class Subscription: try: logger.debug("Sub %s attempting path %s", self.sub_id, path) for stream in self.gnmi_client.subscribe(request): - msg_dict = MessageToDict(stream) - # logger.debug("Stream: %s", msg_dict) + # Check if stop was requested + if self._stop_event.is_set(): + logger.debug("Sub %s stop requested, breaking stream loop", self.sub_id) + break + + # Parse the protobuf message directly (like pygnmi does) + msg_dict = self._parse_subscribe_response(stream) # Process any update data - if msg_dict.get('update'): # 'update' in msg_dict: + if msg_dict.get('update'): logger.debug("Sub %s got update data", self.sub_id) if on_update: on_update(msg_dict) else: self._queue.put(msg_dict) - # logger.debug("The update added in queue → %s", msg_dict) # Put a dummy update if syncResponse is received to prevent timeout - elif msg_dict.get('syncResponse'): # 'syncResponse' in msg_dict: + elif msg_dict.get('sync_response'): logger.debug("Sub %s received sync response", self.sub_id) # Optional: put a notification about the sync if not on_update: @@ -142,13 +218,18 @@ class Subscription: logger.warning("Sub %s received unknown message: %s", self.sub_id, msg_dict) except grpc.RpcError as err: - if err.code() == grpc.StatusCode.INVALID_ARGUMENT: + # Handle graceful shutdown (channel closed) + if err.code() == grpc.StatusCode.CANCELLED: + logger.debug("Sub %s cancelled (channel closed) - graceful shutdown", self.sub_id) + break + elif err.code() == grpc.StatusCode.INVALID_ARGUMENT: logger.warning("Path '%s' rejected (%s) -- trying next", path, err.details()) continue - logger.exception("Subscription %s hit gRPC error: %s", - self.sub_id, err) - break + else: + logger.exception("Subscription %s hit gRPC error: %s", + self.sub_id, err) + break except Exception as exc: # pylint: disable=broad-except logger.exception("Subscription %s failed: %s", self.sub_id, exc) diff --git a/src/telemetry/backend/tests/gnmi_oc/messages.py b/src/telemetry/backend/tests/gnmi_oc/messages.py index d68d2dde3..4722e4bfb 100644 --- a/src/telemetry/backend/tests/gnmi_oc/messages.py +++ b/src/telemetry/backend/tests/gnmi_oc/messages.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Optional import uuid from common.proto import kpi_manager_pb2 from common.proto.kpi_sample_types_pb2 import KpiSampleType @@ -20,48 +21,68 @@ from src.telemetry.backend.service.collectors.gnmi_oc.KPI import KPI # Test device connection parameters devices = { 'device1': { - 'host': '10.1.1.86', - 'port': '6030', + 'host' : '10.1.1.86', + 'port' : '6030', 'username': 'ocnos', 'password': 'ocnos', 'insecure': True, + 'kpi' : KPI.PACKETS_RECEIVED, + 'resource': 'interface', + 'endpoint': 'Management0', }, 'device2': { - 'host': '10.1.1.87', - 'port': '6030', + 'host' : '10.1.1.87', + 'port' : '6030', 'username': 'ocnos', 'password': 'ocnos', 'insecure': True, + 'kpi' : KPI.PACKETS_RECEIVED, + 'resource': 'interface', + 'endpoint': 'Management0', }, 'device3': { - 'host': '172.20.20.101', - 'port': '6030', + 'host' : '172.20.20.101', + 'port' : '6030', 'username': 'admin', 'password': 'admin', 'insecure': True, + 'kpi' : KPI.PACKETS_RECEIVED, + 'resource': 'interface', + 'endpoint': 'Management0', + }, + 'mgon': { + 'host' : 'localhost', + 'port' : '50061', + 'username': 'admin', + 'password': 'admin', + 'insecure': True, + 'kpi' : KPI.TOTAL_POWER, + 'resource': 'wavelength-router', #TODO: verify resource name form mg-on model + 'endpoint': '1', }, } -def creat_basic_sub_request_parameters( - resource: str = 'interface', - endpoint: str = 'Management0', # 'Ethernet1', - kpi: KPI = KPI.PACKETS_RECEIVED, # It should be KPI Id not name? Need to be replaced with KPI id. -) -> dict: +def creat_basic_sub_request_parameters() -> dict: - device = devices['device3'] - return { - 'target' : (device['host'], device['port']), - 'username' : device['username'], - 'password' : device['password'], - 'connect_timeout' : 15, - 'insecure' : device['insecure'], - 'mode' : 'on_change', # Subscription internal mode posibly: on_change, poll, sample - 'sample_interval_ns': '3s', - 'sample_interval' : '10s', - 'kpi' : kpi, - 'resource' : resource, - 'endpoint' : endpoint, - } + device = devices['device3'] + if device: + kpi = device['kpi'] + resource = device['resource'] + endpoint = device['endpoint'] + return { + 'target' : (device['host'], device['port']), + 'username' : device['username'], + 'password' : device['password'], + 'connect_timeout' : 15, + 'insecure' : device['insecure'], + 'mode' : 'sample', # Subscription internal mode posibly: on_change, poll, sample + 'sample_interval_ns': '3s', + 'sample_interval' : '10s', + 'kpi' : kpi, + 'resource' : resource, + 'endpoint' : endpoint, + } + return {} def create_kpi_descriptor_request(descriptor_name: str = "Test_name"): _create_kpi_request = kpi_manager_pb2.KpiDescriptor() diff --git a/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py b/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py index 127098d26..06f7632d4 100644 --- a/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py +++ b/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py @@ -17,6 +17,7 @@ import time import pytest from telemetry.backend.service.collectors.gnmi_oc.GnmiOpenConfigCollector import GNMIOpenConfigCollector from .messages import creat_basic_sub_request_parameters +from ..Fixtures import kpi_manager_client, context_client logging.basicConfig( level=logging.DEBUG, @@ -25,6 +26,16 @@ logging.basicConfig( logger = logging.getLogger(__name__) +@pytest.fixture(autouse=True) +def log_all_methods(request): + ''' + This fixture logs messages before and after each test function runs, indicating the start and end of the test. + The autouse=True parameter ensures that this logging happens automatically for all tests in the module. + ''' + logger.info(f" >>>>> Starting test: {request.node.name} ") + yield + logger.info(f" <<<<< Finished test: {request.node.name} ") + @pytest.fixture def sub_parameters(): """Fixture to provide subscription parameters.""" @@ -98,7 +109,7 @@ def test_get_state_updates(collector, subscription_data): assert len(updates_received) > 0 -def test_unsubscribe_state(collector, subscription_data): +def test_unsubscribe_state(collector, subscription_data, kpi_manager_client, context_client): """Test unsubscribing from state.""" logger.info("----- Testing Unsubscribe -----") collector.SubscribeState(subscription_data) -- GitLab From e40fcec6e5720b17d88e56e13061f4d4b9eac9a6 Mon Sep 17 00:00:00 2001 From: Waleed Akbar Date: Mon, 10 Nov 2025 14:47:55 +0000 Subject: [PATCH 098/638] Enhance gNMI subscription handling and update test logging for dynamic durations --- .../service/collectors/gnmi_oc/SubscriptionNew.py | 15 ++++++++++++++- .../gnmi_oc/test_unit_GnmiOpenConfigCollector.py | 12 ++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py b/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py index 789f5ec1c..69c895a74 100644 --- a/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py +++ b/src/telemetry/backend/service/collectors/gnmi_oc/SubscriptionNew.py @@ -112,9 +112,22 @@ class Subscription: if update_msg.val.HasField("json_ietf_val"): # Access raw bytes and decode directly (like pygnmi does) decoded_val = json.loads(update_msg.val.json_ietf_val) + # Try to convert numeric strings to float for proper formatting + if isinstance(decoded_val, str): + try: + decoded_val = float(decoded_val) + except (ValueError, TypeError): + pass # Keep as string if not numeric update_container["val"] = decoded_val elif update_msg.val.HasField("json_val"): - update_container["val"] = json.loads(update_msg.val.json_val) + decoded_val = json.loads(update_msg.val.json_val) + # Try to convert numeric strings to float + if isinstance(decoded_val, str): + try: + decoded_val = float(decoded_val) + except (ValueError, TypeError): + pass + update_container["val"] = decoded_val elif update_msg.val.HasField("string_val"): update_container["val"] = update_msg.val.string_val elif update_msg.val.HasField("int_val"): diff --git a/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py b/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py index 06f7632d4..ccdb6d38b 100644 --- a/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py +++ b/src/telemetry/backend/tests/gnmi_oc/test_unit_GnmiOpenConfigCollector.py @@ -128,17 +128,21 @@ def test_full_workflow(collector, subscription_data): response1 = collector.SubscribeState(subscription_data) logger.info("Subscription started: %s", subscription_data) assert all(response1) and isinstance(response1, list) + + _, _, duration_received, interval_received = subscription_data[0] # Get updates - logger.info("Requesting state updates for 5 seconds ...") + logger.info(f"Requesting state updates for {duration_received} seconds after every {interval_received} seconds ...") updates_received = [] - for samples in collector.GetState(duration=5.0, blocking=True): + for samples in collector.GetState(duration=duration_received, blocking=True): logger.info("Received state update: %s", samples) updates_received.append(samples) assert len(updates_received) > 0 # Wait for additional updates - logger.info("Waiting for updates for 5 seconds...") - time.sleep(5) + logger.info(f"Waiting for updates after every {interval_received} seconds...") + + # put a sleep to simulate waiting for more updates + time.sleep(15) # Unsubscribe response2 = collector.UnsubscribeState("x123") -- GitLab From a1260aacf3cf50342ee92792c020d8c146964e45 Mon Sep 17 00:00:00 2001 From: Waleed Akbar Date: Mon, 10 Nov 2025 15:21:28 +0000 Subject: [PATCH 099/638] Add Optical Power Total Input KPI to proto and update corresponding Python enum --- proto/kpi_sample_types.proto | 1 + src/telemetry/backend/service/collectors/gnmi_oc/KPI.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/proto/kpi_sample_types.proto b/proto/kpi_sample_types.proto index 5fcda6df9..19cd59f15 100644 --- a/proto/kpi_sample_types.proto +++ b/proto/kpi_sample_types.proto @@ -31,6 +31,7 @@ enum KpiSampleType { KPISAMPLETYPE_ML_CONFIDENCE = 401; //. can be used by both optical and L3 without any issue KPISAMPLETYPE_OPTICAL_SECURITY_STATUS = 501; //. can be used by both optical and L3 without any issue + KPISAMPLETYPE_OPTICAL_POWER_TOTAL_INPUT = 502; KPISAMPLETYPE_L3_UNIQUE_ATTACK_CONNS = 601; KPISAMPLETYPE_L3_TOTAL_DROPPED_PACKTS = 602; diff --git a/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py b/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py index 9ac80dff0..4a57ab8dc 100644 --- a/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py +++ b/src/telemetry/backend/service/collectors/gnmi_oc/KPI.py @@ -25,5 +25,5 @@ class KPI(IntEnum): # TODO: verify KPI names and codes with KPI proto fi BYTES_RECEIVED = 202 BYTES_DROPPED = 203 INBAND_POWER = 301 - TOTAL_POWER = 302 + KPISAMPLETYPE_OPTICAL_POWER_TOTAL_INPUT = 302 # TODO: Add more KPIs as needed, -- GitLab From 9ad39336bbff1cdbc1c979c9c1c1c6356dd8daf8 Mon Sep 17 00:00:00 2001 From: sgambelluri Date: Mon, 10 Nov 2025 16:22:43 +0100 Subject: [PATCH 100/638] temo mon integration --- ofc26.sh | 229 ++++++++++++++++++++++++++++++ scripts/run_mon_test.sh | 28 ++++ src/service/service/monitoring.py | 148 +++++++++++++++++++ 3 files changed, 405 insertions(+) create mode 100644 ofc26.sh create mode 100755 scripts/run_mon_test.sh create mode 100644 src/service/service/monitoring.py diff --git a/ofc26.sh b/ofc26.sh new file mode 100644 index 000000000..e6926b64e --- /dev/null +++ b/ofc26.sh @@ -0,0 +1,229 @@ +#!/bin/bash +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + + +# ----- TeraFlowSDN ------------------------------------------------------------ + +# Set the URL of the internal MicroK8s Docker registry where the images will be uploaded to. +export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" + +# Set the list of components, separated by spaces, you want to build images for, and deploy. +export TFS_COMPONENTS="context device pathcomp opticalcontroller service nbi webui" + +# Uncomment to activate Monitoring (old) +#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" + +# Uncomment to activate Monitoring Framework (new) +export TFS_COMPONENTS="${TFS_COMPONENTS} kpi_manager kpi_value_writer kpi_value_api telemetry analytics automation" + +# Uncomment to activate QoS Profiles +#export TFS_COMPONENTS="${TFS_COMPONENTS} qos_profile" + +# Uncomment to activate BGP-LS Speaker +#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker" + +# Uncomment to activate Optical Controller +# To manage optical connections, "service" requires "opticalcontroller" to be deployed +# before "service", thus we "hack" the TFS_COMPONENTS environment variable prepending the +# "opticalcontroller" only if "service" is already in TFS_COMPONENTS, and re-export it. +#if [[ "$TFS_COMPONENTS" == *"service"* ]]; then +# BEFORE="${TFS_COMPONENTS% service*}" +# AFTER="${TFS_COMPONENTS#* service}" +# export TFS_COMPONENTS="${BEFORE} opticalcontroller service ${AFTER}" +#fi + +# Uncomment to activate ZTP +#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp" + +# Uncomment to activate Policy Manager +#export TFS_COMPONENTS="${TFS_COMPONENTS} policy" + +# Uncomment to activate Optical CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" + +# Uncomment to activate L3 CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" + +# Uncomment to activate TE +#export TFS_COMPONENTS="${TFS_COMPONENTS} te" + +# Uncomment to activate Forecaster +#export TFS_COMPONENTS="${TFS_COMPONENTS} forecaster" + +# Uncomment to activate E2E Orchestrator +#export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" + +# Uncomment to activate VNT Manager +#export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager" + +# Uncomment to activate OSM Client +#export TFS_COMPONENTS="${TFS_COMPONENTS} osm_client" + +# Uncomment to activate DLT and Interdomain +#export TFS_COMPONENTS="${TFS_COMPONENTS} interdomain dlt" +#if [[ "$TFS_COMPONENTS" == *"dlt"* ]]; then +# export KEY_DIRECTORY_PATH="src/dlt/gateway/keys/priv_sk" +# export CERT_DIRECTORY_PATH="src/dlt/gateway/keys/cert.pem" +# export TLS_CERT_PATH="src/dlt/gateway/keys/ca.crt" +#fi + +# Uncomment to activate QKD App +# To manage QKD Apps, "service" requires "qkd_app" to be deployed +# before "service", thus we "hack" the TFS_COMPONENTS environment variable prepending the +# "qkd_app" only if "service" is already in TFS_COMPONENTS, and re-export it. +#if [[ "$TFS_COMPONENTS" == *"service"* ]]; then +# BEFORE="${TFS_COMPONENTS% service*}" +# AFTER="${TFS_COMPONENTS#* service}" +# export TFS_COMPONENTS="${BEFORE} qkd_app service ${AFTER}" +#fi + +# Uncomment to activate SIMAP Connector +#export TFS_COMPONENTS="${TFS_COMPONENTS} simap_connector" + +# Uncomment to activate Load Generator +#export TFS_COMPONENTS="${TFS_COMPONENTS} load_generator" + + +# Set the tag you want to use for your images. +export TFS_IMAGE_TAG="dev" + +# Set the name of the Kubernetes namespace to deploy TFS to. +export TFS_K8S_NAMESPACE="tfs" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" + +# Uncomment to monitor performance of components +#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" + +# Uncomment when deploying Optical CyberSecurity +#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" + +# Set the new Grafana admin password +export TFS_GRAFANA_PASSWORD="admin123+" + +# Disable skip-build flag to rebuild the Docker images. +export TFS_SKIP_BUILD="" + + +# ----- CockroachDB ------------------------------------------------------------ + +# Set the namespace where CockroackDB will be deployed. +export CRDB_NAMESPACE="crdb" + +# Set the external port CockroackDB Postgre SQL interface will be exposed to. +export CRDB_EXT_PORT_SQL="26257" + +# Set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to. +export CRDB_EXT_PORT_HTTP="8081" + +# Set the database username to be used by Context. +export CRDB_USERNAME="tfs" + +# Set the database user's password to be used by Context. +export CRDB_PASSWORD="tfs123" + +# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing. +# See ./deploy/all.sh or ./deploy/crdb.sh for additional details +export CRDB_DEPLOY_MODE="single" + +# Disable flag for dropping database, if it exists. +export CRDB_DROP_DATABASE_IF_EXISTS="YES" + +# Disable flag for re-deploying CockroachDB from scratch. +export CRDB_REDEPLOY="" + + +# ----- NATS ------------------------------------------------------------------- + +# Set the namespace where NATS will be deployed. +export NATS_NAMESPACE="nats" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4222" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8222" + +# Set NATS installation mode to 'single'. This option is convenient for development and testing. +# See ./deploy/all.sh or ./deploy/nats.sh for additional details +export NATS_DEPLOY_MODE="single" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- Apache Kafka ----------------------------------------------------------- + +# Set the namespace where Apache Kafka will be deployed. +export KFK_NAMESPACE="kafka" + +# Set the port Apache Kafka server will be exposed to. +export KFK_EXT_PORT_CLIENT="9092" + +# Set Kafka installation mode to 'single'. This option is convenient for development and testing. +# See ./deploy/all.sh or ./deploy/kafka.sh for additional details +export KFK_DEPLOY_MODE="single" + +# Disable flag for re-deploying Kafka from scratch. +export KFK_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8812" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9009" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9000" + +# Set the database username to be used for QuestDB. +export QDB_USERNAME="admin" + +# Set the database user's password to be used for QuestDB. +export QDB_PASSWORD="quest" + +# Set the table name to be used by Monitoring for KPIs. +export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis" + +# Set the table name to be used by Slice for plotting groups. +export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups" + +# Disable flag for dropping tables if they exist. +export QDB_DROP_TABLES_IF_EXIST="" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" + + +# ----- K8s Observability ------------------------------------------------------ + +# Set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. +export PROM_EXT_PORT_HTTP="9090" + +# Set the external port Grafana HTTP Dashboards will be exposed to. +export GRAF_EXT_PORT_HTTP="3000" + + +# ----- Telemetry Config ------------------------------------------------------ + +# Define a Load Balancer IP for Telemetry Collector components +export LOAD_BALANCER_IP="192.168.5.250" # <-- Change this to match your network diff --git a/scripts/run_mon_test.sh b/scripts/run_mon_test.sh new file mode 100755 index 000000000..874e6bcda --- /dev/null +++ b/scripts/run_mon_test.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + + +PROJECTDIR=`pwd` + +cd $PROJECTDIR/src +#RCFILE=$PROJECTDIR/coverage/.coveragerc + +export KFK_SERVER_ADDRESS='127.0.0.1:9092' + +CRDB_SQL_ADDRESS=$(kubectl get service cockroachdb-public --namespace crdb -o jsonpath='{.spec.clusterIP}') +export CRDB_URI="cockroachdb://tfs:tfs123@${CRDB_SQL_ADDRESS}:26257/tfs_analytics?sslmode=require" + +python3 -m pytest --log-level=DEBUG --log-cli-level=INFO --verbose \ + service/service/monitoring.py diff --git a/src/service/service/monitoring.py b/src/service/service/monitoring.py new file mode 100644 index 000000000..dad72f00a --- /dev/null +++ b/src/service/service/monitoring.py @@ -0,0 +1,148 @@ +import uuid +from common.proto import kpi_manager_pb2 +from common.proto.kpi_sample_types_pb2 import KpiSampleType +from kpi_manager.client.KpiManagerClient import KpiManagerClient +import logging +import pytest +from common.proto.kpi_manager_pb2 import KpiId, KpiDescriptor, KpiDescriptorFilter, KpiDescriptorList + +import uuid +from common.proto import kpi_manager_pb2 +from common.proto.kpi_sample_types_pb2 import KpiSampleType +from src.telemetry.backend.service.collectors.gnmi_oc.KPI import KPI + +from telemetry.backend.service.collectors.gnmi_oc.GnmiOpenConfigCollector import GNMIOpenConfigCollector + + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + + +@pytest.fixture(scope='session') +def kpi_manager_client(): + LOGGER.info('Starting KpiManagerClient...') + _client = KpiManagerClient(host="10.152.183.91") + _client.connect() + LOGGER.info('Yielding Connected KpiManagerClient...') + yield _client + LOGGER.info('Closed KpiManagerClient...') + _client.close() + + + +def create_kpi_descriptor_request(descriptor_name: str = "optical_monitoring"): + _create_kpi_request = kpi_manager_pb2.KpiDescriptor() + #_create_kpi_request.kpi_id.kpi_id.uuid = str(uuid.uuid4()) + _create_kpi_request.kpi_id.kpi_id.uuid = "6e22f180-ba28-4641-b190-2287bf448888" + # _create_kpi_request.kpi_id.kpi_id.uuid = "f974b6cc-095f-4767-b8c1-3457b383fb99" + _create_kpi_request.kpi_description = descriptor_name + _create_kpi_request.kpi_sample_type = KpiSampleType.KPISAMPLETYPE_OPTICAL_POWER_TOTAL_INPUT + #_create_kpi_request.device_id.device_uuid.uuid = str(uuid.uuid4()) + _create_kpi_request.device_id.device_uuid.uuid = "5dc3f5d7-d3a9-5057-a9a0-8af943a5461c" + _create_kpi_request.service_id.service_uuid.uuid = 'SERV2' + _create_kpi_request.slice_id.slice_uuid.uuid = 'SLC1' + #_create_kpi_request.endpoint_id.endpoint_uuid.uuid = str(uuid.uuid4()) + _create_kpi_request.endpoint_id.endpoint_uuid.uuid = "decb9c95-7298-5ec8-a4b6-7f276f595106" + _create_kpi_request.connection_id.connection_uuid.uuid = 'CON1' + _create_kpi_request.link_id.link_uuid.uuid = 'LNK1' + return _create_kpi_request + + +''' +def test_SetKpiDescriptor(kpi_manager_client): + LOGGER.info(" >>> test_SetKpiDescriptor: START <<< ") + response = kpi_manager_client.SetKpiDescriptor(create_kpi_descriptor_request()) + LOGGER.info("Response gRPC message object: {:}".format(response)) + assert isinstance(response, KpiId) +''' + +''' +def test_GetKpiDescriptor(kpi_manager_client): + LOGGER.info(" >>> test_GetKpiDescriptor: START <<< ") + # adding KPI + response_id = kpi_manager_client.SetKpiDescriptor(create_kpi_descriptor_request()) + # get KPI + response = kpi_manager_client.GetKpiDescriptor(response_id) + LOGGER.info("Response gRPC message object: {:}".format(response)) + assert isinstance(response, KpiDescriptor) +''' + +# Test device connection parameters +devices = { + 'device1': { + 'host': '172.17.254.22', + 'port': '50061', + 'username': 'admin', + 'password': 'admin', + 'insecure': True, + } +} + +def create_basic_sub_request_parameters( + resource: str = 'components', + endpoint: str = 'port-1-in', # 'Ethernet1', + kpi: KPI = KPI.KPISAMPLETYPE_OPTICAL_POWER_TOTAL_INPUT, # It should be KPI Id not name? Need to be replaced with KPI id. +) -> dict: + + device = devices['device1'] + return { + 'target' : (device['host'], device['port']), + 'username' : device['username'], + 'password' : device['password'], + 'connect_timeout' : 15, + 'insecure' : device['insecure'], + 'mode' : 'sample', # Subscription internal mode posibly: on_change, poll, sample + 'sample_interval_ns': '3s', + 'sample_interval' : '10s', + 'kpi' : kpi, + 'resource' : resource, + 'endpoint' : endpoint, + } + + +@pytest.fixture +def sub_parameters(): + """Fixture to provide subscription parameters.""" + return create_basic_sub_request_parameters() + + +@pytest.fixture +def collector(sub_parameters): + """Fixture to create and connect GNMI collector.""" + collector = GNMIOpenConfigCollector( + username = sub_parameters['username'], + password = sub_parameters['password'], + insecure = sub_parameters['insecure'], + address = sub_parameters['target'][0], + port = sub_parameters['target'][1], + ) + collector.Connect() + yield collector + collector.Disconnect() + + +@pytest.fixture +def subscription_data(sub_parameters): + """Fixture to provide subscription data.""" + # It should return a list of tuples with subscription parameters. + return [ + ( + "sub_id_123", + { + "kpi" : sub_parameters['kpi'], + "endpoint" : sub_parameters['endpoint'], + "resource" : sub_parameters['resource'], + }, + float(10.0), + float(5.0), + ), + ] + + +def test_collector_connection(collector): + """Test collector connection.""" + LOGGER.info("----- Testing GNMI OpenConfig Collector Connection -----") + assert collector.connected is True + LOGGER.debug("Collector connected: %s", collector.connected) + + -- GitLab From 3a687d23b89e6e672fdb5bfefa482deaa670aef6 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Wed, 26 Nov 2025 11:38:09 +0000 Subject: [PATCH 101/638] WebUI component: - Fix Pan/Tilt/Zoom features of TFS WebUI Topo drawer --- src/webui/service/templates/js/topology.js | 146 +++++++++++++-------- src/webui/service/templates/main/home.html | 27 +++- 2 files changed, 114 insertions(+), 59 deletions(-) diff --git a/src/webui/service/templates/js/topology.js b/src/webui/service/templates/js/topology.js index dcbbc51be..d12669091 100644 --- a/src/webui/service/templates/js/topology.js +++ b/src/webui/service/templates/js/topology.js @@ -31,24 +31,39 @@ const margin = {top: 5, right: 5, bottom: 5, left: 5}; const icon_width = 40; const icon_height = 40; -width = 1400 - margin.left - margin.right; -height = 800 - margin.top - margin.bottom; - -//function handleZoom(e) { -// console.dir(e); -// d3.select('svg g').attr('transform', e.transform); -//} -//let zoom = d3.zoom().scaleExtent([0.01, 10]).translateExtent([[0, 0], [width, height]]).on('zoom', handleZoom); - -// append the svg object to the body of the page -const svg = d3.select('#topology') - .append('svg') +const topologyContainer = d3.select('#topology'); +const svg = topologyContainer.append('svg'); +const zoomLayer = svg.append('g'); +const graphLayer = zoomLayer.append('g') + .attr('transform', `translate(${margin.left}, ${margin.top})`); + +let width = 0; +let height = 0; +let graphInitialized = false; + +function updateCanvasSize() { + const bounds = topologyContainer.node().getBoundingClientRect(); + width = Math.max(bounds.width - margin.left - margin.right, 200); + height = Math.max(bounds.height - margin.top - margin.bottom, 200); + svg .attr('width', width + margin.left + margin.right) - .attr('height', height + margin.top + margin.bottom) - //.call(zoom) - .append('g') - .attr('transform', `translate(${margin.left}, ${margin.top})`) - ; + .attr('height', height + margin.top + margin.bottom); +} +updateCanvasSize(); + +function handleZoom() { + zoomLayer.attr('transform', d3.event.transform); +} + +const zoom = d3.zoom() + .scaleExtent([0.2, 8]) + .on('zoom', handleZoom); + +svg.call(zoom); + +const ZOOM_DURATION_MS = 250; +const ZOOM_SCALE_STEP = 1.2; +const PAN_OFFSET = 80; // svg objects var link, node, optical_link, labels; @@ -67,10 +82,21 @@ forceProperties = { var simulation = d3.forceSimulation(); +function applyDirectionalForces() { + simulation + .force("center", d3.forceCenter(width * forceProperties.center.x, height * forceProperties.center.y)) + .force("forceX", d3.forceX() + .strength(forceProperties.forceX.strength * forceProperties.forceX.enabled) + .x(width * forceProperties.forceX.x)) + .force("forceY", d3.forceY() + .strength(forceProperties.forceY.strength * forceProperties.forceY.enabled) + .y(height * forceProperties.forceY.y)); +} + // load the data d3.json("{{ url_for('main.topology') }}", function(data) { // set the data and properties of link lines and node circles - link = svg.append("g").attr("class", "links")//.style('stroke', '#aaa') + link = graphLayer.append("g").attr("class", "links")//.style('stroke', '#aaa') .selectAll("line") .data(data.links) .enter() @@ -86,7 +112,7 @@ d3.json("{{ url_for('main.topology') }}", function(data) { return l.name.toLowerCase().includes('mgmt') ? "5,5" : "0"; }); - optical_link = svg.append("g").attr("class", "links")//.style('stroke', '#aaa') + optical_link = graphLayer.append("g").attr("class", "links")//.style('stroke', '#aaa') .selectAll("line") .data(data.optical_links) .enter() @@ -102,7 +128,7 @@ d3.json("{{ url_for('main.topology') }}", function(data) { return l.name.toLowerCase().includes('mgmt') ? "5,5" : "0"; }); - node = svg.append("g").attr("class", "devices").attr('r', 20).style('fill', '#69b3a2') + node = graphLayer.append("g").attr("class", "devices").attr('r', 20).style('fill', '#69b3a2') .selectAll("circle") .data(data.devices) .enter() @@ -117,7 +143,7 @@ d3.json("{{ url_for('main.topology') }}", function(data) { // node tooltip //node.append("title").text(function(n) { return n.name; }); // persistent node labels - labels = svg.append("g").attr("class", "labels") + labels = graphLayer.append("g").attr("class", "labels") .selectAll("text") .data(data.devices) .enter() @@ -142,7 +168,7 @@ d3.json("{{ url_for('main.topology') }}", function(data) { // add forces, associate each with a name, and set their properties // Experimental : Optical link part - all_links = data.links.concat(data.optical_links) + const all_links = data.links.concat(data.optical_links); simulation .force("link", d3.forceLink() .id(function(d) {return d.id;}) @@ -162,19 +188,13 @@ d3.json("{{ url_for('main.topology') }}", function(data) { .force("collide", d3.forceCollide() .strength(forceProperties.collide.strength * forceProperties.collide.enabled) .radius(forceProperties.collide.radius) - .iterations(forceProperties.collide.iterations)) - .force("center", d3.forceCenter() - .x(width * forceProperties.center.x) - .y(height * forceProperties.center.y)) - .force("forceX", d3.forceX() - .strength(forceProperties.forceX.strength * forceProperties.forceX.enabled) - .x(width * forceProperties.forceX.x)) - .force("forceY", d3.forceY() - .strength(forceProperties.forceY.strength * forceProperties.forceY.enabled) - .y(height * forceProperties.forceY.y)); + .iterations(forceProperties.collide.iterations)); + + applyDirectionalForces(); // after each simulation tick, update the display positions simulation.on("tick", ticked); + graphInitialized = true; }); // update the display positions @@ -221,30 +241,40 @@ function dragended(d) { } // update size-related forces -d3.select(window).on("resize", function(){ - width = +svg.node().getBoundingClientRect().width; - height = +svg.node().getBoundingClientRect().height; - simulation.alpha(1).restart(); -}); +function handleResize() { + updateCanvasSize(); + if (graphInitialized) { + applyDirectionalForces(); + simulation.alpha(0.3).restart(); + } +} -///******************** UI ACTIONS *******************/ -// -//function resetZoom() { -// d3.select('svg').transition().call(zoom.scaleTo, 1.0); -//} -//function zoomIn() { -// d3.select('svg').transition().call(zoom.scaleBy, 2.0); -//} -//function zoomOut() { -// d3.select('svg').transition().call(zoom.scaleBy, 0.5); -//} -// -//function center() { -// d3.select('svg').transition().call(zoom.translateTo, 0.5 * width, 0.5 * height); -//} -//function panLeft() { -// d3.select('svg').transition().call(zoom.translateBy, -50, 0); -//} -//function panRight() { -// d3.select('svg').transition().call(zoom.translateBy, 50, 0); -//} +d3.select(window).on("resize", handleResize); + +/******************** UI ACTIONS *******************/ + +function resetZoom() { + svg.transition().duration(ZOOM_DURATION_MS).call(zoom.transform, d3.zoomIdentity); +} + +function zoomIn() { + svg.transition().duration(ZOOM_DURATION_MS).call(zoom.scaleBy, ZOOM_SCALE_STEP); +} + +function zoomOut() { + svg.transition().duration(ZOOM_DURATION_MS).call(zoom.scaleBy, 1 / ZOOM_SCALE_STEP); +} + +function center() { + const centerX = margin.left + width / 2; + const centerY = margin.top + height / 2; + svg.transition().duration(ZOOM_DURATION_MS).call(zoom.translateTo, centerX, centerY); +} + +function panLeft() { + svg.transition().duration(ZOOM_DURATION_MS).call(zoom.translateBy, -PAN_OFFSET, 0); +} + +function panRight() { + svg.transition().duration(ZOOM_DURATION_MS).call(zoom.translateBy, PAN_OFFSET, 0); +} diff --git a/src/webui/service/templates/main/home.html b/src/webui/service/templates/main/home.html index 5a5c439e1..4b66463ca 100644 --- a/src/webui/service/templates/main/home.html +++ b/src/webui/service/templates/main/home.html @@ -18,6 +18,17 @@ {% block content %}

ETSI TeraFlowSDN Controller

+ {% for field, message in context_topology_form.errors.items() %}