diff --git a/delete_me/Dockerfile b/delete_me/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..d9d9f9a6b7d433804510d39152b7a1a68885387d --- /dev/null +++ b/delete_me/Dockerfile @@ -0,0 +1,16 @@ +# Use the official Ubuntu image from the Docker Hub +FROM ubuntu:latest + +# Update and install any required packages + +RUN apt-get update + + +# Set the working directory +WORKDIR /app + +# Copy any necessary files into the working directory +COPY . /app + +# Specify the command to run when the container starts +CMD ["echo", "Hello, Docker!"] diff --git a/deploy/crdb.sh b/deploy/crdb.sh index ad0bdd30b6d01c8c70ad454220ee7d19f23468b8..ac270bfe7f14d70bb989c2582ed6ee56ad420881 100755 --- a/deploy/crdb.sh +++ b/deploy/crdb.sh @@ -104,7 +104,7 @@ function crdb_deploy_single() { printf "%c" "." sleep 1 done - kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-0 + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=3600s pod/cockroachdb-0 fi echo @@ -195,7 +195,7 @@ function crdb_deploy_cluster() { sed "s/%TFS_CRDB_NAMESPACE%/${CRDB_NAMESPACE}/g" "${CRDB_MANIFESTS_PATH}/operator.yaml" \ > "${TMP_MANIFESTS_FOLDER}/crdb_operator.yaml" kubectl apply -f "${TMP_MANIFESTS_FOLDER}/crdb_operator.yaml" - kubectl wait --namespace cockroach-operator-system --for=condition=Available=True --timeout=300s \ + kubectl wait --namespace cockroach-operator-system --for=condition=Available=True --timeout=3600s \ deployment/cockroach-operator-manager #kubectl wait --namespace cockroach-operator-system --for=jsonpath='{.status.readyReplicas}'=1 --timeout=300s \ # deployment/cockroach-operator-manager @@ -257,9 +257,9 @@ function crdb_deploy_cluster() { printf "%c" "." sleep 1 done - kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-0 - kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-1 - kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-2 + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=3600s pod/cockroachdb-0 + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=3600s pod/cockroachdb-1 + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=3600s pod/cockroachdb-2 fi echo @@ -271,7 +271,7 @@ function crdb_deploy_cluster() { echo ">>> Deploy CockroachDB Client" cp "${CRDB_MANIFESTS_PATH}/client-secure-operator.yaml" "${TMP_MANIFESTS_FOLDER}/crdb_client-secure-operator.yaml" kubectl create --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_client-secure-operator.yaml" - kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-client-secure + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=3600s pod/cockroachdb-client-secure fi echo diff --git a/deploy/tfs.sh b/deploy/tfs.sh index a1429e443eaa70252ab2dd1f673ce46826b28744..d1b9f191462bebbf2f0db2fd4a8b4423d4f7a791 100755 --- a/deploy/tfs.sh +++ b/deploy/tfs.sh @@ -218,7 +218,9 @@ kubectl create secret generic redis-secrets --namespace=$TFS_K8S_NAMESPACE \ echo "export REDIS_PASSWORD=${REDIS_PASSWORD}" >> $ENV_VARS_SCRIPT printf "\n" -DOCKER_BUILD="docker build" + +DOCKER_BUILD="docker build " + DOCKER_MAJOR_VERSION=$(docker --version | grep -o -E "Docker version [0-9]+\." | grep -o -E "[0-9]+" | cut -c 1-3) if [[ $DOCKER_MAJOR_VERSION -ge 23 ]]; then # If Docker version >= 23, build command was migrated to docker-buildx @@ -230,7 +232,8 @@ if [[ $DOCKER_MAJOR_VERSION -ge 23 ]]; then echo "If you installed docker through APT package docker.io, consider installing also package docker-buildx" exit 1; fi - DOCKER_BUILD="docker buildx build" + + DOCKER_BUILD="docker buildx build --network=host " fi LINKERD_STATUS="$(microk8s status -a linkerd)" diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml index 37f275b6ee4ad5883d38ac1496a7874408425831..527ac73d139d634ded303e773e376d72d7b2af09 100644 --- a/manifests/sliceservice.yaml +++ b/manifests/sliceservice.yaml @@ -50,7 +50,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:4040"] resources: requests: - cpu: 250m + cpu: 350m memory: 128Mi limits: cpu: 1000m diff --git a/manifests/tapiservice.yaml b/manifests/tapiservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..763bef36658562c9448ca6b58b6536cb4a53335c --- /dev/null +++ b/manifests/tapiservice.yaml @@ -0,0 +1,89 @@ +# 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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: tapiservice +spec: + selector: + matchLabels: + app: tapiservice + #replicas: 1 + template: + metadata: + labels: + app: tapiservice + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: labs.etsi.org:5050/tfs/controller/tapi:latest + imagePullPolicy: Always + ports: + - containerPort: 10070 + - containerPort: 9192 + env: + - name: LOG_LEVEL + value: "INFO" + + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 100m + memory: 1024Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: tapiservice + labels: + app: tapiservice +spec: + type: NodePort + selector: + app: tapiservice + ports: + - name: grpc + protocol: TCP + port: 10070 + targetPort: 10070 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: serviceservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: tapiservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml index 4d3b7780c4cfd82a87f89baee57633503d30b92d..a778605fdda7942f1951167e2accb77eafad69ca 100644 --- a/manifests/webuiservice.yaml +++ b/manifests/webuiservice.yaml @@ -61,29 +61,29 @@ spec: limits: cpu: 1000m memory: 1024Mi - - name: grafana - image: grafana/grafana:8.5.22 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 3000 - name: http-grafana - protocol: TCP - env: - - name: GF_SERVER_ROOT_URL - value: "http://0.0.0.0:3000/grafana/" - - name: GF_SERVER_SERVE_FROM_SUB_PATH - value: "true" - readinessProbe: - failureThreshold: 60 - httpGet: - #path: /robots.txt - path: /login - port: 3000 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 2 + # - name: grafana + # image: grafana/grafana:8.5.22 + # imagePullPolicy: IfNotPresent + # ports: + # - containerPort: 3000 + # name: http-grafana + # protocol: TCP + # env: + # - name: GF_SERVER_ROOT_URL + # value: "http://0.0.0.0:3000/grafana/" + # - name: GF_SERVER_SERVE_FROM_SUB_PATH + # value: "true" + # readinessProbe: + # failureThreshold: 60 + # httpGet: + # #path: /robots.txt + # path: /login + # port: 3000 + # scheme: HTTP + # initialDelaySeconds: 1 + # periodSeconds: 1 + # successThreshold: 1 + # timeoutSeconds: 2 livenessProbe: failureThreshold: 60 initialDelaySeconds: 1 @@ -114,9 +114,9 @@ spec: - name: webui port: 8004 targetPort: 8004 - - name: grafana - port: 3000 - targetPort: 3000 + # - name: grafana + # port: 3000 + # targetPort: 3000 --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler diff --git a/my_deploy.sh b/my_deploy.sh index a048edb30b66791d5405961b41faf2443f9d51e1..789d3f8ea211643477d9d63210879c62f36561e3 100755 --- 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 slice nbi webui" +export TFS_COMPONENTS="context device pathcomp opticalcontroller qkd_app service slice webui tapi " # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" diff --git a/proto/tapi.proto b/proto/tapi.proto new file mode 100644 index 0000000000000000000000000000000000000000..fd35cd02d4b6a65500695fd4b55723816557b197 --- /dev/null +++ b/proto/tapi.proto @@ -0,0 +1,30 @@ +// 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. + +syntax = "proto3"; +package tapi; + +import "context.proto"; + + +service TapiService { + rpc GetListTopologies (context.Empty ) returns ( context.TopologyList ) {} + rpc GetTopology (context.TopologyId ) returns ( context.Topology ) {} +} + + +message TapiRequest { + context.ContextId context_id = 1 ; + context.TopologyId topology_id = 2 ; +} diff --git a/scripts/show_logs_context.sh b/scripts/show_logs_context.sh index e3996fc053c22784703e47f362b3aefe912e18ac..a9ab7a084f40b78aa5d72fdef545ad913470d77d 100755 --- a/scripts/show_logs_context.sh +++ b/scripts/show_logs_context.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server --insecure-skip-tls-verify diff --git a/scripts/show_logs_tapi.sh b/scripts/show_logs_tapi.sh new file mode 100755 index 0000000000000000000000000000000000000000..6af5edc5b930fa988aa4b73ab0f07e2dece25af9 --- /dev/null +++ b/scripts/show_logs_tapi.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# 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. + +######################################################################################################################## +# Define your deployment settings here +######################################################################################################################## + +# If not already set, set the name of the Kubernetes namespace to deploy to. +export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/tapiservice -c server --insecure-skip-tls-verify diff --git a/src/common/Constants.py b/src/common/Constants.py index 68200764610b5fded328dbec741fdbbf70bc0930..d7d8a76f9b65f4bbeec3208b9bd667f3ab46683b 100644 --- a/src/common/Constants.py +++ b/src/common/Constants.py @@ -72,6 +72,9 @@ class ServiceNameEnum(Enum): ANALYTICS = 'analytics' ANALYTICSBACKEND = 'analytics-backend' QOSPROFILE = 'qos-profile' + + # Experiment + TAPI = "tapi" # Used for test and debugging only DLT_GATEWAY = 'dltgateway' diff --git a/src/common/tools/descriptor/Loader.py b/src/common/tools/descriptor/Loader.py index 4cdac3674b3b2e5598ddd65e25aa5cefc93306a9..4a5fc37dbfe216db194bf760b1a8f8f1e6f543d1 100644 --- a/src/common/tools/descriptor/Loader.py +++ b/src/common/tools/descriptor/Loader.py @@ -294,6 +294,7 @@ class DescriptorLoader: def num_connections(self) -> int: return len(self.__connections) def process(self) -> TypeResults: + LOGGER.info('processing') # Format CustomConfigRules in Devices, Services and Slices provided in JSON format self.__devices = [format_device_custom_config_rules (device ) for device in self.__devices ] self.__services = [format_service_custom_config_rules(service) for service in self.__services] diff --git a/src/context/Dockerfile b/src/context/Dockerfile index 10986e1a152b9b515c0d9dda3d7dde7a3c683d35..057348189842673845fab50ed5ea4d126b782099 100644 --- a/src/context/Dockerfile +++ b/src/context/Dockerfile @@ -18,6 +18,10 @@ FROM python:3.9-slim RUN apt-get --yes --quiet --quiet update && \ apt-get --yes --quiet --quiet install wget g++ git && \ rm -rf /var/lib/apt/lists/* +# Copy local_pkcgs_resource/. /tmp/sources +# Workdir tmp/sources/ +# Run dpkg -i wget_1.21.2-2ubuntu1.1_amd64.deb g++_4%3a11.2.0-1ubuntu1_amd64.deb git_1%3a2.34.1-1ubuntu1.11_amd64.deb +# RUN apt-get install -f -y && apt-get clean # Set Python to show logs as they occur ENV PYTHONUNBUFFERED=0 diff --git a/src/device/Dockerfile b/src/device/Dockerfile index d760e0c70d44fb4b53455ae60799e61964f5b23f..2da34c9eccdcf5c353c63d691ee549a61aec8d62 100644 --- a/src/device/Dockerfile +++ b/src/device/Dockerfile @@ -23,10 +23,11 @@ RUN apt-get --yes --quiet --quiet update && \ # - Ref: https://github.com/CESNET/libyang # - Ref: https://github.com/CESNET/libyang-python/ RUN mkdir -p /var/libyang -RUN git clone https://github.com/CESNET/libyang.git /var/libyang +#RUN git clone https://github.com/CESNET/libyang.git /var/libyang +COPY libyang/. /var/libyang WORKDIR /var/libyang RUN git fetch -RUN git checkout v2.1.148 +#RUN git checkout v2.1.148 RUN mkdir -p /var/libyang/build WORKDIR /var/libyang/build RUN cmake -D CMAKE_BUILD_TYPE:String="Release" .. diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py index c5a2439589fb5bab4874929a6850e19b22306f80..bfc84bf1a9b95f8b4f5c1e935b23e5bdde2136d4 100644 --- a/src/device/service/drivers/oc_driver/OCDriver.py +++ b/src/device/service/drivers/oc_driver/OCDriver.py @@ -200,18 +200,30 @@ def edit_config( if "L2VSI" in resources[0][1]: #Configure by CLI logger.warning("CLI Configuration") - cli_compose_config(resources, delete=delete, host= netconf_handler._NetconfSessionHandler__address, user=netconf_handler._NetconfSessionHandler__username, passw=netconf_handler._NetconfSessionHandler__password) + cli_compose_config(resources, + delete=delete, + host= netconf_handler._NetconfSessionHandler__address, + user=netconf_handler._NetconfSessionHandler__username, + passw=netconf_handler._NetconfSessionHandler__password) for i,resource in enumerate(resources): results.append(True) else: logger.warning("CLI Configuration CISCO INTERFACE") - cisco_interface(resources, delete=delete, host= netconf_handler._NetconfSessionHandler__address, user=netconf_handler._NetconfSessionHandler__username, passw=netconf_handler._NetconfSessionHandler__password) + cisco_interface(resources, + delete=delete, + host= netconf_handler._NetconfSessionHandler__address + , user=netconf_handler._NetconfSessionHandler__username, + passw=netconf_handler._NetconfSessionHandler__password) for i,resource in enumerate(resources): results.append(True) elif netconf_handler.vendor == "UFISPACE": #Configure by CLI logger.warning("CLI Configuration: {:s}".format(resources)) - ufi_interface(resources, delete=delete, host= netconf_handler._NetconfSessionHandler__address, user=netconf_handler._NetconfSessionHandler__username, passw=netconf_handler._NetconfSessionHandler__password) + ufi_interface(resources, + delete=delete, + host= netconf_handler._NetconfSessionHandler__address, + user=netconf_handler._NetconfSessionHandler__username, + passw=netconf_handler._NetconfSessionHandler__password) for i,resource in enumerate(resources): results.append(True) else: diff --git a/src/nbi/Dockerfile b/src/nbi/Dockerfile index a9be06d37c15757f51d6d849f395d683885e9508..eaa3b9d5b113b80d0b45260c437905984b470249 100644 --- a/src/nbi/Dockerfile +++ b/src/nbi/Dockerfile @@ -23,10 +23,11 @@ RUN apt-get --yes --quiet --quiet update && \ # - Ref: https://github.com/CESNET/libyang # - Ref: https://github.com/CESNET/libyang-python/ RUN mkdir -p /var/libyang -RUN git clone https://github.com/CESNET/libyang.git /var/libyang +#RUN git clone https://github.com/CESNET/libyang.git /var/libyang +COPY libyang/. /var/libyang WORKDIR /var/libyang RUN git fetch -RUN git checkout v2.1.148 +#RUN git checkout v2.1.148 RUN mkdir -p /var/libyang/build WORKDIR /var/libyang/build RUN cmake -D CMAKE_BUILD_TYPE:String="Release" .. diff --git a/src/tapi/.gitlab-ci.yml b/src/tapi/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..0c093b57005efbb604e1c316322942b2cdcb1c68 --- /dev/null +++ b/src/tapi/.gitlab-ci.yml @@ -0,0 +1,144 @@ +# 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. + +# Build, tag, and push the Docker image to the GitLab Docker registry +build device: + variables: + IMAGE_NAME: 'device' # name of the microservice + IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) + stage: build + before_script: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + script: + - docker buildx build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile . + - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" + - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$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"' + - changes: + - src/common/**/*.py + - proto/*.proto + - src/$IMAGE_NAME/**/*.{py,in,yml} + - src/$IMAGE_NAME/Dockerfile + - src/$IMAGE_NAME/tests/*.py + - manifests/${IMAGE_NAME}service.yaml + - .gitlab-ci.yml + +## Start Mock QKD Nodes before unit testing +#start_mock_nodes: +# stage: deploy +# script: +# - bash src/tests/tools/mock_qkd_nodes/start.sh & +# - sleep 10 # wait for nodes to spin up +# artifacts: +# paths: +# - mock_nodes.log +# 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"' + +## Prepare Scenario (Start NBI, mock services) +#prepare_scenario: +# stage: deploy +# script: +# - pytest src/tests/qkd/unit/PrepareScenario.py +# needs: +# - start_mock_nodes +# 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"' + +# Apply unit test to the component +unit_test device: + variables: + IMAGE_NAME: 'device' # name of the microservice + IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) + stage: unit_test + needs: + - build device + #- start_mock_nodes + #- prepare_scenario + before_script: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + - > + if docker network list | grep teraflowbridge; then + echo "teraflowbridge is already created"; + else + docker network create -d bridge teraflowbridge; + fi + - > + if docker container ls | grep $IMAGE_NAME; then + docker rm -f $IMAGE_NAME; + else + echo "$IMAGE_NAME image is not in the system"; + fi + script: + - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" + - docker run --name $IMAGE_NAME -d -p 2020:2020 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG + - sleep 5 + - docker ps -a + - docker logs $IMAGE_NAME + - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary_emulated.py --junitxml=/opt/results/${IMAGE_NAME}_report_emulated.xml" + - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary_ietf_actn.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_actn.xml" + #- docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/qkd/unit/test_*.py" + - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing" + coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' + after_script: + - docker rm -f $IMAGE_NAME + - docker network rm teraflowbridge + 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 + - src/$IMAGE_NAME/**/*.{py,in,yml} + - src/$IMAGE_NAME/Dockerfile + - src/$IMAGE_NAME/tests/*.py + - src/$IMAGE_NAME/tests/Dockerfile + - manifests/${IMAGE_NAME}service.yaml + - .gitlab-ci.yml + artifacts: + when: always + reports: + junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report_*.xml + +## Deployment of the service in Kubernetes Cluster +#deploy device: +# variables: +# IMAGE_NAME: 'device' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test device +# # - integ_test execute +# script: +# - 'sed -i "s/$IMAGE_NAME:.*/$IMAGE_NAME:$IMAGE_TAG/" manifests/${IMAGE_NAME}service.yaml' +# - kubectl version +# - kubectl get all +# - kubectl apply -f "manifests/${IMAGE_NAME}service.yaml" +# - kubectl get all +# # environment: +# # name: test +# # url: https://example.com +# # kubernetes: +# # namespace: test +# 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: manual +# - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' +# when: manual diff --git a/src/tapi/Config.py b/src/tapi/Config.py new file mode 100644 index 0000000000000000000000000000000000000000..73c37610dcc7ba6e76760b567f699a8be575b3e3 --- /dev/null +++ b/src/tapi/Config.py @@ -0,0 +1,20 @@ +# 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 os + +TRUE_VALUES = {'T', 'TRUE', 'YES', '1'} +DEVICE_EMULATED_ONLY = os.environ.get('DEVICE_EMULATED_ONLY') +LOAD_ALL_DEVICE_DRIVERS = (DEVICE_EMULATED_ONLY is None) or (DEVICE_EMULATED_ONLY.upper() not in TRUE_VALUES) diff --git a/src/tapi/Dockerfile b/src/tapi/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..384980cafab9feb29228a839acb63aaf1fe4d9ea --- /dev/null +++ b/src/tapi/Dockerfile @@ -0,0 +1,75 @@ +# 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. + +FROM python:3.9-slim + +# Install dependencies +RUN apt-get --yes --quiet --quiet update && \ + apt-get --yes --quiet --quiet install wget g++ git build-essential cmake libpcre2-dev python3-dev python3-cffi && \ + rm -rf /var/lib/apt/lists/* + +# Download, build and install libyang. Note that APT package is outdated +# - Ref: https://github.com/CESNET/libyang +# - Ref: https://github.com/CESNET/libyang-python/ + + +# Set Python to show logs as they occur +ENV PYTHONUNBUFFERED=0 + +# Download the gRPC health probe + + +# Get generic Python packages +RUN python3 -m pip install --upgrade pip +RUN python3 -m pip install --upgrade setuptools wheel +RUN python3 -m pip install --upgrade pip-tools + +# Get common Python packages +# Note: this step enables sharing the previous Docker build steps among all the Python components +WORKDIR /var/teraflow +COPY common_requirements.in common_requirements.in +RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in +RUN python3 -m pip install -r common_requirements.txt + +# Add common files into working directory +WORKDIR /var/teraflow/common +COPY src/common/. ./ +RUN rm -rf proto + +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /var/teraflow/common/proto +WORKDIR /var/teraflow/common/proto +RUN touch __init__.py +COPY proto/*.proto ./ +RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto +RUN rm *.proto +RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \; + +# Create component sub-folders, get specific Python packages +RUN mkdir -p /var/teraflow/tapi +WORKDIR /var/teraflow/tapi +COPY src/tapi/requirements.in requirements.in +RUN pip-compile --quiet --output-file=requirements.txt requirements.in +RUN python3 -m pip install -r requirements.txt + +# Add component files into working directory +WORKDIR /var/teraflow +COPY src/tapi/. tapi/ +COPY src/context/__init__.py context/__init__.py +COPY src/context/client/. context/client/ + +WORKDIR /var/teraflow + +# Start the service +ENTRYPOINT ["python", "-m", "tapi.service"] diff --git a/src/tapi/__init__.py b/src/tapi/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..53d5157f750bfb085125cbd33faff1cec5924e14 --- /dev/null +++ b/src/tapi/__init__.py @@ -0,0 +1,14 @@ +# 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. + diff --git a/src/tapi/client/TapiClient.py b/src/tapi/client/TapiClient.py new file mode 100644 index 0000000000000000000000000000000000000000..e95fc0855f82c82ec3024a53da2167b50f2c6009 --- /dev/null +++ b/src/tapi/client/TapiClient.py @@ -0,0 +1,70 @@ +# 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 grpc, logging +from common.Constants import ServiceNameEnum +from common.Settings import get_service_host, get_service_port_grpc +from common.proto.context_pb2 import ( + Topology, + TopologyList, Empty +) +from common.proto.tapi_pb2 import TapiRequest + +from common.proto.tapi_pb2_grpc import TapiServiceStub + +from common.tools.client.RetryDecorator import retry, delay_exponential +from common.tools.grpc.Tools import grpc_message_to_json_string + +LOGGER = logging.getLogger(__name__) +MAX_RETRIES = 15 +DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) +RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + +class TapiClient: + def __init__(self, host, port): + host = self.host + port = self.port + self.endpoint = '{:s}:{:s}'.format(str(host), str(port)) + LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint))) + self.channel = None + self.stub = None + self.openconfig_stub=None + self.connect() + LOGGER.debug('Channel created') + + def connect(self): + self.channel = grpc.insecure_channel(self.endpoint) + self.stub = TapiServiceStub(self.channel) + + def close(self): + if self.channel is not None: self.channel.close() + self.channel = None + self.stub = None + self.openconfig_stub = None + + @RETRY_DECORATOR + def GetListTopologies(self, request : Empty) -> TopologyList: + LOGGER.debug('GetListTopologies request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.GetListTopologies(request) + LOGGER.debug('GetListTopologies result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def GetTopology(self, request : TapiRequest) -> Topology: + LOGGER.debug('GetTopology request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.GetTopology(request) + LOGGER.debug('GetTopology result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + \ No newline at end of file diff --git a/src/tapi/client/__init__.py b/src/tapi/client/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..53d5157f750bfb085125cbd33faff1cec5924e14 --- /dev/null +++ b/src/tapi/client/__init__.py @@ -0,0 +1,14 @@ +# 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. + diff --git a/src/tapi/requirements.in b/src/tapi/requirements.in new file mode 100644 index 0000000000000000000000000000000000000000..e8449adda3f771cb8438b28b88d89501095f7bb0 --- /dev/null +++ b/src/tapi/requirements.in @@ -0,0 +1,25 @@ +# 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. + +requests==2.27.1 +requests-mock==1.9.3 +tabulate +websockets==12.0 +xmltodict==0.12.0 + +# pip's dependency resolver does not take into account installed packages. +# p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one +# adding here again grpcio==1.47.* and protobuf==3.20.* with explicit versions to prevent collisions +grpcio==1.47.* +protobuf==3.20.* diff --git a/src/tapi/service/TapiService.py b/src/tapi/service/TapiService.py new file mode 100644 index 0000000000000000000000000000000000000000..ef796800f722841395f203e9ca52286bd5fb8504 --- /dev/null +++ b/src/tapi/service/TapiService.py @@ -0,0 +1,46 @@ +# 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 os +from common.Constants import ServiceNameEnum +from common.Settings import get_service_port_grpc +from common.proto.tapi_pb2_grpc import add_TapiServiceServicer_to_server + +from common.tools.service.GenericGrpcService import GenericGrpcService + + +from .TapiServiceServicerImpl import TapiServiceServicerImpl + + +# Custom gRPC settings +# Multiple clients might keep connections alive waiting for RPC methods to be executed. +# Requests needs to be serialized to ensure correct device configurations +GRPC_MAX_WORKERS = 200 + +class TapiService(GenericGrpcService): + def __init__(self, cls_name: str = __name__) -> None: + port = get_service_port_grpc(ServiceNameEnum.TAPI) + super().__init__(port, max_workers=GRPC_MAX_WORKERS, cls_name=cls_name) + + self.tapi_servicer = TapiServiceServicerImpl() + + + def install_servicers(self): + + add_TapiServiceServicer_to_server(self.tapi_servicer, self.server) + + + def stop(self): + super().stop() + diff --git a/src/tapi/service/TapiServiceServicerImpl.py b/src/tapi/service/TapiServiceServicerImpl.py new file mode 100644 index 0000000000000000000000000000000000000000..b5b886d0f215892dd3ed4c5f0e6a6ab628daeb8f --- /dev/null +++ b/src/tapi/service/TapiServiceServicerImpl.py @@ -0,0 +1,80 @@ +# 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 grpc, logging, os, time + + +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method + +from common.proto.context_pb2 import ( + Topology,TopologyList ,TopologyId,Empty +) + +from common.proto.tapi_pb2 import TapiRequest +from common.proto.tapi_pb2_grpc import TapiService + +from common.tools.mutex_queues.MutexQueues import MutexQueues +from context.client.ContextClient import ContextClient + + +LOGGER = logging.getLogger(__name__) + +METRICS_POOL = MetricsPool('Tapi', 'RPC') + +METRICS_POOL_DETAILS = MetricsPool('Tapi', 'execution', labels={ + 'driver': '', 'operation': '', 'step': '', +}) + +class TapiServiceServicerImpl(TapiService): + def __init__(self) -> None: + LOGGER.debug('Creating Servicer...') + + + self.mutex_queues = MutexQueues() + LOGGER.debug('Servicer Created') + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetListTopologies(self, request : Empty, context : grpc.ServicerContext) -> TopologyList: + LOGGER.info("we recieved a request ") + t0 = time.time() + t1 = time.time() + response = [] + topology_list=TopologyList() + + context_client = ContextClient() + context_list = context_client.ListContextIds(Empty()) + context_ids_list = context_list.context_ids + + + try: + for context_id in context_ids_list: + topology_list = context_client.ListTopologies(context_id) + response.append(topology_list) + + + LOGGER.info(f"topologies_list {response}") + return topology_list + + + except Exception as e : + + LOGGER.info(f"error in Tapi servicer {e}") + + + def GetTopology (self ,topology_id:TapiRequest) -> Topology : + + topology = Topology () + + return topology + diff --git a/src/tapi/service/__init__.py b/src/tapi/service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..53d5157f750bfb085125cbd33faff1cec5924e14 --- /dev/null +++ b/src/tapi/service/__init__.py @@ -0,0 +1,14 @@ +# 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. + diff --git a/src/tapi/service/__main__.py b/src/tapi/service/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..dd0d9dd178585f211d56212bd5b57c94e74a37a9 --- /dev/null +++ b/src/tapi/service/__main__.py @@ -0,0 +1,78 @@ +# 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, signal, sys, threading +from prometheus_client import start_http_server +from common.Constants import ServiceNameEnum +from common.Settings import ( + ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, + get_env_var_name, get_log_level, get_metrics_port, + wait_for_environment_variables +) +from .TapiService import TapiService + +terminate = threading.Event() +LOGGER : logging.Logger = None + +def signal_handler(signal, frame): # pylint: disable=redefined-outer-name + LOGGER.warning('Terminate signal received') + terminate.set() + +def main(): + global LOGGER # pylint: disable=global-statement + + log_level = get_log_level() + logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") + logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING) + logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING) + logging.getLogger('monitoring-client').setLevel(logging.WARNING) + LOGGER = logging.getLogger(__name__) + + wait_for_environment_variables([ + get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST ), + get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ]) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + LOGGER.info('Starting...') + + # Start metrics server + metrics_port = get_metrics_port() + start_http_server(metrics_port) + + # Initialize Driver framework + + + # Starting device service + grpc_service = TapiService() + grpc_service.start() + + # Initialize drivers with existing devices in context + LOGGER.info('Pre-loading drivers...') + + + # Wait for Ctrl+C or termination signal + while not terminate.wait(timeout=1.0): pass + + LOGGER.info('Terminating...') + grpc_service.stop() + + + LOGGER.info('Bye') + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/webui/service/__main__.py b/src/webui/service/__main__.py index 6f7954147677045da3db36e487f8ce85c1eac32d..e604b0d9030c436bd07c02d792b22d5be0bd0701 100644 --- a/src/webui/service/__main__.py +++ b/src/webui/service/__main__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import hashlib, sys, logging +import hashlib, sys, logging from prometheus_client import start_http_server from common.Constants import ServiceNameEnum from common.Settings import ( @@ -53,15 +53,17 @@ def main(): web_app_root = get_service_baseurl_http(ServiceNameEnum.WEBUI) debug = get_setting('DEBUG', default=DEBUG) if isinstance(debug, str): debug = (debug.upper() in {'T', '1', 'TRUE'}) - + + + app = create_app(use_config={ 'SECRET_KEY': SECRET_KEY, 'MAX_CONTENT_LENGTH': MAX_CONTENT_LENGTH, 'SESSION_COOKIE_NAME': create_unique_session_cookie_name(), }, web_app_root=web_app_root) app.run(host=host, port=service_port, debug=debug) - - logger.info('Bye') + + logger.info(f'Bye ') return 0 if __name__ == '__main__': diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py index 02e1d28ba4a2f2f334a4cf015368d0a8fb5bb8d2..2e23c28a67956f6a274a8f9c61df1ce2a7deb6ed 100644 --- a/src/webui/service/main/routes.py +++ b/src/webui/service/main/routes.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import base64, json, logging #, re +import base64, json, logging , os #, re from flask import jsonify, redirect, render_template, Blueprint, flash, session, url_for, request from common.proto.context_pb2 import ContextList, Empty, TopologyId, TopologyList from common.tools.descriptor.Loader import DescriptorLoader, compose_notifications @@ -110,6 +110,7 @@ def home(): if descriptor_form.validate_on_submit(): process_descriptors(descriptor_form.descriptors) return redirect(url_for("main.home")) + except Exception as e: # pylint: disable=broad-except LOGGER.exception('Descriptor load failed') flash(f'Descriptor load failed: `{str(e)}`', 'danger') @@ -186,3 +187,16 @@ def debug(): def reset_session(): session.clear() return redirect(url_for("main.home")) + + +@main.get('/add_all') +def add_all(): + current_dir = os.path.dirname(os.path.abspath(__file__)) + file_path = "/home/webui/teraflow/webui/test/all.json" + with open(file_path, 'r') as file: + data = json.load(file) + defescriptor_loader = DescriptorLoader(data, num_workers=10) + results = defescriptor_loader.process() + + return redirect(url_for("main.home")) + diff --git a/src/webui/test/all.json b/src/webui/test/all.json new file mode 100755 index 0000000000000000000000000000000000000000..c78a4f5fae8c057a57fbf55f8d1dbd9e6204f2f4 --- /dev/null +++ b/src/webui/test/all.json @@ -0,0 +1,2071 @@ +{ + "contexts": [ + { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_ids": [], + "service_ids": [] + } + ], + "topologies": [ + { + "topology_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_uuid": {"uuid": "admin"} + }, + "device_ids": [], + "link_ids": [], + "optical_link_ids":[] + } + ], + "devices": [ + { + "device_id": { + "device_uuid": { + "uuid": "T1.1" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2023" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "1" + } + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T1.2" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2023" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "1" + } + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T1.3" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2023" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "1" + } + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2.1" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2024" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "6" + } + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2.3" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2024" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "6" + } + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2.2" + } + }, + "device_type": "optical-transponder", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2024" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "6" + } + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "device_type": "optical-roadm", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2025" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "type":"optical-roadm", + "device_params": { + "name": "default" + + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "2" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "3" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "12" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "13" + } + + ] + } + } + } + ] + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "device_type": "optical-roadm", + "device_drivers": [ + 11 + ], + "device_endpoints": [ + + ], + "device_operational_status": 1, + "device_config": { + "config_rules": [ + { + "action": 1, + "custom": { + "resource_key": "_connect/address", + "resource_value": "10.0.2.4" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/port", + "resource_value": "2026" + } + }, + { + "action": 1, + "custom": { + "resource_key": "_connect/settings", + "resource_value": { + "username": "admin", + "password": "admin", + "force_running": false, + "hostkey_verify": false, + "look_for_keys": false, + "allow_agent": false, + "commit_per_rule": false, + "type":"optical-roadm", + "device_params": { + "name": "default" + }, + "manager_params": { + "timeout": 120 + }, + "endpoints": [ + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "4" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "5" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "14" + }, + { + "sample_types": [ + 101, + 102, + 201, + 202 + ], + "type": "optical", + "uuid": "15" + } + + ] + } + } + } + ] + } + } + ], + "optical_links": [ + { + "name": "T1.1-R1", + "link_id": { + "link_uuid": { + "uuid": "T1.1->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T1.1" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "12" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "1", + "dst_port": "12", + "local_peer_port": "1", + "remote_peer_port": "2", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "T1.2-R1", + "link_id": { + "link_uuid": { + "uuid": "T1.2->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T1.2" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "13" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "1", + "dst_port": "13", + "local_peer_port": "1", + "remote_peer_port": "3", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "T1.3-R1", + "link_id": { + "link_uuid": { + "uuid": "T1.3->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T1.3" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "14" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "1", + "dst_port": "14", + "local_peer_port": "1", + "remote_peer_port": "4", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R1-T1.1", + "link_id": { + "link_uuid": { + "uuid": "R1->T1.1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "2" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T1.1" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "2", + "dst_port": "1", + "local_peer_port": "12", + "remote_peer_port": "1", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R1-T1.2", + "link_id": { + "link_uuid": { + "uuid": "R1->T1.2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "3" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T1.2" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "3", + "dst_port": "1", + "local_peer_port": "13", + "remote_peer_port": "1", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R1-T1.3", + "link_id": { + "link_uuid": { + "uuid": "R1->T1.3" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "4" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T1.3" + } + }, + "endpoint_uuid": { + "uuid": "1" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "4", + "dst_port": "1", + "local_peer_port": "14", + "remote_peer_port": "1", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R1-R2", + "link_id": { + "link_uuid": { + "uuid": "R1->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "101" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "111" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "101", + "dst_port": "111", + "local_peer_port": "111", + "remote_peer_port": "101", + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R2-R1", + "link_id": { + "link_uuid": { + "uuid": "R2->R1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "101" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R1" + } + }, + "endpoint_uuid": { + "uuid": "111" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "101", + "dst_port": "111", + "local_peer_port": "111", + "remote_peer_port": "101", + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "T2.1-R2", + "link_id": { + "link_uuid": { + "uuid": "T2.1->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T2.1" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "12" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "6", + "dst_port": "12", + "local_peer_port": "6", + "remote_peer_port": "2", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "T2.2-R2", + "link_id": { + "link_uuid": { + "uuid": "T2.2->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T2.2" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "13" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "6", + "dst_port": "13", + "local_peer_port": "6", + "remote_peer_port": "3", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "T2.3-R2", + "link_id": { + "link_uuid": { + "uuid": "T2.3->R2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "T2.3" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "14" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "6", + "dst_port": "14", + "local_peer_port": "6", + "remote_peer_port": "4", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R2-T2.1", + "link_id": { + "link_uuid": { + "uuid": "R2->T2.1" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "2" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2.1" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "2", + "dst_port": "6", + "local_peer_port": "12", + "remote_peer_port": "6", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R2-T2.2", + "link_id": { + "link_uuid": { + "uuid": "R1->T2.2" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "3" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2.2" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "3", + "dst_port": "6", + "local_peer_port": "13", + "remote_peer_port": "6", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + }, + { + "name": "R2-T2.3", + "link_id": { + "link_uuid": { + "uuid": "R2->T2.3" + } + }, + "link_endpoint_ids": [ + { + "device_id": { + "device_uuid": { + "uuid": "R2" + } + }, + "endpoint_uuid": { + "uuid": "4" + } + }, + { + "device_id": { + "device_uuid": { + "uuid": "T2.3" + } + }, + "endpoint_uuid": { + "uuid": "6" + } + } + ], + "optical_details": { + "length": 0, + "src_port": "4", + "dst_port": "6", + "local_peer_port": "14", + "remote_peer_port": "6", + "used": false, + "c_slots": { + "1": 1, + "2": 1, + "3": 1, + "4": 1, + "5": 1, + "6": 1, + "7": 1, + "8": 1, + "9": 1, + "10": 1, + "11": 1, + "12": 1, + "13": 1, + "14": 1, + "15": 1, + "16": 1, + "17": 1, + "18": 1, + "19": 1, + "20": 1 + }, + "l_slots": { + "101": 1, + "102": 1, + "103": 1, + "104": 1, + "105": 1, + "106": 1, + "107": 1, + "108": 1, + "109": 1, + "110": 1, + "111": 1, + "112": 1, + "113": 1, + "114": 1, + "115": 1, + "116": 1, + "117": 1, + "118": 1, + "119": 1, + "120": 1 + }, + "s_slots": { + "501": 1, + "502": 1, + "503": 1, + "504": 1, + "505": 1, + "506": 1, + "507": 1, + "508": 1, + "509": 1, + "510": 1, + "511": 1, + "512": 1, + "513": 1, + "514": 1, + "515": 1, + "516": 1, + "517": 1, + "518": 1, + "519": 1, + "520": 1 + } + } + } + ] +} \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000000000000000000000000000000000000..acc58edbf5085bdafc39652ff613a59cf085e757 --- /dev/null +++ b/test.py @@ -0,0 +1,32 @@ +from ncclient import manager + +# Define device connection details +device = { + 'host': '10.0.2.4', # replace with the target device's hostname or IP address + 'port': 2023, # NETCONF default port + 'username': 'admin', # replace with your username + 'password': 'admin', # replace with your password + 'hostkey_verify': False , # disable host key verification (use only for testing) + + "hostkey_verify": False, + "look_for_keys": False, + "allow_agent": False, + + "device_params": { + "name": "default" + }, +} + +# Establish a NETCONF connection +with manager.connect(**device) as m: + print("Connected to the device successfully!") + config = m.get_config(source='running').data_xml + print("Device Configuration:") + print(config) + # Example RPC call to get the device's capabilities + capabilities = m.server_capabilities + for capability in capabilities: + print(capability) + + # Close the connection +