diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 713d893cffe4b88cb9b37d64a860f480c9669008..6a00c6eed58ed2421c20acd90f407bd51893bd34 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,9 +28,10 @@ include: - 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/opticalcentralizedattackdetector/.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/automation/.gitlab-ci.yml' - local: '/src/policy/.gitlab-ci.yml' #- local: '/src/webui/.gitlab-ci.yml' diff --git a/common_requirements.in b/common_requirements.in index cb418f0197f1d18980654c8d00102efd191c67dd..37b70c993e913602f9d5e509d0c887802c5d0b1e 100644 --- a/common_requirements.in +++ b/common_requirements.in @@ -16,6 +16,7 @@ coverage==6.3 grpcio==1.47.* grpcio-health-checking==1.47.* grpcio-tools==1.47.* +grpclib==0.4.4 prettytable==3.5.0 prometheus-client==0.13.0 protobuf==3.20.* diff --git a/deploy/all.sh b/deploy/all.sh index 6f5592cb43a5f214b2536226bb857629ad0c3cf0..9584dd32d121b7f63e7c7f177bf7bee8c287b4c9 100755 --- a/deploy/all.sh +++ b/deploy/all.sh @@ -51,6 +51,12 @@ export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} # If not already set, set the namespace where CockroackDB will be deployed. export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} +# If not already set, set the external port CockroackDB Postgre SQL interface will be exposed to. +export CRDB_EXT_PORT_SQL=${CRDB_EXT_PORT_SQL:-"26257"} + +# If not already set, set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to. +export CRDB_EXT_PORT_HTTP=${CRDB_EXT_PORT_HTTP:-"8081"} + # If not already set, set the database username to be used by Context. export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} @@ -90,6 +96,12 @@ export CRDB_REDEPLOY=${CRDB_REDEPLOY:-""} # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} +# If not already set, set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"} + +# If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"} + # If not already set, disable flag for re-deploying NATS from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS. @@ -101,6 +113,15 @@ export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} +# If not already set, set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL=${QDB_EXT_PORT_SQL:-"8812"} + +# If not already set, set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP=${QDB_EXT_PORT_ILP:-"9009"} + +# If not already set, set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP=${QDB_EXT_PORT_HTTP:-"9000"} + # If not already set, set the database username to be used for QuestDB. export QDB_USERNAME=${QDB_USERNAME:-"admin"} @@ -126,6 +147,15 @@ export QDB_DROP_TABLES_IF_EXIST=${QDB_DROP_TABLES_IF_EXIST:-""} export QDB_REDEPLOY=${QDB_REDEPLOY:-""} +# ----- K8s Observability ------------------------------------------------------ + +# If not already set, set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. +export PROM_EXT_PORT_HTTP=${PROM_EXT_PORT_HTTP:-"9090"} + +# If not already set, set the external port Grafana HTTP Dashboards will be exposed to. +export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} + + ######################################################################################################################## # Automated steps start here ######################################################################################################################## @@ -139,6 +169,9 @@ export QDB_REDEPLOY=${QDB_REDEPLOY:-""} # Deploy QuestDB ./deploy/qdb.sh +# Expose Dashboard +./deploy/expose_dashboard.sh + # Deploy TeraFlowSDN ./deploy/tfs.sh diff --git a/deploy/crdb.sh b/deploy/crdb.sh index 4e8cfe2c399fb0e943c90e5c585f93f0707ca835..5d87adf60bbb3303e9abe9cc17c4a68cbe295370 100755 --- a/deploy/crdb.sh +++ b/deploy/crdb.sh @@ -21,6 +21,12 @@ # If not already set, set the namespace where CockroackDB will be deployed. export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} +# If not already set, set the external port CockroackDB Postgre SQL interface will be exposed to. +export CRDB_EXT_PORT_SQL=${CRDB_EXT_PORT_SQL:-"26257"} + +# If not already set, set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to. +export CRDB_EXT_PORT_HTTP=${CRDB_EXT_PORT_HTTP:-"8081"} + # If not already set, set the database username to be used by Context. export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} @@ -64,7 +70,7 @@ TMP_FOLDER="./tmp" CRDB_MANIFESTS_PATH="manifests/cockroachdb" # Create a tmp folder for files modified during the deployment -TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" +TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${CRDB_NAMESPACE}/manifests" mkdir -p $TMP_MANIFESTS_FOLDER function crdb_deploy_single() { @@ -109,24 +115,23 @@ function crdb_deploy_single() { echo echo "CockroachDB Port Mapping" - echo ">>> Expose CockroachDB SQL port (26257->26257)" - CRDB_SQL_PORT=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') - PATCH='{"data": {"'${CRDB_SQL_PORT}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_SQL_PORT}'"}}' + echo ">>> Expose CockroachDB SQL port (26257->${CRDB_EXT_PORT_SQL})" + CRDB_PORT_SQL=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') + PATCH='{"data": {"'${CRDB_EXT_PORT_SQL}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_PORT_SQL}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${CRDB_SQL_PORT}', "hostPort": '${CRDB_SQL_PORT}'}' + PORT_MAP='{"containerPort": '${CRDB_EXT_PORT_SQL}', "hostPort": '${CRDB_EXT_PORT_SQL}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo - echo ">>> Expose CockroachDB HTTP Mgmt GUI port (8080->8081)" - CRDB_GUI_PORT_EXT="8081" - CRDB_GUI_PORT=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') - PATCH='{"data": {"'${CRDB_GUI_PORT_EXT}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_GUI_PORT}'"}}' + echo ">>> Expose CockroachDB HTTP Mgmt GUI port (8080->${CRDB_EXT_PORT_HTTP})" + CRDB_PORT_HTTP=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') + PATCH='{"data": {"'${CRDB_EXT_PORT_HTTP}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_PORT_HTTP}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${CRDB_GUI_PORT_EXT}', "hostPort": '${CRDB_GUI_PORT_EXT}'}' + PORT_MAP='{"containerPort": '${CRDB_EXT_PORT_HTTP}', "hostPort": '${CRDB_EXT_PORT_HTTP}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" @@ -153,7 +158,8 @@ function crdb_undeploy_single() { function crdb_drop_database_single() { echo "Drop database if exists" - CRDB_CLIENT_URL="postgresql://${CRDB_USERNAME}:${CRDB_PASSWORD}@cockroachdb-0:${CRDB_SQL_PORT}/defaultdb?sslmode=require" + CRDB_PORT_SQL=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') + CRDB_CLIENT_URL="postgresql://${CRDB_USERNAME}:${CRDB_PASSWORD}@cockroachdb-0:${CRDB_PORT_SQL}/defaultdb?sslmode=require" kubectl exec -it --namespace ${CRDB_NAMESPACE} cockroachdb-0 -- \ ./cockroach sql --certs-dir=/cockroach/cockroach-certs --url=${CRDB_CLIENT_URL} \ --execute "DROP DATABASE IF EXISTS ${CRDB_DATABASE};" @@ -161,6 +167,11 @@ function crdb_drop_database_single() { } function crdb_deploy_cluster() { + echo "CockroachDB Operator Namespace" + echo ">>> Create CockroachDB Operator Namespace (if missing)" + kubectl apply -f "${CRDB_MANIFESTS_PATH}/pre_operator.yaml" + echo + echo "Cockroach Operator CRDs" echo ">>> Apply Cockroach Operator CRDs (if they are missing)" cp "${CRDB_MANIFESTS_PATH}/crds.yaml" "${TMP_MANIFESTS_FOLDER}/crdb_crds.yaml" @@ -263,24 +274,23 @@ function crdb_deploy_cluster() { echo echo "CockroachDB Port Mapping" - echo ">>> Expose CockroachDB SQL port (26257)" - CRDB_SQL_PORT=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') - PATCH='{"data": {"'${CRDB_SQL_PORT}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_SQL_PORT}'"}}' + echo ">>> Expose CockroachDB SQL port (26257->${CRDB_EXT_PORT_SQL})" + CRDB_PORT_SQL=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') + PATCH='{"data": {"'${CRDB_EXT_PORT_SQL}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_PORT_SQL}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${CRDB_SQL_PORT}', "hostPort": '${CRDB_SQL_PORT}'}' + PORT_MAP='{"containerPort": '${CRDB_EXT_PORT_SQL}', "hostPort": '${CRDB_EXT_PORT_SQL}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo - echo ">>> Expose CockroachDB HTTP Mgmt GUI port (8080->8081)" - CRDB_GUI_PORT_EXT="8081" - CRDB_GUI_PORT=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') - PATCH='{"data": {"'${CRDB_GUI_PORT_EXT}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_GUI_PORT}'"}}' + echo ">>> Expose CockroachDB HTTP Mgmt GUI port (8080->${CRDB_EXT_PORT_HTTP})" + CRDB_PORT_HTTP=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') + PATCH='{"data": {"'${CRDB_EXT_PORT_HTTP}'": "'${CRDB_NAMESPACE}'/cockroachdb-public:'${CRDB_PORT_HTTP}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${CRDB_GUI_PORT_EXT}', "hostPort": '${CRDB_GUI_PORT_EXT}'}' + PORT_MAP='{"containerPort": '${CRDB_EXT_PORT_HTTP}', "hostPort": '${CRDB_EXT_PORT_HTTP}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" @@ -342,17 +352,23 @@ function crdb_drop_database_cluster() { if [ "$CRDB_DEPLOY_MODE" == "single" ]; then if [ "$CRDB_REDEPLOY" == "YES" ]; then crdb_undeploy_single - elif [ "$CRDB_DROP_DATABASE_IF_EXISTS" == "YES" ]; then - crdb_drop_database_single fi + crdb_deploy_single + + if [ "$CRDB_DROP_DATABASE_IF_EXISTS" == "YES" ]; then + crdb_drop_database_single + fi elif [ "$CRDB_DEPLOY_MODE" == "cluster" ]; then if [ "$CRDB_REDEPLOY" == "YES" ]; then crdb_undeploy_cluster - elif [ "$CRDB_DROP_DATABASE_IF_EXISTS" == "YES" ]; then - crdb_drop_database_cluster fi + crdb_deploy_cluster + + if [ "$CRDB_DROP_DATABASE_IF_EXISTS" == "YES" ]; then + crdb_drop_database_cluster + fi else echo "Unsupported value: CRDB_DEPLOY_MODE=$CRDB_DEPLOY_MODE" fi diff --git a/deploy/expose_dashboard.sh b/deploy/expose_dashboard.sh new file mode 100755 index 0000000000000000000000000000000000000000..60b41c7b75d4f96a22151b1d4d68ba53c75a265c --- /dev/null +++ b/deploy/expose_dashboard.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +######################################################################################################################## +# Read deployment settings +######################################################################################################################## + +# If not already set, set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. +export PROM_EXT_PORT_HTTP=${PROM_EXT_PORT_HTTP:-"9090"} + +# If not already set, set the external port Grafana HTTP Dashboards will be exposed to. +export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} + + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +function expose_dashboard() { + echo "Prometheus Port Mapping" + echo ">>> Expose Prometheus HTTP Mgmt GUI port (9090->${PROM_EXT_PORT_HTTP})" + PROM_PORT_HTTP=$(kubectl --namespace monitoring get service prometheus-k8s -o 'jsonpath={.spec.ports[?(@.name=="web")].port}') + PATCH='{"data": {"'${PROM_EXT_PORT_HTTP}'": "monitoring/prometheus-k8s:'${PROM_PORT_HTTP}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${PROM_EXT_PORT_HTTP}', "hostPort": '${PROM_EXT_PORT_HTTP}'}' + CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' + PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' + kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" + echo + + echo "Grafana Port Mapping" + echo ">>> Expose Grafana HTTP Mgmt GUI port (3000->${GRAF_EXT_PORT_HTTP})" + GRAF_PORT_HTTP=$(kubectl --namespace monitoring get service grafana -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') + PATCH='{"data": {"'${GRAF_EXT_PORT_HTTP}'": "monitoring/grafana:'${GRAF_PORT_HTTP}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${GRAF_EXT_PORT_HTTP}', "hostPort": '${GRAF_EXT_PORT_HTTP}'}' + CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' + PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' + kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" + echo +} + +expose_dashboard diff --git a/deploy/nats.sh b/deploy/nats.sh index 9edbc7765a09135d62a6021c5f2b0669e36a69a4..b730cec4af66920e5a7d8a2235e63beff70e8694 100755 --- a/deploy/nats.sh +++ b/deploy/nats.sh @@ -21,6 +21,12 @@ # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} +# If not already set, set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"} + +# If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"} + # If not already set, disable flag for re-deploying NATS from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS. @@ -43,14 +49,14 @@ function nats_deploy_single() { echo "Install NATS (single-node)" echo ">>> Checking if NATS is deployed..." - if kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; then + if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then echo ">>> NATS is present; skipping step." else echo ">>> Deploy NATS" - helm3 install nats nats/nats --namespace ${NATS_NAMESPACE} --set nats.image.tag=2.9-alpine + helm3 install ${NATS_NAMESPACE} nats/nats --namespace ${NATS_NAMESPACE} --set nats.image=nats:2.9-alpine echo ">>> Waiting NATS statefulset to be created..." - while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; do + while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; do printf "%c" "." sleep 1 done @@ -64,32 +70,32 @@ function nats_deploy_single() { #kubectl wait --namespace ${NATS_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ # statefulset/nats echo ">>> NATS statefulset created. Waiting NATS pods to be created..." - while ! kubectl get --namespace ${NATS_NAMESPACE} pod/nats-0 &> /dev/null; do + while ! kubectl get --namespace ${NATS_NAMESPACE} pod/${NATS_NAMESPACE}-0 &> /dev/null; do printf "%c" "." sleep 1 done - kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/nats-0 + kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/${NATS_NAMESPACE}-0 fi echo echo "NATS Port Mapping" - echo ">>> Expose NATS Client port (4222)" - NATS_CLIENT_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service nats -o 'jsonpath={.spec.ports[?(@.name=="client")].port}') - PATCH='{"data": {"'${NATS_CLIENT_PORT}'": "'${NATS_NAMESPACE}'/nats:'${NATS_CLIENT_PORT}'"}}' + echo ">>> Expose NATS Client port (4222->${NATS_EXT_PORT_CLIENT})" + NATS_PORT_CLIENT=$(kubectl --namespace ${NATS_NAMESPACE} get service ${NATS_NAMESPACE} -o 'jsonpath={.spec.ports[?(@.name=="client")].port}') + PATCH='{"data": {"'${NATS_EXT_PORT_CLIENT}'": "'${NATS_NAMESPACE}'/'${NATS_NAMESPACE}':'${NATS_PORT_CLIENT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${NATS_CLIENT_PORT}', "hostPort": '${NATS_CLIENT_PORT}'}' + PORT_MAP='{"containerPort": '${NATS_EXT_PORT_CLIENT}', "hostPort": '${NATS_EXT_PORT_CLIENT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo - echo ">>> Expose NATS HTTP Mgmt GUI port (8222)" - NATS_GUI_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service nats -o 'jsonpath={.spec.ports[?(@.name=="monitor")].port}') - PATCH='{"data": {"'${NATS_GUI_PORT}'": "'${NATS_NAMESPACE}'/nats:'${NATS_GUI_PORT}'"}}' + echo ">>> Expose NATS HTTP Mgmt GUI port (8222->${NATS_EXT_PORT_HTTP})" + NATS_PORT_HTTP=$(kubectl --namespace ${NATS_NAMESPACE} get service ${NATS_NAMESPACE} -o 'jsonpath={.spec.ports[?(@.name=="monitor")].port}') + PATCH='{"data": {"'${NATS_EXT_PORT_HTTP}'": "'${NATS_NAMESPACE}'/'${NATS_NAMESPACE}':'${NATS_PORT_HTTP}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${NATS_GUI_PORT}', "hostPort": '${NATS_GUI_PORT}'}' + PORT_MAP='{"containerPort": '${NATS_EXT_PORT_HTTP}', "hostPort": '${NATS_EXT_PORT_HTTP}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" @@ -99,9 +105,9 @@ function nats_deploy_single() { function nats_undeploy_single() { echo "NATS" echo ">>> Checking if NATS is deployed..." - if kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; then + if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then echo ">>> Undeploy NATS" - helm3 uninstall --namespace ${NATS_NAMESPACE} nats + helm3 uninstall --namespace ${NATS_NAMESPACE} ${NATS_NAMESPACE} else echo ">>> NATS is not present; skipping step." fi diff --git a/deploy/qdb.sh b/deploy/qdb.sh index d94c000bf8d40c72faa255e7c6554926b6f683d3..e930b5a6cfdba8897ec138e97e3115da8917554f 100755 --- a/deploy/qdb.sh +++ b/deploy/qdb.sh @@ -21,6 +21,15 @@ # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} +# If not already set, set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL=${QDB_EXT_PORT_SQL:-"8812"} + +# If not already set, set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP=${QDB_EXT_PORT_ILP:-"9009"} + +# If not already set, set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP=${QDB_EXT_PORT_HTTP:-"9000"} + # If not already set, set the database username to be used for QuestDB. export QDB_USERNAME=${QDB_USERNAME:-"admin"} @@ -55,12 +64,14 @@ TMP_FOLDER="./tmp" QDB_MANIFESTS_PATH="manifests/questdb" # Create a tmp folder for files modified during the deployment -TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" +TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${QDB_NAMESPACE}/manifests" +mkdir -p $TMP_MANIFESTS_FOLDER function qdb_deploy() { echo "QuestDB Namespace" echo ">>> Create QuestDB Namespace (if missing)" kubectl create namespace ${QDB_NAMESPACE} + sleep 2 echo echo "QuestDB" @@ -96,34 +107,34 @@ function qdb_deploy() { echo echo "QuestDB Port Mapping" - echo ">>> Expose QuestDB SQL port (8812->8812)" - QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') - PATCH='{"data": {"'${QDB_SQL_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_SQL_PORT}'"}}' + echo ">>> Expose QuestDB SQL port (8812->${QDB_EXT_PORT_SQL})" + QDB_PORT_SQL=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') + PATCH='{"data": {"'${QDB_EXT_PORT_SQL}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_PORT_SQL}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${QDB_SQL_PORT}', "hostPort": '${QDB_SQL_PORT}'}' + PORT_MAP='{"containerPort": '${QDB_EXT_PORT_SQL}', "hostPort": '${QDB_EXT_PORT_SQL}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo - echo ">>> Expose QuestDB Influx Line Protocol port (9009->9009)" - QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') - PATCH='{"data": {"'${QDB_ILP_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_ILP_PORT}'"}}' + echo ">>> Expose QuestDB Influx Line Protocol port (9009->${QDB_EXT_PORT_ILP})" + QDB_PORT_ILP=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') + PATCH='{"data": {"'${QDB_EXT_PORT_ILP}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_PORT_ILP}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${QDB_ILP_PORT}', "hostPort": '${QDB_ILP_PORT}'}' + PORT_MAP='{"containerPort": '${QDB_EXT_PORT_ILP}', "hostPort": '${QDB_EXT_PORT_ILP}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo - echo ">>> Expose QuestDB HTTP Mgmt GUI port (9000->9000)" - QDB_GUI_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') - PATCH='{"data": {"'${QDB_GUI_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_GUI_PORT}'"}}' + echo ">>> Expose QuestDB HTTP Mgmt GUI port (9000->${QDB_EXT_PORT_HTTP})" + QDB_PORT_HTTP=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') + PATCH='{"data": {"'${QDB_EXT_PORT_HTTP}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_PORT_HTTP}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - PORT_MAP='{"containerPort": '${QDB_GUI_PORT}', "hostPort": '${QDB_GUI_PORT}'}' + PORT_MAP='{"containerPort": '${QDB_EXT_PORT_HTTP}', "hostPort": '${QDB_EXT_PORT_HTTP}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" @@ -161,7 +172,10 @@ function qdb_drop_tables() { if [ "$QDB_REDEPLOY" == "YES" ]; then qdb_undeploy -elif [ "$QDB_DROP_TABLES_IF_EXIST" == "YES" ]; then - qdb_drop_tables fi + qdb_deploy + +if [ "$QDB_DROP_TABLES_IF_EXIST" == "YES" ]; then + qdb_drop_tables +fi diff --git a/deploy/tfs.sh b/deploy/tfs.sh index 16cf5c13bd4532aac0267b7904c6c403d7ac057c..e6a0c0c1053b69462a0e60c6b6cebe28a7dc59af 100755 --- a/deploy/tfs.sh +++ b/deploy/tfs.sh @@ -51,6 +51,12 @@ export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} # If not already set, set the namespace where CockroackDB will be deployed. export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} +# If not already set, set the external port CockroackDB Postgre SQL interface will be exposed to. +export CRDB_EXT_PORT_SQL=${CRDB_EXT_PORT_SQL:-"26257"} + +# If not already set, set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to. +export CRDB_EXT_PORT_HTTP=${CRDB_EXT_PORT_HTTP:-"8081"} + # If not already set, set the database username to be used by Context. export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} @@ -66,12 +72,27 @@ export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"} # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} +# If not already set, set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"} + +# If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"} + # ----- QuestDB ---------------------------------------------------------------- # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} +# If not already set, set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL=${QDB_EXT_PORT_SQL:-"8812"} + +# If not already set, set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP=${QDB_EXT_PORT_ILP:-"9009"} + +# If not already set, set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP=${QDB_EXT_PORT_HTTP:-"9000"} + # If not already set, set the database username to be used for QuestDB. export QDB_USERNAME=${QDB_USERNAME:-"admin"} @@ -85,6 +106,15 @@ export QDB_TABLE_MONITORING_KPIS=${QDB_TABLE_MONITORING_KPIS:-"tfs_monitoring_kp export QDB_TABLE_SLICE_GROUPS=${QDB_TABLE_SLICE_GROUPS:-"tfs_slice_groups"} +# ----- K8s Observability ------------------------------------------------------ + +# If not already set, set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. +export PROM_EXT_PORT_HTTP=${PROM_EXT_PORT_HTTP:-"9090"} + +# If not already set, set the external port Grafana HTTP Dashboards will be exposed to. +export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} + + ######################################################################################################################## # Automated steps start here ######################################################################################################################## @@ -94,14 +124,15 @@ GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller" TMP_FOLDER="./tmp" # Create a tmp folder for files modified during the deployment -TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" +TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${TFS_K8S_NAMESPACE}/manifests" mkdir -p $TMP_MANIFESTS_FOLDER -TMP_LOGS_FOLDER="$TMP_FOLDER/logs" +TMP_LOGS_FOLDER="${TMP_FOLDER}/${TFS_K8S_NAMESPACE}/logs" mkdir -p $TMP_LOGS_FOLDER echo "Deleting and Creating a new namespace..." kubectl delete namespace $TFS_K8S_NAMESPACE --ignore-not-found kubectl create namespace $TFS_K8S_NAMESPACE +sleep 2 printf "\n" echo "Create secret with CockroachDB data" @@ -116,7 +147,7 @@ kubectl create secret generic crdb-data --namespace ${TFS_K8S_NAMESPACE} --type= printf "\n" echo "Create secret with NATS data" -NATS_CLIENT_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service nats -o 'jsonpath={.spec.ports[?(@.name=="client")].port}') +NATS_CLIENT_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service ${NATS_NAMESPACE} -o 'jsonpath={.spec.ports[?(@.name=="client")].port}') kubectl create secret generic nats-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \ --from-literal=NATS_NAMESPACE=${NATS_NAMESPACE} \ --from-literal=NATS_CLIENT_PORT=${NATS_CLIENT_PORT} @@ -145,6 +176,14 @@ echo "# Environment variables for TeraFlowSDN deployment" > $ENV_VARS_SCRIPT PYTHONPATH=$(pwd)/src echo "export PYTHONPATH=${PYTHONPATH}" >> $ENV_VARS_SCRIPT +echo "Create Redis secret..." +# first try to delete an old one if exists +kubectl delete secret redis-secrets --namespace=$TFS_K8S_NAMESPACE --ignore-not-found +REDIS_PASSWORD=`uuidgen` +kubectl create secret generic redis-secrets --namespace=$TFS_K8S_NAMESPACE \ + --from-literal=REDIS_PASSWORD=$REDIS_PASSWORD +echo "export REDIS_PASSWORD=${REDIS_PASSWORD}" >> $ENV_VARS_SCRIPT + for COMPONENT in $TFS_COMPONENTS; do echo "Processing '$COMPONENT' component..." @@ -220,7 +259,8 @@ for COMPONENT in $TFS_COMPONENTS; do echo " Adapting '$COMPONENT' manifest file..." MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml" - cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST" + # cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST" + cat ./manifests/"${COMPONENT}"service.yaml | linkerd inject - --proxy-cpu-request "10m" --proxy-cpu-limit "1" --proxy-memory-request "64Mi" --proxy-memory-limit "256Mi" > "$MANIFEST" if [ "$COMPONENT" == "pathcomp" ]; then IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') @@ -303,14 +343,18 @@ for COMPONENT in $TFS_COMPONENTS; do printf "\n" done -if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then +if [[ "$TFS_COMPONENTS" == *"webui"* ]]; then echo "Configuring WebUI DataStores and Dashboards..." sleep 5 + INGRESS_CTRL_NAME=$(echo "${TFS_K8S_NAMESPACE}" | sed "s/tfs/nginx-ingress-microk8s-controller/g") + EXT_HTTP_PORT=$(kubectl get daemonsets.apps --namespace ingress ${INGRESS_CTRL_NAME} \ + -o 'jsonpath={.spec.template.spec.containers[?(@.name=="nginx-ingress-microk8s")].ports[?(@.name=="http")].hostPort}') + # Exposed through the ingress controller "tfs-ingress" - GRAFANA_URL="127.0.0.1:80/grafana" + GRAFANA_URL="127.0.0.1:${EXT_HTTP_PORT}/grafana" - # Default Grafana credentials + # Default Grafana credentials when installed with the `monitoring` addon GRAFANA_USERNAME="admin" GRAFANA_PASSWORD="admin" @@ -387,25 +431,118 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" }, "secureJsonData": {"password": "'${QDB_PASSWORD}'"} }' ${GRAFANA_URL_UPDATED}/api/datasources + echo + + curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{ + "access" : "proxy", + "type" : "postgres", + "name" : "cockroachdb", + "url" : "'cockroachdb-public.${CRDB_NAMESPACE}.svc.cluster.local:${CRDB_SQL_PORT}'", + "database" : "'${CRDB_DATABASE}'", + "user" : "'${CRDB_USERNAME}'", + "basicAuth": false, + "isDefault": false, + "jsonData" : { + "sslmode" : "require", + "postgresVersion" : 1100, + "maxOpenConns" : 0, + "maxIdleConns" : 2, + "connMaxLifetime" : 14400, + "tlsAuth" : false, + "tlsAuthWithCACert" : false, + "timescaledb" : false, + "tlsConfigurationMethod": "file-path", + "tlsSkipVerify" : true + }, + "secureJsonData": {"password": "'${CRDB_PASSWORD}'"} + }' ${GRAFANA_URL_UPDATED}/api/datasources + echo + + # adding the datasource of the metrics collection framework + curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{ + "access" : "proxy", + "type" : "prometheus", + "name" : "prometheus", + "url" : "http://prometheus-k8s.monitoring.svc:9090", + "basicAuth": false, + "isDefault": false, + "jsonData" : { + "httpMethod" : "POST" + } + }' ${GRAFANA_URL_UPDATED}/api/datasources printf "\n\n" - echo ">> Creating dashboards..." + echo ">> Creating and staring dashboards..." # Ref: https://grafana.com/docs/grafana/latest/http_api/dashboard/ + + # Dashboard: L3 Monitoring KPIs curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_db_mon_kpis_psql.json' \ ${GRAFANA_URL_UPDATED}/api/dashboards/db echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-l3-monit" + DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') + curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} + echo + # Dashboard: Slice Grouping curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_db_slc_grps_psql.json' \ ${GRAFANA_URL_UPDATED}/api/dashboards/db - printf "\n\n" + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-slice-grps" + DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') + curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} + echo - echo ">> Staring dashboards..." - DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-l3-monit" + # Dashboard: Component RPCs + curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_prom_component_rpc.json' \ + ${GRAFANA_URL_UPDATED}/api/dashboards/db + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-comp-rpc" DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} echo - DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-slice-grps" + # Dashboard: Device Drivers + curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_prom_device_driver.json' \ + ${GRAFANA_URL_UPDATED}/api/dashboards/db + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-dev-drv" + DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') + curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} + echo + + # Dashboard: Service Handlers + curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_prom_service_handler.json' \ + ${GRAFANA_URL_UPDATED}/api/dashboards/db + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-svc-hdlr" + DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') + curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} + echo + + # Dashboard: Device Execution Details + curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_prom_device_exec_details.json' \ + ${GRAFANA_URL_UPDATED}/api/dashboards/db + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-dev-exec" + DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') + curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} + echo + + # Dashboard: Load Generator Status + curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_prom_load_generator.json' \ + ${GRAFANA_URL_UPDATED}/api/dashboards/db + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-loadgen-stats" + DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') + curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} + echo + + # Dashboard: Load Generator Status + curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_prom_tfs_num_pods.json' \ + ${GRAFANA_URL_UPDATED}/api/dashboards/db + echo + DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-num-pods" DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id') curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID} echo diff --git a/expose_ingress_grpc.sh b/expose_ingress_grpc.sh index 945641c1f3b6ae981685a2a257260b14ceb927b2..2bc0fd64b60cafdfad92b3d8d031cd28d7d6a873 100755 --- a/expose_ingress_grpc.sh +++ b/expose_ingress_grpc.sh @@ -21,7 +21,7 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # If not already set, set the list of components you want to build images for, and deploy. -export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device automation policy service compute monitoring dbscanserving opticalattackmitigator opticalcentralizedattackdetector webui"} +export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device automation policy service compute monitoring dbscanserving opticalattackmitigator opticalcentralizedattackdetector l3_attackmitigator l3_centralizedattackdetector webui"} ######################################################################################################################## # Automated steps start here diff --git a/manifests/automationservice.yaml b/manifests/automationservice.yaml deleted file mode 120000 index 5e8d3c1c82db0c03119f29865e2a7edabcdfb0eb..0000000000000000000000000000000000000000 --- a/manifests/automationservice.yaml +++ /dev/null @@ -1 +0,0 @@ -../src/automation/target/kubernetes/kubernetes.yml \ No newline at end of file diff --git a/manifests/automationservice.yaml b/manifests/automationservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..73e6b1d7be076dbcf55014ae3accbc1e29e0c8e8 --- /dev/null +++ b/manifests/automationservice.yaml @@ -0,0 +1,125 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: Service +metadata: + annotations: + app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000 + labels: + app.kubernetes.io/name: automationservice + app: automationservice + name: automationservice +spec: + ports: + - name: grpc + port: 5050 + targetPort: 5050 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 8080 + selector: + app.kubernetes.io/name: automationservice + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000 + labels: + app: automationservice + app.kubernetes.io/name: automationservice + name: automationservice +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: automationservice + template: + metadata: + annotations: + app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000 + labels: + app: automationservice + app.kubernetes.io/name: automationservice + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CONTEXT_SERVICE_HOST + value: contextservice + - name: DEVICE_SERVICE_HOST + value: deviceservice + image: labs.etsi.org:5050/tfs/controller/automation:0.2.0 + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /q/health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 2 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: automationservice + ports: + - containerPort: 5050 + name: grpc + protocol: TCP + - containerPort: 8080 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /q/health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 2 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + resources: + requests: + cpu: 50m + memory: 512Mi + limits: + cpu: 500m + memory: 2048Mi +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: automationservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: automationservice + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 diff --git a/manifests/cachingservice.yaml b/manifests/cachingservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..be8fced491a823aace2b7e06be3aad1f6114d245 --- /dev/null +++ b/manifests/cachingservice.yaml @@ -0,0 +1,64 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: cachingservice +spec: + selector: + matchLabels: + app: cachingservice + template: + metadata: + labels: + app: cachingservice + spec: + containers: + - name: redis + image: redis:7.0-alpine + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-secrets + key: REDIS_PASSWORD + ports: + - containerPort: 6379 + name: client + command: ["redis-server"] + args: + - --requirepass + - $(REDIS_PASSWORD) + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 500m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: cachingservice +spec: + type: ClusterIP + selector: + app: cachingservice + ports: + - name: redis + port: 6379 + targetPort: 6379 diff --git a/manifests/cockroachdb/client-secure-operator.yaml b/manifests/cockroachdb/client-secure-operator.yaml index f7f81c8339d4ba47722a0ef2a2236178f1b9e1b0..ee3afbc5ae5feec673dc5f507f8bc794757818c7 100644 --- a/manifests/cockroachdb/client-secure-operator.yaml +++ b/manifests/cockroachdb/client-secure-operator.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 The Cockroach Authors +# Copyright 2023 The Cockroach Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ spec: serviceAccountName: cockroachdb-sa containers: - name: cockroachdb-client-secure - image: cockroachdb/cockroach:v22.2.0 + image: cockroachdb/cockroach:v22.2.8 imagePullPolicy: IfNotPresent volumeMounts: - name: client-certs diff --git a/manifests/cockroachdb/cluster.yaml b/manifests/cockroachdb/cluster.yaml index f7444c0067cc9c2c07b53c85d765bb81d1c20c05..4d9ef0f844b5ffb02753b6cc7a7be7d03928896c 100644 --- a/manifests/cockroachdb/cluster.yaml +++ b/manifests/cockroachdb/cluster.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 The Cockroach Authors +# Copyright 2023 The Cockroach Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,16 +33,16 @@ spec: resources: requests: # This is intentionally low to make it work on local k3d clusters. - cpu: 100m - memory: 1Gi - limits: - cpu: 1 + cpu: 4 memory: 4Gi + limits: + cpu: 8 + memory: 8Gi tlsEnabled: true # You can set either a version of the db or a specific image name -# cockroachDBVersion: v22.2.0 +# cockroachDBVersion: v22.2.8 image: - name: cockroachdb/cockroach:v22.2.0 + name: cockroachdb/cockroach:v22.2.8 # nodes refers to the number of crdb pods that are created # via the statefulset nodes: 3 diff --git a/manifests/cockroachdb/crds.yaml b/manifests/cockroachdb/crds.yaml index 1b5cd89ae7001b3e200c0de7da240b660c461f3b..2ef9983924f639a82d2091907384be18e6c8c1f4 100644 --- a/manifests/cockroachdb/crds.yaml +++ b/manifests/cockroachdb/crds.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 The Cockroach Authors +# Copyright 2023 The Cockroach Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -354,10 +354,71 @@ spec: The requirements are ANDed. type: object type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is alpha-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" items: type: string type: array @@ -449,10 +510,66 @@ spec: requirements are ANDed. type: object type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + This field is alpha-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object namespaces: - description: namespaces specifies which namespaces the - labelSelector applies to (matches against); null or - empty list means "this pod's namespace" + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace" items: type: string type: array @@ -546,10 +663,71 @@ spec: The requirements are ANDed. type: object type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is alpha-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" items: type: string type: array @@ -641,10 +819,66 @@ spec: requirements are ANDed. type: object type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + This field is alpha-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object namespaces: - description: namespaces specifies which namespaces the - labelSelector applies to (matches against); null or - empty list means "this pod's namespace" + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace" items: type: string type: array @@ -767,7 +1001,7 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object requests: additionalProperties: @@ -780,7 +1014,7 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: @@ -1138,7 +1372,7 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object requests: additionalProperties: @@ -1150,7 +1384,7 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sqlPort: diff --git a/manifests/cockroachdb/operator.yaml b/manifests/cockroachdb/operator.yaml index 2be72d329b48bc6f45d66f811c299140cda85e27..59d515061c4c0f253523aab803653b3f33007461 100644 --- a/manifests/cockroachdb/operator.yaml +++ b/manifests/cockroachdb/operator.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 The Cockroach Authors +# Copyright 2023 The Cockroach Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -538,8 +538,34 @@ spec: value: cockroachdb/cockroach:v22.1.11 - name: RELATED_IMAGE_COCKROACH_v22_1_12 value: cockroachdb/cockroach:v22.1.12 + - name: RELATED_IMAGE_COCKROACH_v22_1_13 + value: cockroachdb/cockroach:v22.1.13 + - name: RELATED_IMAGE_COCKROACH_v22_1_14 + value: cockroachdb/cockroach:v22.1.14 + - name: RELATED_IMAGE_COCKROACH_v22_1_15 + value: cockroachdb/cockroach:v22.1.15 + - name: RELATED_IMAGE_COCKROACH_v22_1_16 + value: cockroachdb/cockroach:v22.1.16 + - name: RELATED_IMAGE_COCKROACH_v22_1_18 + value: cockroachdb/cockroach:v22.1.18 - name: RELATED_IMAGE_COCKROACH_v22_2_0 value: cockroachdb/cockroach:v22.2.0 + - name: RELATED_IMAGE_COCKROACH_v22_2_1 + value: cockroachdb/cockroach:v22.2.1 + - name: RELATED_IMAGE_COCKROACH_v22_2_2 + value: cockroachdb/cockroach:v22.2.2 + - name: RELATED_IMAGE_COCKROACH_v22_2_3 + value: cockroachdb/cockroach:v22.2.3 + - name: RELATED_IMAGE_COCKROACH_v22_2_4 + value: cockroachdb/cockroach:v22.2.4 + - name: RELATED_IMAGE_COCKROACH_v22_2_5 + value: cockroachdb/cockroach:v22.2.5 + - name: RELATED_IMAGE_COCKROACH_v22_2_6 + value: cockroachdb/cockroach:v22.2.6 + - name: RELATED_IMAGE_COCKROACH_v22_2_7 + value: cockroachdb/cockroach:v22.2.7 + - name: RELATED_IMAGE_COCKROACH_v22_2_8 + value: cockroachdb/cockroach:v22.2.8 - name: OPERATOR_NAME value: cockroachdb - name: WATCH_NAMESPACE @@ -552,7 +578,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: cockroachdb/cockroach-operator:v2.9.0 + image: cockroachdb/cockroach-operator:v2.10.0 imagePullPolicy: IfNotPresent name: cockroach-operator resources: diff --git a/manifests/cockroachdb/pre_operator.yaml b/manifests/cockroachdb/pre_operator.yaml new file mode 100644 index 0000000000000000000000000000000000000000..16718a77918491170502a5cbb864a6fda39c734a --- /dev/null +++ b/manifests/cockroachdb/pre_operator.yaml @@ -0,0 +1,19 @@ +# Copyright 2022 The Cockroach Authors +# +# 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 +# +# https://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: v1 +kind: Namespace +metadata: + labels: + control-plane: cockroach-operator + name: cockroach-operator-system diff --git a/manifests/cockroachdb/single-node.yaml b/manifests/cockroachdb/single-node.yaml index 72454a0904fa70b6b4062dae8ef7e2e5d8625648..20d7e18c69a9eb75bcb70c9123455926d41eebc6 100644 --- a/manifests/cockroachdb/single-node.yaml +++ b/manifests/cockroachdb/single-node.yaml @@ -61,6 +61,7 @@ spec: containers: - name: cockroachdb image: cockroachdb/cockroach:latest-v22.2 + imagePullPolicy: Always args: - start-single-node ports: diff --git a/manifests/computeservice.yaml b/manifests/computeservice.yaml index 7e40ef988bc7dcb77960b224dfe5626ee95cfdfb..3e3b041ab20968ad0010eb06f7900faa7b649dc9 100644 --- a/manifests/computeservice.yaml +++ b/manifests/computeservice.yaml @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: computeservice + replicas: 1 template: metadata: labels: @@ -33,6 +34,7 @@ spec: ports: - containerPort: 8080 - containerPort: 9090 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -44,16 +46,18 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:9090"] resources: requests: - cpu: 250m - memory: 512Mi + cpu: 50m + memory: 64Mi limits: - cpu: 700m - memory: 1024Mi + cpu: 500m + memory: 512Mi --- apiVersion: v1 kind: Service metadata: name: computeservice + labels: + app: computeservice spec: type: ClusterIP selector: @@ -67,3 +71,7 @@ spec: protocol: TCP port: 9090 targetPort: 9090 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/manifests/contextservice.yaml b/manifests/contextservice.yaml index b1e6eb89dc4ec92409dbd05bbe668987ea93828f..96735bf5f89f682f31131c123ee9884a1becbfdb 100644 --- a/manifests/contextservice.yaml +++ b/manifests/contextservice.yaml @@ -20,9 +20,11 @@ spec: selector: matchLabels: app: contextservice - replicas: 1 + #replicas: 1 template: metadata: + annotations: + config.linkerd.io/skip-outbound-ports: "4222" labels: app: contextservice spec: @@ -52,11 +54,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:1010"] resources: requests: - cpu: 50m - memory: 64Mi + cpu: 250m + memory: 128Mi limits: - cpu: 500m - memory: 512Mi + cpu: 1000m + memory: 1024Mi --- apiVersion: v1 kind: Service @@ -77,3 +79,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: contextservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: contextservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/dbscanservingservice.yaml b/manifests/dbscanservingservice.yaml index ae920143454da2c63bccc6eb74ea75670bad6eff..b5b8fc437a9b7f47f92defdbc96ee71a56715316 100644 --- a/manifests/dbscanservingservice.yaml +++ b/manifests/dbscanservingservice.yaml @@ -31,33 +31,61 @@ spec: image: labs.etsi.org:5050/tfs/controller/dbscanserving:latest imagePullPolicy: Always ports: - - containerPort: 10006 + - containerPort: 10008 + - containerPort: 9192 env: - name: LOG_LEVEL - value: "DEBUG" + value: "INFO" readinessProbe: exec: - command: ["/bin/grpc_health_probe", "-addr=:10006"] + command: ["/bin/grpc_health_probe", "-addr=:10008"] livenessProbe: exec: - command: ["/bin/grpc_health_probe", "-addr=:10006"] + command: ["/bin/grpc_health_probe", "-addr=:10008"] resources: requests: cpu: 250m - memory: 512Mi + memory: 128Mi limits: - cpu: 700m + cpu: 1000m memory: 1024Mi --- apiVersion: v1 kind: Service metadata: name: dbscanservingservice + labels: + app: dbscanservingservice spec: type: ClusterIP selector: app: dbscanservingservice ports: - name: grpc - port: 10006 - targetPort: 10006 + port: 10008 + targetPort: 10008 + - name: metrics + port: 9192 + targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: dbscanservingservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: dbscanservingservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml index ddcc997cd9a23c99fae4001e3594957f867b3061..3892129e926a5154c3db59928a1cf5b806b4f115 100644 --- a/manifests/deviceservice.yaml +++ b/manifests/deviceservice.yaml @@ -23,6 +23,9 @@ spec: replicas: 1 template: metadata: + annotations: + # Required for IETF L2VPN SBI when both parent and child run in same K8s cluster with Linkerd + config.linkerd.io/skip-outbound-ports: "8002" labels: app: deviceservice spec: @@ -45,11 +48,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:2020"] resources: requests: - cpu: 50m - memory: 64Mi + cpu: 250m + memory: 128Mi limits: - cpu: 500m - memory: 512Mi + cpu: 1000m + memory: 1024Mi --- apiVersion: v1 kind: Service diff --git a/manifests/interdomainservice.yaml b/manifests/interdomainservice.yaml index 79acf96def508837fd0b3def816d3e4c4e20a368..067f9432749f7d2c986503b034e55a13c8f2b210 100644 --- a/manifests/interdomainservice.yaml +++ b/manifests/interdomainservice.yaml @@ -44,11 +44,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:10010"] resources: requests: - cpu: 50m + cpu: 250m memory: 64Mi limits: - cpu: 500m - memory: 512Mi + cpu: 1000m + memory: 1024Mi --- apiVersion: v1 kind: Service diff --git a/manifests/l3_attackmitigatorservice.yaml b/manifests/l3_attackmitigatorservice.yaml index dec1bc4d936a9db5758679691f0fb130a5d67324..ee97d2c92abb5abcad80f8ddf04800ef13144522 100644 --- a/manifests/l3_attackmitigatorservice.yaml +++ b/manifests/l3_attackmitigatorservice.yaml @@ -32,6 +32,7 @@ spec: imagePullPolicy: Always ports: - containerPort: 10002 + - containerPort: 9192 env: - name: LOG_LEVEL value: "DEBUG" @@ -53,11 +54,69 @@ apiVersion: v1 kind: Service metadata: name: l3-attackmitigatorservice + labels: + app: l3-attackmitigatorservice spec: type: ClusterIP selector: app: l3-attackmitigatorservice ports: + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 - name: grpc port: 10002 targetPort: 10002 + +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: l3-attackmitigatorservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: l3-attackmitigatorservice + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 120 + +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: tfs-l3-attackmitigatorservice-metric + labels: + app: l3-attackmitigatorservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: l3-attackmitigatorservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running diff --git a/manifests/l3_centralizedattackdetectorservice.yaml b/manifests/l3_centralizedattackdetectorservice.yaml index 0ef23ba512ac5397203baa4195ceebe17cf6c743..594e21f4dbb1b10e1d859053c33785e2e59e4b46 100644 --- a/manifests/l3_centralizedattackdetectorservice.yaml +++ b/manifests/l3_centralizedattackdetectorservice.yaml @@ -32,6 +32,7 @@ spec: imagePullPolicy: Always ports: - containerPort: 10001 + - containerPort: 9192 env: - name: LOG_LEVEL value: "DEBUG" @@ -53,11 +54,68 @@ apiVersion: v1 kind: Service metadata: name: l3-centralizedattackdetectorservice + labels: + app: l3-centralizedattackdetectorservice spec: type: ClusterIP selector: app: l3-centralizedattackdetectorservice ports: + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 - name: grpc port: 10001 targetPort: 10001 + +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: l3-centralizedattackdetectorservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: l3-centralizedattackdetectorservice + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 120 +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: tfs-l3-centralizedattackdetectorservice-metric + labels: + app: l3-centralizedattackdetectorservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: l3-centralizedattackdetectorservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running diff --git a/manifests/load_generatorservice.yaml b/manifests/load_generatorservice.yaml index b94e11e725757fa2ec67de19f98ecfa6a03f085b..7cc6f19122573a612ddca774c3a785bff93f8b38 100644 --- a/manifests/load_generatorservice.yaml +++ b/manifests/load_generatorservice.yaml @@ -33,6 +33,7 @@ spec: imagePullPolicy: Always ports: - containerPort: 50052 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -44,11 +45,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:50052"] resources: requests: - cpu: 50m + cpu: 256m memory: 64Mi limits: - cpu: 500m - memory: 512Mi + cpu: 512m + memory: 128Mi --- apiVersion: v1 kind: Service @@ -65,3 +66,7 @@ spec: protocol: TCP port: 50052 targetPort: 50052 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/manifests/nginx_ingress_http.yaml b/manifests/nginx_ingress_http.yaml index 5db05d4af0e3594edd6186a5adbcb6733ed7d5c8..80caefa935d00d49cb311e586d2a6cc5206b8d02 100644 --- a/manifests/nginx_ingress_http.yaml +++ b/manifests/nginx_ingress_http.yaml @@ -36,13 +36,6 @@ spec: name: webuiservice port: number: 3000 - #- path: /context(/|$)(.*) - # pathType: Prefix - # backend: - # service: - # name: contextservice - # port: - # number: 8080 - path: /()(restconf/.*) pathType: Prefix backend: diff --git a/manifests/opticalattackdetectorservice.yaml b/manifests/opticalattackdetectorservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..197c23dd237e5f6271fbab7e47613892c6f58f83 --- /dev/null +++ b/manifests/opticalattackdetectorservice.yaml @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: opticalattackdetectorservice +spec: + selector: + matchLabels: + app: opticalattackdetectorservice + template: + metadata: + labels: + app: opticalattackdetectorservice + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: labs.etsi.org:5050/tfs/controller/opticalattackdetector:latest + imagePullPolicy: Always + ports: + - containerPort: 10006 + - containerPort: 9192 + env: + - name: LOG_LEVEL + value: "INFO" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-secrets + key: REDIS_PASSWORD + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:10006"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:10006"] + resources: + requests: + cpu: 250m + memory: 128Mi + limits: + cpu: 1000m + memory: 1024Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: opticalattackdetectorservice + labels: + app: opticalattackdetectorservice +spec: + type: ClusterIP + selector: + app: opticalattackdetectorservice + ports: + - name: grpc + port: 10006 + targetPort: 10006 + - name: metrics + port: 9192 + targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: opticalattackdetectorservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: opticalattackdetectorservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/opticalcentralizedattackdetectorservice.yaml b/manifests/opticalattackmanagerservice.yaml similarity index 52% rename from manifests/opticalcentralizedattackdetectorservice.yaml rename to manifests/opticalattackmanagerservice.yaml index 13d4d97c222699544dc051564ec1609cad7ed7e1..f9838bcbb1c0d86e5d3a22d8ed982b533f984eb3 100644 --- a/manifests/opticalcentralizedattackdetectorservice.yaml +++ b/manifests/opticalattackmanagerservice.yaml @@ -15,49 +15,61 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: opticalcentralizedattackdetectorservice + name: opticalattackmanagerservice spec: selector: matchLabels: - app: opticalcentralizedattackdetectorservice + app: opticalattackmanagerservice + replicas: 1 template: metadata: labels: - app: opticalcentralizedattackdetectorservice + app: opticalattackmanagerservice spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: labs.etsi.org:5050/tfs/controller/opticalcentralizedattackdetector:latest + image: labs.etsi.org:5050/tfs/controller/opticalattackmanager:latest imagePullPolicy: Always ports: - containerPort: 10005 - envFrom: - - secretRef: - name: monitoring-secrets - readinessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:10005"] - livenessProbe: - exec: - command: ["/bin/grpc_health_probe", "-addr=:10005"] + - containerPort: 9192 + env: + - name: LOG_LEVEL + value: "INFO" + - name: MONITORING_INTERVAL + value: "30" + - name: OPTICALATTACKMANAGERSERVICE_LOOP_MIN_WORKERS + value: "2" # remember to align this with the resource limits + - name: OPTICALATTACKMANAGERSERVICE_LOOP_MAX_WORKERS + value: "10" # remember to align this with the resource limits + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-secrets + key: REDIS_PASSWORD resources: requests: cpu: 250m - memory: 512Mi + memory: 128Mi limits: - cpu: 700m - memory: 1024Mi + cpu: 10000m + memory: 10240Mi --- apiVersion: v1 kind: Service metadata: - name: opticalcentralizedattackdetectorservice + name: opticalattackmanagerservice + labels: + app: opticalattackmanagerservice spec: type: ClusterIP selector: - app: opticalcentralizedattackdetectorservice + app: opticalattackmanagerservice ports: - name: grpc port: 10005 targetPort: 10005 + - name: metrics + port: 9192 + targetPort: 9192 diff --git a/manifests/opticalattackmitigatorservice.yaml b/manifests/opticalattackmitigatorservice.yaml index bfac05e40917aeca1f55c68ebf845937b46c9cdb..4d148b347157bd310ec6c921670f0434315e6e27 100644 --- a/manifests/opticalattackmitigatorservice.yaml +++ b/manifests/opticalattackmitigatorservice.yaml @@ -32,9 +32,10 @@ spec: imagePullPolicy: Always ports: - containerPort: 10007 + - containerPort: 9192 env: - name: LOG_LEVEL - value: "DEBUG" + value: "INFO" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:10007"] @@ -44,15 +45,17 @@ spec: resources: requests: cpu: 250m - memory: 512Mi + memory: 128Mi limits: - cpu: 700m + cpu: 1000m memory: 1024Mi --- apiVersion: v1 kind: Service metadata: name: opticalattackmitigatorservice + labels: + app: opticalattackmitigatorservice spec: type: ClusterIP selector: @@ -61,3 +64,28 @@ spec: - name: grpc port: 10007 targetPort: 10007 + - name: metrics + port: 9192 + targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: opticalattackmitigatorservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: opticalattackmitigatorservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/pathcompservice.yaml b/manifests/pathcompservice.yaml index 5916d09a68a93f4d877009c00925f3c56cb7f17d..f1017870098b578770fd0d4f8e9201c7fb9bf0a4 100644 --- a/manifests/pathcompservice.yaml +++ b/manifests/pathcompservice.yaml @@ -20,7 +20,7 @@ spec: selector: matchLabels: app: pathcompservice - replicas: 1 + #replicas: 1 template: metadata: labels: @@ -53,6 +53,8 @@ spec: - name: backend image: labs.etsi.org:5050/tfs/controller/pathcomp-backend:latest imagePullPolicy: Always + ports: + - containerPort: 8081 #readinessProbe: # httpGet: # path: /health @@ -96,3 +98,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: pathcompservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: pathcompservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/policyservice.yaml b/manifests/policyservice.yaml deleted file mode 120000 index bb28f6e2cff4c6b50e44f049dec6a53d31922e86..0000000000000000000000000000000000000000 --- a/manifests/policyservice.yaml +++ /dev/null @@ -1 +0,0 @@ -../src/policy/target/kubernetes/kubernetes.yml \ No newline at end of file diff --git a/manifests/policyservice.yaml b/manifests/policyservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..72da09ecaf1de9d080d686c63c0f18c88f09e8b4 --- /dev/null +++ b/manifests/policyservice.yaml @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: Service +metadata: + annotations: + app.quarkus.io/commit-id: 8065cee75be759e14af792737179537096de5e11 + app.quarkus.io/build-timestamp: 2023-03-30 - 13:49:59 +0000 + labels: + app.kubernetes.io/name: policyservice + app: policyservice + name: policyservice +spec: + ports: + - name: metrics + port: 9192 + targetPort: 8080 + - name: grpc + port: 6060 + targetPort: 6060 + selector: + app.kubernetes.io/name: policyservice + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + app.quarkus.io/commit-id: 8065cee75be759e14af792737179537096de5e11 + app.quarkus.io/build-timestamp: 2023-03-30 - 13:49:59 +0000 + labels: + app: policyservice + app.kubernetes.io/name: policyservice + name: policyservice +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: policyservice + template: + metadata: + annotations: + app.quarkus.io/commit-id: 8065cee75be759e14af792737179537096de5e11 + app.quarkus.io/build-timestamp: 2023-03-30 - 13:49:59 +0000 + labels: + app: policyservice + app.kubernetes.io/name: policyservice + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SERVICE_SERVICE_HOST + value: serviceservice + - name: CONTEXT_SERVICE_HOST + value: contextservice + - name: MONITORING_SERVICE_HOST + value: monitoringservice + image: labs.etsi.org:5050/tfs/controller/policy:0.1.0 + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /q/health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 2 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: policyservice + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + - containerPort: 6060 + name: grpc-server + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /q/health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 2 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + resources: + requests: + cpu: 50m + memory: 512Mi + limits: + cpu: 500m + memory: 2048Mi +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: policyservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: policyservice + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 \ No newline at end of file diff --git a/manifests/servicemonitors.yaml b/manifests/servicemonitors.yaml index 06c3390f4fddbcb6f8adec5d931989cc8a41cc68..e77216af2a723cef8a4c5f468ef564625ea810f1 100644 --- a/manifests/servicemonitors.yaml +++ b/manifests/servicemonitors.yaml @@ -243,3 +243,235 @@ spec: any: false matchNames: - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-policyservice-metric + labels: + app: policyservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: policyservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /q/metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-automationservice-metric + labels: + app: automationservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: automationservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /q/metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-computeservice-metric + labels: + app: computeservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: computeservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-load-generatorservice-metric + labels: + app: load-generatorservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: load-generatorservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-dbscanservingservice-metric + labels: + app: dbscanservingservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: dbscanservingservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-opticalattackmitigatorservice-metric + labels: + app: opticalattackmitigatorservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: opticalattackmitigatorservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-opticalattackdetectorservice-metric + labels: + app: opticalattackdetectorservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: opticalattackdetectorservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-opticalattackmanagerservice-metric + labels: + app: opticalattackmanagerservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: opticalattackmanagerservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running \ No newline at end of file diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index 801c06f52c8cb7d725ac4071e6d5fc99a504a291..3865fd6c0bee8d5222d57c50df58435a5669b9e1 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -20,7 +20,7 @@ spec: selector: matchLabels: app: serviceservice - replicas: 1 + #replicas: 1 template: metadata: labels: @@ -45,11 +45,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:3030"] resources: requests: - cpu: 50m - memory: 64Mi + cpu: 250m + memory: 128Mi limits: - cpu: 500m - memory: 512Mi + cpu: 1000m + memory: 1024Mi --- apiVersion: v1 kind: Service @@ -70,3 +70,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: serviceservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: serviceservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml index 49e2b5943d20586941f80e8fc4b5c32c99d70f8e..e7e5c1604a8b971424ff5f7e5bf292c4b263cbfe 100644 --- a/manifests/sliceservice.yaml +++ b/manifests/sliceservice.yaml @@ -20,7 +20,7 @@ spec: selector: matchLabels: app: sliceservice - replicas: 1 + #replicas: 1 template: metadata: labels: @@ -50,11 +50,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:4040"] resources: requests: - cpu: 50m - memory: 64Mi + cpu: 250m + memory: 128Mi limits: - cpu: 500m - memory: 512Mi + cpu: 1000m + memory: 1024Mi --- apiVersion: v1 kind: Service @@ -75,3 +75,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: sliceservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: sliceservice + 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 f25dbf6e501775d56f266699b1474429b42b2015..b6ddfc0a91ae5316969079c517e148f63fb18b61 100644 --- a/manifests/webuiservice.yaml +++ b/manifests/webuiservice.yaml @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: webuiservice + replicas: 1 template: metadata: labels: @@ -55,13 +56,13 @@ spec: timeoutSeconds: 1 resources: requests: - cpu: 100m - memory: 512Mi + cpu: 50m + memory: 64Mi limits: - cpu: 700m - memory: 1024Mi + cpu: 500m + memory: 512Mi - name: grafana - image: grafana/grafana:8.5.11 + image: grafana/grafana:8.5.22 imagePullPolicy: IfNotPresent ports: - containerPort: 3000 @@ -92,16 +93,18 @@ spec: timeoutSeconds: 1 resources: requests: - cpu: 250m - memory: 750Mi + cpu: 150m + memory: 512Mi limits: - cpu: 700m + cpu: 500m memory: 1024Mi --- apiVersion: v1 kind: Service metadata: name: webuiservice + labels: + app: webuiservice spec: type: ClusterIP selector: diff --git a/my_deploy.sh b/my_deploy.sh index c0a3d461fd910c0aaa1c4d672dbc3172e1801075..1ffbffa15e3d285af37ed6328e45b768de7abc1b 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -20,9 +20,20 @@ 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 automation monitoring pathcomp service slice compute webui load_generator" export TFS_COMPONENTS="context device pathcomp service slice compute webui load_generator" +# Uncoment to activate Monitoring +#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" + +# Uncoment to activate Automation and Policy Manager +#export TFS_COMPONENTS="${TFS_COMPONENTS} automation policy" + +# Uncoment to activate Optical CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" + +# Uncoment to activate L3 CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" + # Set the tag you want to use for your images. export TFS_IMAGE_TAG="dev" @@ -30,8 +41,10 @@ export TFS_IMAGE_TAG="dev" export TFS_K8S_NAMESPACE="tfs" # Set additional manifest files to be applied after the deployment -#export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml manifests/servicemonitors.yaml" -export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" +export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml manifests/servicemonitors.yaml" + +# Uncoment 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+" @@ -45,6 +58,12 @@ export TFS_SKIP_BUILD="" # 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" @@ -70,6 +89,12 @@ export CRDB_REDEPLOY="" # 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" + # Disable flag for re-deploying NATS from scratch. export NATS_REDEPLOY="" @@ -79,6 +104,15 @@ export NATS_REDEPLOY="" # 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" @@ -96,3 +130,12 @@ export QDB_DROP_TABLES_IF_EXIST="YES" # 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" diff --git a/ofc23 b/ofc23 new file mode 120000 index 0000000000000000000000000000000000000000..a1135d4c59a81997350864319a6c267eaaf9ed93 --- /dev/null +++ b/ofc23 @@ -0,0 +1 @@ +src/tests/ofc23/ \ No newline at end of file diff --git a/proto/context.proto b/proto/context.proto index 49d16229cdac5de84f25cfaa7d196d25184f46f0..3104f1b545c02bab71c8638ebba03efdcbfe71ff 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -40,7 +40,7 @@ service ContextService { rpc SetDevice (Device ) returns ( DeviceId ) {} rpc RemoveDevice (DeviceId ) returns ( Empty ) {} rpc GetDeviceEvents (Empty ) returns (stream DeviceEvent ) {} - + rpc SelectDevice (DeviceFilter ) returns ( DeviceList ) {} rpc ListEndPointNames (EndPointIdList) returns ( EndPointNameList) {} rpc ListLinkIds (Empty ) returns ( LinkIdList ) {} @@ -57,6 +57,7 @@ service ContextService { rpc UnsetService (Service ) returns ( ServiceId ) {} rpc RemoveService (ServiceId ) returns ( Empty ) {} rpc GetServiceEvents (Empty ) returns (stream ServiceEvent ) {} + rpc SelectService (ServiceFilter ) returns ( ServiceList ) {} rpc ListSliceIds (ContextId ) returns ( SliceIdList ) {} rpc ListSlices (ContextId ) returns ( SliceList ) {} @@ -65,6 +66,7 @@ service ContextService { rpc UnsetSlice (Slice ) returns ( SliceId ) {} rpc RemoveSlice (SliceId ) returns ( Empty ) {} rpc GetSliceEvents (Empty ) returns (stream SliceEvent ) {} + rpc SelectSlice (SliceFilter ) returns ( SliceList ) {} rpc ListConnectionIds (ServiceId ) returns ( ConnectionIdList) {} rpc ListConnections (ServiceId ) returns ( ConnectionList ) {} @@ -173,6 +175,7 @@ message Device { repeated DeviceDriverEnum device_drivers = 6; repeated EndPoint device_endpoints = 7; repeated Component component = 8; // Used for inventory + DeviceId controller_id = 9; // Identifier of node controlling the actual device } message Component { @@ -191,6 +194,7 @@ enum DeviceDriverEnum { DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4; DEVICEDRIVER_ONF_TR_352 = 5; DEVICEDRIVER_XR = 6; + DEVICEDRIVER_IETF_L2VPN = 7; } enum DeviceOperationalStatusEnum { @@ -207,6 +211,13 @@ message DeviceList { repeated Device devices = 1; } +message DeviceFilter { + DeviceIdList device_ids = 1; + bool include_endpoints = 2; + bool include_config_rules = 3; + bool include_components = 4; +} + message DeviceEvent { Event event = 1; DeviceId device_id = 2; @@ -266,9 +277,10 @@ enum ServiceTypeEnum { enum ServiceStatusEnum { SERVICESTATUS_UNDEFINED = 0; SERVICESTATUS_PLANNED = 1; - SERVICESTATUS_ACTIVE = 2; - SERVICESTATUS_PENDING_REMOVAL = 3; - SERVICESTATUS_SLA_VIOLATED = 4; + SERVICESTATUS_ACTIVE = 2; + SERVICESTATUS_UPDATING = 3; + SERVICESTATUS_PENDING_REMOVAL = 4; + SERVICESTATUS_SLA_VIOLATED = 5; } message ServiceStatus { @@ -287,6 +299,13 @@ message ServiceList { repeated Service services = 1; } +message ServiceFilter { + ServiceIdList service_ids = 1; + bool include_endpoint_ids = 2; + bool include_constraints = 3; + bool include_config_rules = 4; +} + message ServiceEvent { Event event = 1; ServiceId service_id = 2; @@ -341,6 +360,15 @@ message SliceList { repeated Slice slices = 1; } +message SliceFilter { + SliceIdList slice_ids = 1; + bool include_endpoint_ids = 2; + bool include_constraints = 3; + bool include_service_ids = 4; + bool include_subslice_ids = 5; + bool include_config_rules = 6; +} + message SliceEvent { Event event = 1; SliceId slice_id = 2; @@ -528,6 +556,13 @@ message Constraint_SLA_Isolation_level { repeated IsolationLevelEnum isolation_level = 1; } +message Constraint_Exclusions { + bool is_permanent = 1; + repeated DeviceId device_ids = 2; + repeated EndPointId endpoint_ids = 3; + repeated LinkId link_ids = 4; +} + message Constraint { oneof constraint { Constraint_Custom custom = 1; @@ -538,6 +573,7 @@ message Constraint { Constraint_SLA_Latency sla_latency = 6; Constraint_SLA_Availability sla_availability = 7; Constraint_SLA_Isolation_level sla_isolation = 8; + Constraint_Exclusions exclusions = 9; } } diff --git a/proto/generate_code_python.sh b/proto/generate_code_python.sh index 5c5db5444d3ef31570019abbcd7eab4f1a305a48..14f403b37a80e4b29c81ffc13c4e327195841d2c 100755 --- a/proto/generate_code_python.sh +++ b/proto/generate_code_python.sh @@ -38,5 +38,8 @@ EOF # Generate Python code python3 -m grpc_tools.protoc -I=./ --python_out=src/python/ --grpc_python_out=src/python/ *.proto +# new line added to generate protobuf for the `grpclib` library +python3 -m grpc_tools.protoc -I=./ --python_out=src/python/asyncio --grpclib_python_out=src/python/asyncio *.proto + # Arrange generated code imports to enable imports from arbitrary subpackages find src/python -type f -iname *.py -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \; diff --git a/proto/l3_attackmitigator.proto b/proto/l3_attackmitigator.proto index 5ce9428b6f47318cf4bdd205c48645295ff26d71..572d96f9e586dae4a124b1b9de1368b71fb9f0b7 100644 --- a/proto/l3_attackmitigator.proto +++ b/proto/l3_attackmitigator.proto @@ -17,23 +17,33 @@ syntax = "proto3"; import "context.proto"; service L3Attackmitigator{ - // Sends a greeting - rpc SendOutput (L3AttackmitigatorOutput) returns (context.Empty) {} - // Sends another greeting + // Perform Mitigation + rpc PerformMitigation (L3AttackmitigatorOutput) returns (context.Empty) {} + // Get Mitigation rpc GetMitigation (context.Empty) returns (context.Empty) {} + // Get Configured ACL Rules + rpc GetConfiguredACLRules (context.Empty) returns (ACLRules) {} } message L3AttackmitigatorOutput { float confidence = 1; string timestamp = 2; - string ip_o = 3; - string tag_name = 4; - int32 tag = 5; - string flow_id = 6; - string protocol = 7; - string port_d = 8; - string ml_id = 9; - float time_start = 10; - float time_end = 11; + string ip_o = 3; + string ip_d = 4; + string tag_name = 5; + int32 tag = 6; + string flow_id = 7; + string protocol = 8; + string port_o = 9; + string port_d = 10; + string ml_id = 11; + context.ServiceId service_id = 12; + context.EndPointId endpoint_id = 13; + float time_start = 14; + float time_end = 15; +} + +message ACLRules { + repeated context.ConfigRule acl_rules = 1; } diff --git a/proto/l3_centralizedattackdetector.proto b/proto/l3_centralizedattackdetector.proto index 2aeb8826e8662b6495f10a333145a9f6abe594b9..ed99435aa7db6584b381079cb1e3d589fb9998b5 100644 --- a/proto/l3_centralizedattackdetector.proto +++ b/proto/l3_centralizedattackdetector.proto @@ -14,65 +14,55 @@ syntax = "proto3"; +import "context.proto"; + service L3Centralizedattackdetector { - // Sends a greeting - rpc SendInput (L3CentralizedattackdetectorMetrics) returns (Empty) {} - // Sends another greeting - rpc GetOutput (Empty) returns (L3CentralizedattackdetectorModelOutput) {} + // Analyze single input to the ML model in the CAD component + rpc AnalyzeConnectionStatistics (L3CentralizedattackdetectorMetrics) returns (Empty) {} + + // Analyze a batch of inputs to the ML model in the CAD component + rpc AnalyzeBatchConnectionStatistics (L3CentralizedattackdetectorBatchInput) returns (Empty) {} + + // Get the list of features used by the ML model in the CAD component + rpc GetFeaturesIds (Empty) returns (AutoFeatures) {} +} + +message Feature { + float feature = 1; } message L3CentralizedattackdetectorMetrics { - /* - Model input sent to the Inferencer by the client - There are currently 9 values and - */ + // Input sent by the DAD compoenent to the ML model integrated in the CAD component. - // Machine learning - float n_packets_server_seconds = 1; - float n_packets_client_seconds = 2; - float n_bits_server_seconds = 3; - float n_bits_client_seconds = 4; - float n_bits_server_n_packets_server = 5; - float n_bits_client_n_packets_client = 6; - float n_packets_server_n_packets_client = 7; - float n_bits_server_n_bits_client = 8; + // Machine learning model features + repeated Feature features = 1; + ConnectionMetadata connection_metadata = 2; - // Conection identifier - string ip_o = 9; - string port_o = 10; - string ip_d = 11; - string port_d = 12; - string flow_id = 13; - string protocol = 14; - float time_start = 15; - float time_end = 16; } -message Empty { - string message = 1; +message ConnectionMetadata { + string ip_o = 1; + string port_o = 2; + string ip_d = 3; + string port_d = 4; + string flow_id = 5; + context.ServiceId service_id = 6; + context.EndPointId endpoint_id = 7; + string protocol = 8; + float time_start = 9; + float time_end = 10; } -message L3CentralizedattackdetectorModelOutput { - float confidence = 1; - string timestamp = 2; - string ip_o = 3; - string tag_name = 4; - int32 tag = 5; - string flow_id = 6; - string protocol = 7; - string port_d = 8; - string ml_id = 9; - float time_start = 10; - float time_end = 11; +// Collection of values representing ML features +message AutoFeatures { + repeated float auto_features = 1; } -// Collections or streams? -/* -message InputCollection { - repeated model_input = 1; +// Collection (batch) of model inputs that will be sent to the model +message L3CentralizedattackdetectorBatchInput { + repeated L3CentralizedattackdetectorMetrics metrics = 1; } -message OutputCollection { - repeated model_output = 1; +message Empty { + string message = 1; } -*/ diff --git a/proto/load_generator.proto b/proto/load_generator.proto index 86f9469588f1586da5339edad198e39e82598cde..32523b331418813b51fb542d9eb17e29fc2b13d2 100644 --- a/proto/load_generator.proto +++ b/proto/load_generator.proto @@ -33,21 +33,40 @@ enum RequestTypeEnum { REQUESTTYPE_SLICE_L3NM = 6; } +message Range { + float minimum = 1; + float maximum = 2; +} + +message ScalarOrRange { + oneof value { + float scalar = 1; // select the scalar value + Range range = 2; // select a random uniformly dstributed value between minimum and maximum + } +} + message Parameters { uint64 num_requests = 1; // if == 0, generate infinite requests repeated RequestTypeEnum request_types = 2; - float offered_load = 3; - float holding_time = 4; - float inter_arrival_time = 5; - bool do_teardown = 6; - bool dry_mode = 7; - bool record_to_dlt = 8; - string dlt_domain_id = 9; + string device_regex = 3; // Only devices and endpoints matching the regex expression will be considered as + string endpoint_regex = 4; // source-destination candidates for the requests generated. + float offered_load = 5; + float holding_time = 6; + float inter_arrival_time = 7; + repeated ScalarOrRange availability = 8; // One from the list is selected to populate the constraint + repeated ScalarOrRange capacity_gbps = 9; // One from the list is selected to populate the constraint + repeated ScalarOrRange e2e_latency_ms = 10; // One from the list is selected to populate the constraint + uint32 max_workers = 11; + bool do_teardown = 12; + bool dry_mode = 13; + bool record_to_dlt = 14; + string dlt_domain_id = 15; } message Status { Parameters parameters = 1; uint64 num_generated = 2; - bool infinite_loop = 3; - bool running = 4; + uint64 num_released = 3; + bool infinite_loop = 4; + bool running = 5; } diff --git a/proto/centralized_attack_detector.proto b/proto/optical_attack_detector.proto similarity index 62% rename from proto/centralized_attack_detector.proto rename to proto/optical_attack_detector.proto index 7b4fc35f07b079955d4c347ecf3f728abd0292f5..ebe3b5e06163c6e5a3bf7889065d5bb31923dd89 100644 --- a/proto/centralized_attack_detector.proto +++ b/proto/optical_attack_detector.proto @@ -14,19 +14,19 @@ // protocol buffers documentation: https://developers.google.com/protocol-buffers/docs/proto3 syntax = "proto3"; -package centralized_attack_detector; +package optical_attack_detector; import "context.proto"; import "monitoring.proto"; -service CentralizedAttackDetectorService { - rpc NotifyServiceUpdate (context.Service ) returns (context.Empty) {} +service OpticalAttackDetectorService { - // rpc that triggers the attack detection loop - rpc DetectAttack (context.Empty ) returns (context.Empty) {} + // rpc that executes the detection loop for a particular service + rpc DetectAttack (DetectionRequest) returns (context.Empty) {} - // rpc called by the distributed component to report KPIs - rpc ReportSummarizedKpi (monitoring.KpiList) returns (context.Empty) {} +} - rpc ReportKpi (monitoring.KpiList) returns (context.Empty) {} +message DetectionRequest { + context.ServiceId service_id = 1; + monitoring.KpiId kpi_id = 2; } diff --git a/proto/optical_centralized_attack_detector.proto b/proto/optical_centralized_attack_detector.proto deleted file mode 100644 index 98ffeddc81c7533fccfd118075732a3f7799264f..0000000000000000000000000000000000000000 --- a/proto/optical_centralized_attack_detector.proto +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -// protocol buffers documentation: https://developers.google.com/protocol-buffers/docs/proto3 -syntax = "proto3"; -package centralized_attack_detector; - -import "context.proto"; -import "monitoring.proto"; - -service OpticalCentralizedAttackDetectorService { - rpc NotifyServiceUpdate (context.Service ) returns (context.Empty) {} - - // rpc that triggers the attack detection loop - rpc DetectAttack (context.Empty ) returns (context.Empty) {} - - // rpc called by the distributed component to report KPIs - rpc ReportSummarizedKpi (monitoring.KpiList) returns (context.Empty) {} - - rpc ReportKpi (monitoring.KpiList) returns (context.Empty) {} -} diff --git a/proto/service.proto b/proto/service.proto index 21e5699413cc4842962af6ee9c204b383fc61ec0..658859e3c5aac58e792d508a89b467e937198c5b 100644 --- a/proto/service.proto +++ b/proto/service.proto @@ -18,7 +18,8 @@ package service; import "context.proto"; service ServiceService { - rpc CreateService(context.Service ) returns (context.ServiceId) {} - rpc UpdateService(context.Service ) returns (context.ServiceId) {} - rpc DeleteService(context.ServiceId) returns (context.Empty ) {} + rpc CreateService (context.Service ) returns (context.ServiceId) {} + rpc UpdateService (context.Service ) returns (context.ServiceId) {} + rpc DeleteService (context.ServiceId) returns (context.Empty ) {} + rpc RecomputeConnections(context.Service ) returns (context.Empty ) {} } diff --git a/proto/src/python/asyncio/__init__.py b/proto/src/python/asyncio/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/proto/src/python/asyncio/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/scripts/old/open_dashboard.sh b/scripts/old/open_dashboard.sh old mode 100755 new mode 100644 index 4ea206f4538c27fe8563ce5c30ed837781f8d362..2ff15684a499fe390816ebb8e4859cad49d43d32 --- a/scripts/old/open_dashboard.sh +++ b/scripts/old/open_dashboard.sh @@ -16,9 +16,7 @@ # this script opens the dashboard -K8S_NAMESPACE=${K8S_NAMESPACE:-'tfs'} - -GRAFANA_IP=$(kubectl get service/webuiservice -n ${TFS_K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}') +GRAFANA_IP=$(kubectl get service/grafana -n monitoring -o jsonpath='{.spec.clusterIP}') GRAFANA_PORT=3000 #$(kubectl get service webuiservice --namespace $TFS_K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==3000)].nodePort}') URL=http://${GRAFANA_IP}:${GRAFANA_PORT} diff --git a/scripts/show_logs_compute.sh b/scripts/show_logs_compute.sh index fc992eb43e5872b4522db6f5c8ce39207f12d559..f0c24b63aa7b7e5c6678659c34dee34e8ce5b49e 100755 --- a/scripts/show_logs_compute.sh +++ b/scripts/show_logs_compute.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/computeservice +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/computeservice -c server diff --git a/scripts/show_logs_device.sh b/scripts/show_logs_device.sh index 6a77c38152716f1e6fbf320671dda25d974431c8..e643f563a6b8ba250985b013cecc9340c53c9411 100755 --- a/scripts/show_logs_device.sh +++ b/scripts/show_logs_device.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/deviceservice +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/deviceservice -c server diff --git a/scripts/show_logs_l3-attack-mitigator.sh b/scripts/show_logs_l3-attack-mitigator.sh new file mode 100755 index 0000000000000000000000000000000000000000..fc54a2a36e14b1a40941a5536ef575e7d4ce7038 --- /dev/null +++ b/scripts/show_logs_l3-attack-mitigator.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/l3-attackmitigatorservice -c server diff --git a/scripts/show_logs_l3-centralized-attack-detector.sh b/scripts/show_logs_l3-centralized-attack-detector.sh new file mode 100755 index 0000000000000000000000000000000000000000..002755f3a97d18d1242b05aeeba1364c980bf4a1 --- /dev/null +++ b/scripts/show_logs_l3-centralized-attack-detector.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/l3-centralizedattackdetectorservice -c server diff --git a/scripts/show_logs_load_generator.sh b/scripts/show_logs_load_generator.sh index d0f2527d74840d48a10e0ec7ba018f513eea2c52..51438f181f5492a1c9c9bc8dd0b5a76f6db1046c 100755 --- a/scripts/show_logs_load_generator.sh +++ b/scripts/show_logs_load_generator.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/load-generatorservice +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/load-generatorservice -c server diff --git a/scripts/show_logs_monitoring.sh b/scripts/show_logs_monitoring.sh index 1a152a32216545f53607880c3908266f4ac41e95..61b0b5cc024f89daeffc0745c2689d85500f4115 100755 --- a/scripts/show_logs_monitoring.sh +++ b/scripts/show_logs_monitoring.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/monitoringservice server +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/monitoringservice -c server diff --git a/scripts/show_logs_service.sh b/scripts/show_logs_service.sh index 7ca1c1c2f4286a5fc46f7d36197d376472b447ed..cc75e19c64935f99c7919f9371717b91b0e6b3cb 100755 --- a/scripts/show_logs_service.sh +++ b/scripts/show_logs_service.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/serviceservice +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/serviceservice -c server diff --git a/scripts/show_logs_slice.sh b/scripts/show_logs_slice.sh index c71bc92eaa4a8d411372fc0ad4194881a5a2a9c8..7fa8091cce081ff7cef152f465bea8e426b40124 100755 --- a/scripts/show_logs_slice.sh +++ b/scripts/show_logs_slice.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/sliceservice +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/sliceservice -c server diff --git a/src/automation/pom.xml b/src/automation/pom.xml index 2fd5fd263a698145f39c37ed358982de58dfee77..7dfc3dac438fa5df740381be0ef595a5734d7699 100644 --- a/src/automation/pom.xml +++ b/src/automation/pom.xml @@ -174,6 +174,11 @@ test + + io.quarkus + quarkus-smallrye-metrics + + diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java index 51857bb3dba6422fe6ffc93930e0e2bf65b1a223..2f9054cd8296579b3e391aae84ec16ad1f460bdb 100644 --- a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java +++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java @@ -27,6 +27,10 @@ import io.quarkus.grpc.GrpcService; import io.smallrye.mutiny.Uni; import javax.inject.Inject; +import org.eclipse.microprofile.metrics.MetricUnits; +import org.eclipse.microprofile.metrics.annotation.Counted; +import org.eclipse.microprofile.metrics.annotation.Timed; + @GrpcService public class AutomationGatewayImpl implements AutomationGateway { @@ -40,18 +44,24 @@ public class AutomationGatewayImpl implements AutomationGateway { } @Override + @Counted(name = "automation_ztpGetDeviceRole_counter") + @Timed(name = "automation_ztpGetDeviceRole_histogram", unit = MetricUnits.MILLISECONDS) public Uni ztpGetDeviceRole(Automation.DeviceRoleId request) { return Uni.createFrom() .item(() -> Automation.DeviceRole.newBuilder().setDevRoleId(request).build()); } @Override + @Counted(name = "automation_ztpGetDeviceRolesByDeviceId_counter") + @Timed(name = "automation_ztpGetDeviceRolesByDeviceId_histogram", unit = MetricUnits.MILLISECONDS) public Uni ztpGetDeviceRolesByDeviceId( ContextOuterClass.DeviceId request) { return Uni.createFrom().item(() -> Automation.DeviceRoleList.newBuilder().build()); } @Override + @Counted(name = "automation_ztpAdd_counter") + @Timed(name = "automation_ztpAdd_histogram", unit = MetricUnits.MILLISECONDS) public Uni ztpAdd(Automation.DeviceRole request) { final var devRoleId = request.getDevRoleId().getDevRoleId().getUuid(); final var deviceId = serializer.deserialize(request.getDevRoleId().getDevId()); @@ -63,6 +73,8 @@ public class AutomationGatewayImpl implements AutomationGateway { } @Override + @Counted(name = "automation_ztpUpdate_counter") + @Timed(name = "automation_ztpUpdate_histogram", unit = MetricUnits.MILLISECONDS) public Uni ztpUpdate(DeviceRoleConfig request) { final var devRoleId = request.getDevRole().getDevRoleId().getDevRoleId().getUuid(); final var deviceId = serializer.deserialize(request.getDevRole().getDevRoleId().getDevId()); @@ -75,6 +87,8 @@ public class AutomationGatewayImpl implements AutomationGateway { } @Override + @Counted(name = "automation_ztpDelete_counter") + @Timed(name = "automation_ztpDelete_histogram", unit = MetricUnits.MILLISECONDS) public Uni ztpDelete(Automation.DeviceRole request) { final var devRoleId = request.getDevRoleId().getDevRoleId().getUuid(); return automationService @@ -84,6 +98,8 @@ public class AutomationGatewayImpl implements AutomationGateway { } @Override + @Counted(name = "automation_ztpDeleteAll_counter") + @Timed(name = "automation_ztpDeleteAll_histogram", unit = MetricUnits.MILLISECONDS) public Uni ztpDeleteAll(ContextOuterClass.Empty empty) { return Uni.createFrom().item(() -> Automation.DeviceDeletionResult.newBuilder().build()); } diff --git a/src/automation/src/main/java/eu/teraflow/automation/Serializer.java b/src/automation/src/main/java/eu/teraflow/automation/Serializer.java index 08691b5266b8172a2bd0449df870033bd2664dd0..b0729aa55b25da030f9722330e22a0976a3d007f 100644 --- a/src/automation/src/main/java/eu/teraflow/automation/Serializer.java +++ b/src/automation/src/main/java/eu/teraflow/automation/Serializer.java @@ -853,6 +853,8 @@ public class Serializer { return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352; case XR: return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_XR; + case IETF_L2VPN: + return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN; case UNDEFINED: default: return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_UNDEFINED; @@ -874,6 +876,8 @@ public class Serializer { return DeviceDriverEnum.ONF_TR_352; case DEVICEDRIVER_XR: return DeviceDriverEnum.XR; + case DEVICEDRIVER_IETF_L2VPN: + return DeviceDriverEnum.IETF_L2VPN; case DEVICEDRIVER_UNDEFINED: case UNRECOGNIZED: default: diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceDriverEnum.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceDriverEnum.java index a364bb0e3cb821d20061d574428984acacb0cc46..3a26937e79d0df2cfead305a10ccadf3c54eae89 100644 --- a/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceDriverEnum.java +++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceDriverEnum.java @@ -23,5 +23,6 @@ public enum DeviceDriverEnum { P4, IETF_NETWORK_TOPOLOGY, ONF_TR_352, - XR + XR, + IETF_L2VPN } diff --git a/src/automation/src/main/resources/application.yml b/src/automation/src/main/resources/application.yml index f7b767e98f55556d21910b649fdfda2d9a8f94ec..bf638039daf3460c2f4ef374a380b37d01de1f1c 100644 --- a/src/automation/src/main/resources/application.yml +++ b/src/automation/src/main/resources/application.yml @@ -17,7 +17,7 @@ automation: quarkus: banner: path: teraflow-automation-banner.txt - grpc: + grpc: server: port: 5050 enable-reflection-service: true @@ -36,6 +36,7 @@ quarkus: group: tfs name: controller/automation registry: labs.etsi.org:5050 + tag: 0.2.0 kubernetes: name: automationservice @@ -51,12 +52,16 @@ quarkus: period: 10s ports: http: - host-port: 8080 + host-port: 9192 container-port: 8080 - grpc: - host-port: 5050 - container-port: 5050 env: vars: context-service-host: "contextservice" device-service-host: "deviceservice" + resources: + requests: + cpu: 50m + memory: 512Mi + limits: + cpu: 500m + memory: 2048Mi diff --git a/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java b/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java index 494e608a105897fe005a18b7041b34fe95b40f8b..0931054c682dede502fb9f22bf911439e52c2140 100644 --- a/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java +++ b/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java @@ -1215,6 +1215,8 @@ class SerializerTest { DeviceDriverEnum.ONF_TR_352, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352), Arguments.of(DeviceDriverEnum.XR, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_XR), + Arguments.of( + DeviceDriverEnum.IETF_L2VPN, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN), Arguments.of( DeviceDriverEnum.UNDEFINED, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_UNDEFINED)); } diff --git a/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java b/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java index 060e81a556893b1ca3c60928569983506bff3672..b1bccdeccf564b0d8d7bd2a8606f614b00ede972 100644 --- a/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java +++ b/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java @@ -177,6 +177,10 @@ public final class ContextOuterClass { * DEVICEDRIVER_XR = 6; */ DEVICEDRIVER_XR(6), + /** + * DEVICEDRIVER_IETF_L2VPN = 7; + */ + DEVICEDRIVER_IETF_L2VPN(7), UNRECOGNIZED(-1), ; @@ -212,6 +216,10 @@ public final class ContextOuterClass { * DEVICEDRIVER_XR = 6; */ public static final int DEVICEDRIVER_XR_VALUE = 6; + /** + * DEVICEDRIVER_IETF_L2VPN = 7; + */ + public static final int DEVICEDRIVER_IETF_L2VPN_VALUE = 7; public final int getNumber() { @@ -245,6 +253,7 @@ public final class ContextOuterClass { case 4: return DEVICEDRIVER_IETF_NETWORK_TOPOLOGY; case 5: return DEVICEDRIVER_ONF_TR_352; case 6: return DEVICEDRIVER_XR; + case 7: return DEVICEDRIVER_IETF_L2VPN; default: return null; } } diff --git a/src/automation/target/kubernetes/kubernetes.yml b/src/automation/target/kubernetes/kubernetes.yml index 4dacf3998c3991a441dc374ca6c6abc29e8d3b80..7aa68a257eeda04d6101f05b291882c274c43f86 100644 --- a/src/automation/target/kubernetes/kubernetes.yml +++ b/src/automation/target/kubernetes/kubernetes.yml @@ -4,32 +4,36 @@ # 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 +# 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: v1 kind: Service metadata: annotations: - app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000 + app.quarkus.io/commit-id: 23832f2975e3c8967e9685f7e3a5f5458d04527a + app.quarkus.io/build-timestamp: 2023-04-04 - 11:47:48 +0000 + prometheus.io/scrape: "true" + prometheus.io/path: /q/metrics + prometheus.io/port: "8080" + prometheus.io/scheme: http labels: app.kubernetes.io/name: automationservice app: automationservice name: automationservice spec: ports: - - name: grpc - port: 5050 - targetPort: 5050 - name: http - port: 8080 + port: 9192 targetPort: 8080 + - name: grpc-server + port: 5050 + targetPort: 5050 selector: app.kubernetes.io/name: automationservice type: ClusterIP @@ -38,7 +42,12 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000 + app.quarkus.io/commit-id: 23832f2975e3c8967e9685f7e3a5f5458d04527a + app.quarkus.io/build-timestamp: 2023-04-04 - 11:47:48 +0000 + prometheus.io/scrape: "true" + prometheus.io/path: /q/metrics + prometheus.io/port: "8080" + prometheus.io/scheme: http labels: app: automationservice app.kubernetes.io/name: automationservice @@ -51,7 +60,12 @@ spec: template: metadata: annotations: - app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000 + app.quarkus.io/commit-id: 23832f2975e3c8967e9685f7e3a5f5458d04527a + app.quarkus.io/build-timestamp: 2023-04-04 - 11:47:48 +0000 + prometheus.io/scrape: "true" + prometheus.io/path: /q/metrics + prometheus.io/port: "8080" + prometheus.io/scheme: http labels: app: automationservice app.kubernetes.io/name: automationservice @@ -80,12 +94,12 @@ spec: timeoutSeconds: 10 name: automationservice ports: - - containerPort: 5050 - name: grpc - protocol: TCP - containerPort: 8080 name: http protocol: TCP + - containerPort: 5050 + name: grpc-server + protocol: TCP readinessProbe: failureThreshold: 3 httpGet: @@ -96,3 +110,10 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 + resources: + limits: + cpu: 500m + memory: 2048Mi + requests: + cpu: 50m + memory: 512Mi diff --git a/src/common/Constants.py b/src/common/Constants.py index a7bf198a7204677ed3669fc28a2c3528a5936425..ed1c1475ad3c69cfb9bd650f0d99f33c6cf0f2bc 100644 --- a/src/common/Constants.py +++ b/src/common/Constants.py @@ -36,19 +36,26 @@ INTERDOMAIN_TOPOLOGY_NAME = 'inter' # contains the abstract inter-domain top # Default service names class ServiceNameEnum(Enum): - CONTEXT = 'context' - DEVICE = 'device' - SERVICE = 'service' - SLICE = 'slice' - AUTOMATION = 'automation' - POLICY = 'policy' - MONITORING = 'monitoring' - DLT = 'dlt' - COMPUTE = 'compute' - CYBERSECURITY = 'cybersecurity' - INTERDOMAIN = 'interdomain' - PATHCOMP = 'pathcomp' - WEBUI = 'webui' + CONTEXT = 'context' + DEVICE = 'device' + SERVICE = 'service' + SLICE = 'slice' + AUTOMATION = 'automation' + POLICY = 'policy' + MONITORING = 'monitoring' + DLT = 'dlt' + COMPUTE = 'compute' + CYBERSECURITY = 'cybersecurity' + INTERDOMAIN = 'interdomain' + PATHCOMP = 'pathcomp' + L3_AM = 'l3-attackmitigator' + L3_CAD = 'l3-centralizedattackdetector' + WEBUI = 'webui' + DBSCANSERVING = 'dbscanserving' + OPTICALATTACKMANAGER = 'opticalattackmanager' + OPTICALATTACKDETECTOR = 'opticalattackdetector' + OPTICALATTACKMITIGATOR = 'opticalattackmitigator' + CACHING = 'caching' # Used for test and debugging only DLT_GATEWAY = 'dltgateway' @@ -56,18 +63,23 @@ class ServiceNameEnum(Enum): # Default gRPC service ports DEFAULT_SERVICE_GRPC_PORTS = { - ServiceNameEnum.CONTEXT .value : 1010, - ServiceNameEnum.DEVICE .value : 2020, - ServiceNameEnum.SERVICE .value : 3030, - ServiceNameEnum.SLICE .value : 4040, - ServiceNameEnum.AUTOMATION .value : 5050, - ServiceNameEnum.POLICY .value : 6060, - ServiceNameEnum.MONITORING .value : 7070, - ServiceNameEnum.DLT .value : 8080, - ServiceNameEnum.COMPUTE .value : 9090, - ServiceNameEnum.CYBERSECURITY.value : 10000, - ServiceNameEnum.INTERDOMAIN .value : 10010, - ServiceNameEnum.PATHCOMP .value : 10020, + ServiceNameEnum.CONTEXT .value : 1010, + ServiceNameEnum.DEVICE .value : 2020, + ServiceNameEnum.SERVICE .value : 3030, + ServiceNameEnum.SLICE .value : 4040, + ServiceNameEnum.AUTOMATION .value : 5050, + ServiceNameEnum.POLICY .value : 6060, + ServiceNameEnum.MONITORING .value : 7070, + ServiceNameEnum.DLT .value : 8080, + ServiceNameEnum.COMPUTE .value : 9090, + ServiceNameEnum.L3_CAD .value : 10001, + ServiceNameEnum.L3_AM .value : 10002, + ServiceNameEnum.DBSCANSERVING .value : 10008, + ServiceNameEnum.OPTICALATTACKDETECTOR .value : 10006, + ServiceNameEnum.OPTICALATTACKMITIGATOR .value : 10007, + ServiceNameEnum.OPTICALATTACKMANAGER .value : 10005, + ServiceNameEnum.INTERDOMAIN .value : 10010, + ServiceNameEnum.PATHCOMP .value : 10020, # Used for test and debugging only ServiceNameEnum.DLT_GATEWAY .value : 50051, diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py index 99255defdb6b5ee155607536a2e13d23b97b2d3a..bb8948585f163aeb84ee758b8581bc6509d29799 100644 --- a/src/common/DeviceTypes.py +++ b/src/common/DeviceTypes.py @@ -25,9 +25,12 @@ class DeviceTypeEnum(Enum): EMULATED_OPEN_LINE_SYSTEM = 'emu-open-line-system' EMULATED_OPTICAL_ROADM = 'emu-optical-roadm' EMULATED_OPTICAL_TRANSPONDER = 'emu-optical-transponder' + EMULATED_OPTICAL_SPLITTER = 'emu-optical-splitter' # passive component required for XR Constellation EMULATED_P4_SWITCH = 'emu-p4-switch' + EMULATED_PACKET_RADIO_ROUTER = 'emu-packet-radio-router' EMULATED_PACKET_ROUTER = 'emu-packet-router' EMULATED_PACKET_SWITCH = 'emu-packet-switch' + EMULATED_XR_CONSTELLATION = 'emu-xr-constellation' # Real device types DATACENTER = 'datacenter' @@ -36,6 +39,10 @@ class DeviceTypeEnum(Enum): OPTICAL_ROADM = 'optical-roadm' OPTICAL_TRANSPONDER = 'optical-transponder' P4_SWITCH = 'p4-switch' + PACKET_RADIO_ROUTER = 'packet-radio-router' PACKET_ROUTER = 'packet-router' PACKET_SWITCH = 'packet-switch' - XR_CONSTELLATION = 'xr-constellation' \ No newline at end of file + XR_CONSTELLATION = 'xr-constellation' + + # ETSI TeraFlowSDN controller + TERAFLOWSDN_CONTROLLER = 'teraflowsdn' diff --git a/src/common/Settings.py b/src/common/Settings.py index ea161e55590a54f1defc53c3c833f5a4302af972..1efe80db72cc47ba26a32241cc0bf9c15e866176 100644 --- a/src/common/Settings.py +++ b/src/common/Settings.py @@ -37,16 +37,25 @@ ENVVAR_SUFIX_SERVICE_HOST = 'SERVICE_HOST' ENVVAR_SUFIX_SERVICE_PORT_GRPC = 'SERVICE_PORT_GRPC' ENVVAR_SUFIX_SERVICE_PORT_HTTP = 'SERVICE_PORT_HTTP' +def find_missing_environment_variables( + required_environment_variables : List[str] = [] +) -> List[str]: + if ENVVAR_KUBERNETES_PORT in os.environ: + missing_variables = set(required_environment_variables).difference(set(os.environ.keys())) + else: + # We're not running in Kubernetes, nothing to wait for + missing_variables = required_environment_variables + return missing_variables + def wait_for_environment_variables( required_environment_variables : List[str] = [], wait_delay_seconds : float = DEFAULT_RESTART_DELAY ): - if ENVVAR_KUBERNETES_PORT not in os.environ: return # We're not running in Kubernetes, nothing to wait for - missing_variables = set(required_environment_variables).difference(set(os.environ.keys())) + missing_variables = find_missing_environment_variables(required_environment_variables) if len(missing_variables) == 0: return # We have all environment variables defined msg = 'Variables({:s}) are missing in Environment({:s}), restarting in {:f} seconds...' LOGGER.error(msg.format(str(missing_variables), str(os.environ), wait_delay_seconds)) time.sleep(wait_delay_seconds) - raise Exception('Restarting...') + raise Exception('Restarting...') # pylint: disable=broad-exception-raised def get_setting(name, **kwargs): value = os.environ.get(name) @@ -54,6 +63,7 @@ def get_setting(name, **kwargs): value = kwargs['settings'].pop(name, value) if value is not None: return value if 'default' in kwargs: return kwargs['default'] + # pylint: disable=broad-exception-raised raise Exception('Setting({:s}) not specified in environment or configuration'.format(str(name))) def get_env_var_name(service_name : ServiceNameEnum, env_var_group): diff --git a/src/common/message_broker/backend/nats/NatsBackend.py b/src/common/message_broker/backend/nats/NatsBackend.py index 35de3acb3043f5b0a7a08cb9a441bffe8af3462e..bcbf2a721e5d41ef122f239ee5a536eb575edcbe 100644 --- a/src/common/message_broker/backend/nats/NatsBackend.py +++ b/src/common/message_broker/backend/nats/NatsBackend.py @@ -19,8 +19,8 @@ from common.message_broker.Message import Message from .._Backend import _Backend from .NatsBackendThread import NatsBackendThread -NATS_URI_TEMPLATE_AUTH = 'nats://{:s}:{:s}@nats.{:s}.svc.cluster.local:{:s}' -NATS_URI_TEMPLATE_NOAUTH = 'nats://nats.{:s}.svc.cluster.local:{:s}' +NATS_URI_TEMPLATE_AUTH = 'nats://{:s}:{:s}@{:s}.{:s}.svc.cluster.local:{:s}' +NATS_URI_TEMPLATE_NOAUTH = 'nats://{:s}.{:s}.svc.cluster.local:{:s}' class NatsBackend(_Backend): def __init__(self, **settings) -> None: # pylint: disable=super-init-not-called @@ -32,10 +32,10 @@ class NatsBackend(_Backend): nats_password = get_setting('NATS_PASSWORD', settings=settings, default=None) if nats_username is None or nats_password is None: nats_uri = NATS_URI_TEMPLATE_NOAUTH.format( - nats_namespace, nats_client_port) + nats_namespace, nats_namespace, nats_client_port) else: nats_uri = NATS_URI_TEMPLATE_AUTH.format( - nats_username, nats_password, nats_namespace, nats_client_port) + nats_username, nats_password, nats_namespace, nats_namespace, nats_client_port) self._terminate = threading.Event() self._nats_backend_thread = NatsBackendThread(nats_uri) diff --git a/src/common/message_broker/backend/nats/NatsBackendThread.py b/src/common/message_broker/backend/nats/NatsBackendThread.py index e59e4d6835ef662e4b0ed9f92d79a45c22954a6f..0bedd2b242f7eeaa1585d0eb41c5a0bd9efe07e5 100644 --- a/src/common/message_broker/backend/nats/NatsBackendThread.py +++ b/src/common/message_broker/backend/nats/NatsBackendThread.py @@ -12,10 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import asyncio, nats, nats.errors, queue, threading +import asyncio, logging, nats, nats.errors, queue, threading from typing import List from common.message_broker.Message import Message +LOGGER = logging.getLogger(__name__) + class NatsBackendThread(threading.Thread): def __init__(self, nats_uri : str) -> None: self._nats_uri = nats_uri @@ -32,7 +34,9 @@ class NatsBackendThread(threading.Thread): self._tasks_terminated.set() async def _run_publisher(self) -> None: + LOGGER.info('[_run_publisher] NATS URI: {:s}'.format(str(self._nats_uri))) client = await nats.connect(servers=[self._nats_uri]) + LOGGER.info('[_run_publisher] Connected!') while not self._terminate.is_set(): try: message : Message = await self._publish_queue.get() @@ -47,8 +51,11 @@ class NatsBackendThread(threading.Thread): async def _run_subscriber( self, topic_name : str, timeout : float, out_queue : queue.Queue[Message], unsubscribe : threading.Event ) -> None: + LOGGER.info('[_run_subscriber] NATS URI: {:s}'.format(str(self._nats_uri))) client = await nats.connect(servers=[self._nats_uri]) + LOGGER.info('[_run_subscriber] Connected!') subscription = await client.subscribe(topic_name) + LOGGER.info('[_run_subscriber] Subscribed!') while not self._terminate.is_set() and not unsubscribe.is_set(): try: message = await subscription.next_msg(timeout) diff --git a/src/common/method_wrappers/Decorator.py b/src/common/method_wrappers/Decorator.py index c5cbfb5659df7697de93a99da39a228d5df04001..b241d3b62821c0bfe319546cbeadce79fce59db9 100644 --- a/src/common/method_wrappers/Decorator.py +++ b/src/common/method_wrappers/Decorator.py @@ -15,7 +15,7 @@ import grpc, json, logging, threading from enum import Enum from prettytable import PrettyTable -from typing import Any, Dict, List, Set, Tuple +from typing import Any, Dict, List, Optional, Set, Tuple from prometheus_client import Counter, Histogram from prometheus_client.metrics import MetricWrapperBase, INF from common.tools.grpc.Tools import grpc_message_to_json_string @@ -25,20 +25,28 @@ class MetricTypeEnum(Enum): COUNTER_STARTED = 'tfs_{component:s}_{sub_module:s}_{method:s}_counter_requests_started' COUNTER_COMPLETED = 'tfs_{component:s}_{sub_module:s}_{method:s}_counter_requests_completed' COUNTER_FAILED = 'tfs_{component:s}_{sub_module:s}_{method:s}_counter_requests_failed' + COUNTER_BLOCKED = 'tfs_{component:s}_{sub_module:s}_{method:s}_counter_requests_blocked' HISTOGRAM_DURATION = 'tfs_{component:s}_{sub_module:s}_{method:s}_histogram_duration' METRIC_TO_CLASS_PARAMS = { MetricTypeEnum.COUNTER_STARTED : (Counter, {}), MetricTypeEnum.COUNTER_COMPLETED : (Counter, {}), MetricTypeEnum.COUNTER_FAILED : (Counter, {}), + MetricTypeEnum.COUNTER_BLOCKED : (Counter, {}), MetricTypeEnum.HISTOGRAM_DURATION: (Histogram, { 'buckets': ( # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - INF) + #0.0010, 0.0025, 0.0050, 0.0075, + #0.0100, 0.0250, 0.0500, 0.0750, + #0.1000, 0.2500, 0.5000, 0.7500, + #1.0000, 2.5000, 5.0000, 7.5000, + 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, # 1~9 ms + 0.010, 0.020, 0.030, 0.040, 0.050, 0.060, 0.070, 0.080, 0.090, # 10~90 ms + 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.700, 0.800, 0.900, # 100~900 ms + 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000, 8.000, 9.000, # 1~9 sec + 10.00, 20.00, 30.00, 40.00, 50.00, 60.00, 70.00, 80.00, 90.00, # 10~90 sec + 100.0, 110.0, 120.0, INF # 100sec~2min & Infinity + ) }) } @@ -69,21 +77,45 @@ class MetricsPool: return MetricsPool.metrics[metric_name] def get_metrics( - self, method : str - ) -> Tuple[MetricWrapperBase, MetricWrapperBase, MetricWrapperBase, MetricWrapperBase]: + self, method : str, labels : Optional[Dict[str, str]] = None + ) -> Tuple[Histogram, Counter, Counter, Counter]: histogram_duration : Histogram = self.get_or_create(method, MetricTypeEnum.HISTOGRAM_DURATION) counter_started : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_STARTED) counter_completed : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_COMPLETED) counter_failed : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_FAILED) - if len(self._labels) > 0: - histogram_duration = histogram_duration.labels(**(self._labels)) - counter_started = counter_started.labels(**(self._labels)) - counter_completed = counter_completed.labels(**(self._labels)) - counter_failed = counter_failed.labels(**(self._labels)) + if labels is None and len(self._labels) > 0: + labels = self._labels + + if labels is not None and len(labels) > 0: + histogram_duration = histogram_duration.labels(**labels) + counter_started = counter_started.labels(**labels) + counter_completed = counter_completed.labels(**labels) + counter_failed = counter_failed.labels(**labels) return histogram_duration, counter_started, counter_completed, counter_failed + def get_metrics_loadgen( + self, method : str, labels : Optional[Dict[str, str]] = None + ) -> Tuple[Histogram, Counter, Counter, Counter, Counter]: + histogram_duration : Histogram = self.get_or_create(method, MetricTypeEnum.HISTOGRAM_DURATION) + counter_started : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_STARTED) + counter_completed : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_COMPLETED) + counter_failed : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_FAILED) + counter_blocked : Counter = self.get_or_create(method, MetricTypeEnum.COUNTER_BLOCKED) + + if labels is None and len(self._labels) > 0: + labels = self._labels + + if labels is not None and len(labels) > 0: + histogram_duration = histogram_duration.labels(**labels) + counter_started = counter_started.labels(**labels) + counter_completed = counter_completed.labels(**labels) + counter_failed = counter_failed.labels(**labels) + counter_blocked = counter_blocked.labels(**labels) + + return histogram_duration, counter_started, counter_completed, counter_failed, counter_blocked + def get_pretty_table(self, remove_empty_buckets : bool = True) -> PrettyTable: with MetricsPool.lock: method_to_metric_fields : Dict[str, Dict[str, Dict[str, Any]]] = dict() @@ -194,6 +226,8 @@ def safe_and_metered_rpc_method(metrics_pool : MetricsPool, logger : logging.Log # Assume not found or already exists is just a condition, not an error logger.exception('{:s} exception'.format(method_name)) counter_failed.inc() + else: + counter_completed.inc() grpc_context.abort(e.code, e.details) except Exception as e: # pragma: no cover, pylint: disable=broad-except logger.exception('{:s} exception'.format(method_name)) diff --git a/src/common/method_wrappers/tests/grafana_prometheus_component_rpc.json b/src/common/method_wrappers/tests/grafana_prometheus_component_rpc.json deleted file mode 100644 index b5b857e7573264f26289ba9a72ec5444e4ac71a4..0000000000000000000000000000000000000000 --- a/src/common/method_wrappers/tests/grafana_prometheus_component_rpc.json +++ /dev/null @@ -1,426 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 25, - "iteration": 1671297223428, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.5.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(tfs_[[component]]_rpc_[[method]]_counter_requests_started_total{pod=~\"[[pod]]\"})", - "interval": "", - "legendFormat": "started", - "queryType": "randomWalk", - "refId": "A" - }, - { - "exemplar": true, - "expr": "sum(tfs_[[component]]_rpc_[[method]]_counter_requests_completed_total{pod=~\"[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "completed", - "refId": "B" - }, - { - "exemplar": true, - "expr": "sum(tfs_[[component]]_rpc_[[method]]_counter_requests_started_total{pod=~\"[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "failed", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:935", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:936", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "cards": { - "cardPadding": null, - "cardRound": null - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "linear", - "colorScheme": "interpolateRdYlGn", - "exponent": 0.5, - "max": null, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 6 - }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, - "id": 2, - "interval": "60s", - "legend": { - "show": true - }, - "pluginVersion": "7.5.4", - "reverseYBuckets": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(\r\n max_over_time(tfs_[[component]]_rpc_[[method]]_histogram_duration_bucket{pod=~\"[[pod]]\"}[1m]) -\r\n min_over_time(tfs_[[component]]_rpc_[[method]]_histogram_duration_bucket{pod=~\"[[pod]]\"}[1m])\r\n) by (le)", - "format": "heatmap", - "instant": false, - "interval": "1m", - "intervalFactor": 1, - "legendFormat": "{{le}}", - "queryType": "randomWalk", - "refId": "A" - } - ], - "title": "Histogram", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "xBucketNumber": null, - "xBucketSize": null, - "yAxis": { - "decimals": null, - "format": "s", - "logBase": 1, - "max": null, - "min": null, - "show": true, - "splitFactor": null - }, - "yBucketBound": "auto", - "yBucketNumber": null, - "yBucketSize": null - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.5.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(tfs_[[component]]_rpc_[[method]]_histogram_duration_sum{pod=~\"[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "total time", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Total Exec Time", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:407", - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:408", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "5s", - "schemaVersion": 27, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allValue": null, - "current": { - "selected": false, - "text": "context", - "value": "context" - }, - "datasource": "prometheus", - "definition": "metrics(tfs_)", - "description": null, - "error": null, - "hide": 0, - "includeAll": false, - "label": "Component", - "multi": false, - "name": "component", - "options": [], - "query": { - "query": "metrics(tfs_)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "/tfs_(.+)_rpc_.*/", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": "", - "current": { - "selected": false, - "text": "getcontext", - "value": "getcontext" - }, - "datasource": "prometheus", - "definition": "metrics(tfs_[[component]]_rpc_)", - "description": null, - "error": null, - "hide": 0, - "includeAll": false, - "label": "Method", - "multi": false, - "name": "method", - "options": [], - "query": { - "query": "metrics(tfs_[[component]]_rpc_)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "/tfs_[[component]]_rpc_(.+)_histogram_duration_bucket/", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "prometheus", - "definition": "label_values(tfs_[[component]]_rpc_[[method]]_histogram_duration_bucket, pod)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": "Pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(tfs_[[component]]_rpc_[[method]]_histogram_duration_bucket, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "TFS / Component RPCs", - "uid": "KKxzxIFVz", - "version": 21 -} \ No newline at end of file diff --git a/src/common/method_wrappers/tests/grafana_prometheus_device_driver.json b/src/common/method_wrappers/tests/grafana_prometheus_device_driver.json deleted file mode 100644 index 2926a409b3b77b16c4e7b5d86ecd7d56f6acdebc..0000000000000000000000000000000000000000 --- a/src/common/method_wrappers/tests/grafana_prometheus_device_driver.json +++ /dev/null @@ -1,431 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 26, - "iteration": 1671318718779, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.5.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(tfs_device_driver_[[method]]_counter_requests_started_total{driver=~\"[[driver]]\", pod=~\"deviceservice-[[pod]]\"})", - "interval": "", - "legendFormat": "started", - "queryType": "randomWalk", - "refId": "A" - }, - { - "exemplar": true, - "expr": "sum(tfs_device_driver_[[method]]_counter_requests_completed_total{driver=~\"[[driver]]\", pod=~\"deviceservice-[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "completed", - "refId": "B" - }, - { - "exemplar": true, - "expr": "sum(tfs_device_driver_[[method]]_counter_requests_failed_total{driver=~\"[[driver]]\", pod=~\"deviceservice-[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "failed", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:864", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:865", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "cards": { - "cardPadding": null, - "cardRound": null - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "linear", - "colorScheme": "interpolateRdYlGn", - "exponent": 0.5, - "max": null, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 6 - }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, - "id": 2, - "interval": "60s", - "legend": { - "show": true - }, - "pluginVersion": "7.5.4", - "reverseYBuckets": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(\r\n max_over_time(tfs_device_driver_[[method]]_histogram_duration_bucket{driver=~\"[[driver]]\", pod=~\"deviceservice-[[pod]]\"}[1m]) -\r\n min_over_time(tfs_device_driver_[[method]]_histogram_duration_bucket{driver=~\"[[driver]]\", pod=~\"deviceservice-[[pod]]\"}[1m])\r\n) by (le)", - "format": "heatmap", - "instant": false, - "interval": "60s", - "intervalFactor": 1, - "legendFormat": "{{le}}", - "queryType": "randomWalk", - "refId": "A" - } - ], - "timeFrom": null, - "title": "Histogram", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "xBucketNumber": null, - "xBucketSize": null, - "yAxis": { - "decimals": null, - "format": "s", - "logBase": 1, - "max": null, - "min": null, - "show": true, - "splitFactor": null - }, - "yBucketBound": "auto", - "yBucketNumber": null, - "yBucketSize": null - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.5.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(tfs_device_driver_[[method]]_histogram_duration_sum{driver=~\"[[driver]]\", pod=~\"deviceservice-[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "total time", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Total Exec Time", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:407", - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:408", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "5s", - "schemaVersion": 27, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allValue": "", - "current": { - "selected": false, - "text": "setconfig", - "value": "setconfig" - }, - "datasource": "prometheus", - "definition": "metrics(tfs_device_driver_.+)", - "description": null, - "error": null, - "hide": 0, - "includeAll": false, - "label": "Method", - "multi": false, - "name": "method", - "options": [], - "query": { - "query": "metrics(tfs_device_driver_.+)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "/tfs_device_driver_(.+config)_histogram_duration_bucket/", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "prometheus", - "definition": "label_values(tfs_device_driver_[[method]]_histogram_duration_bucket, driver)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": "Driver", - "multi": true, - "name": "driver", - "options": [], - "query": { - "query": "label_values(tfs_device_driver_[[method]]_histogram_duration_bucket, driver)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "prometheus", - "definition": "label_values(tfs_device_driver_[[method]]_histogram_duration_bucket, pod)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": "Pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(tfs_device_driver_[[method]]_histogram_duration_bucket, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "/deviceservice-(.*)/", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "TFS / Device / Driver", - "uid": "eAg-wsOVk", - "version": 30 -} \ No newline at end of file diff --git a/src/common/method_wrappers/tests/grafana_prometheus_service_handler.json b/src/common/method_wrappers/tests/grafana_prometheus_service_handler.json deleted file mode 100644 index 48e770afe4bba9c2eb5df76d3532bf35d6cfe192..0000000000000000000000000000000000000000 --- a/src/common/method_wrappers/tests/grafana_prometheus_service_handler.json +++ /dev/null @@ -1,432 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": 27, - "iteration": 1671319012315, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 4, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.5.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(tfs_service_handler_[[method]]_counter_requests_started_total{handler=~\"[[handler]]\", pod=~\"serviceservice-[[pod]]\"})", - "instant": false, - "interval": "", - "legendFormat": "started", - "queryType": "randomWalk", - "refId": "A" - }, - { - "exemplar": true, - "expr": "sum(tfs_service_handler_[[method]]_counter_requests_completed_total{handler=~\"[[handler]]\", pod=~\"serviceservice-[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "completed", - "refId": "B" - }, - { - "exemplar": true, - "expr": "sum(tfs_service_handler_[[method]]_counter_requests_failed_total{handler=~\"[[handler]]\", pod=~\"serviceservice-[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "failed", - "refId": "C" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Requests", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:935", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:936", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "cards": { - "cardPadding": null, - "cardRound": null - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "linear", - "colorScheme": "interpolateRdYlGn", - "exponent": 0.5, - "max": null, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 6 - }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, - "id": 2, - "interval": "60s", - "legend": { - "show": true - }, - "pluginVersion": "7.5.4", - "reverseYBuckets": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(\r\n max_over_time(tfs_service_handler_[[method]]_histogram_duration_bucket{handler=~\"[[handler]]\", pod=~\"serviceservice-[[pod]]\"}[1m]) -\r\n min_over_time(tfs_service_handler_[[method]]_histogram_duration_bucket{handler=~\"[[handler]]\", pod=~\"serviceservice-[[pod]]\"}[1m])\r\n) by (le)", - "format": "heatmap", - "instant": false, - "interval": "1m", - "intervalFactor": 1, - "legendFormat": "{{le}}", - "queryType": "randomWalk", - "refId": "A" - } - ], - "timeFrom": null, - "title": "Histogram", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "xBucketNumber": null, - "xBucketSize": null, - "yAxis": { - "decimals": null, - "format": "s", - "logBase": 1, - "max": null, - "min": null, - "show": true, - "splitFactor": null - }, - "yBucketBound": "auto", - "yBucketNumber": null, - "yBucketSize": null - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "prometheus", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.5.4", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "exemplar": true, - "expr": "sum(tfs_service_handler_[[method]]_histogram_duration_sum{handler=~\"[[handler]]\", pod=~\"serviceservice-[[pod]]\"})", - "hide": false, - "interval": "", - "legendFormat": "total time", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Total Exec Time", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:407", - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:408", - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "5s", - "schemaVersion": 27, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allValue": "", - "current": { - "selected": false, - "text": "setendpoint", - "value": "setendpoint" - }, - "datasource": "prometheus", - "definition": "metrics(tfs_service_handler_.+)", - "description": null, - "error": null, - "hide": 0, - "includeAll": false, - "label": "Method", - "multi": false, - "name": "method", - "options": [], - "query": { - "query": "metrics(tfs_service_handler_.+)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "/tfs_service_handler_(.+)_histogram_duration_bucket/", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "prometheus", - "definition": "label_values(tfs_service_handler_[[method]]_histogram_duration_bucket, handler)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": "Handler", - "multi": true, - "name": "handler", - "options": [], - "query": { - "query": "label_values(tfs_service_handler_[[method]]_histogram_duration_bucket, handler)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".*", - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "prometheus", - "definition": "label_values(tfs_service_handler_[[method]]_histogram_duration_bucket, pod)", - "description": null, - "error": null, - "hide": 0, - "includeAll": true, - "label": "Pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(tfs_service_handler_[[method]]_histogram_duration_bucket, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "/serviceservice-(.*)/", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "TFS / Service / Handler", - "uid": "DNOhOIF4k", - "version": 16 -} \ No newline at end of file diff --git a/src/common/tools/context_queries/Connection.py b/src/common/tools/context_queries/Connection.py new file mode 100644 index 0000000000000000000000000000000000000000..3021335131332dab73d6d645f4c7937f499732ef --- /dev/null +++ b/src/common/tools/context_queries/Connection.py @@ -0,0 +1,43 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Optional +from common.proto.context_pb2 import Connection, ConnectionId +from context.client.ContextClient import ContextClient + +LOGGER = logging.getLogger(__name__) + +def get_connection_by_id( + context_client : ContextClient, connection_id : ConnectionId, rw_copy : bool = False +) -> Optional[Connection]: + try: + ro_connection : Connection = context_client.GetConnection(connection_id) + if not rw_copy: return ro_connection + rw_connection = Connection() + rw_connection.CopyFrom(ro_connection) + return rw_connection + except grpc.RpcError as e: + if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member + #connection_uuid = connection_id.connection_uuid.uuid + #LOGGER.exception('Unable to get connection({:s})'.format(str(connection_uuid))) + return None + +def get_connection_by_uuid( + context_client : ContextClient, connection_uuid : str, rw_copy : bool = False +) -> Optional[Connection]: + # pylint: disable=no-member + connection_id = ConnectionId() + connection_id.connection_uuid.uuid = connection_uuid + return get_connection_by_id(context_client, connection_id, rw_copy=rw_copy) diff --git a/src/common/tools/context_queries/Device.py b/src/common/tools/context_queries/Device.py index 166882f2fd90475d6bc64b4c4a7c44535fc6aa64..95f0e90b740d3b167f09db394e259599db20a59b 100644 --- a/src/common/tools/context_queries/Device.py +++ b/src/common/tools/context_queries/Device.py @@ -14,23 +14,34 @@ import grpc, logging from typing import List, Optional, Set -from common.proto.context_pb2 import ContextId, Device, DeviceId, Empty, Topology, TopologyId +from common.proto.context_pb2 import ContextId, Device, DeviceFilter, Empty, Topology, TopologyId from common.tools.object_factory.Topology import json_topology_id from context.client.ContextClient import ContextClient LOGGER = logging.getLogger(__name__) -def get_device(context_client : ContextClient, device_uuid : str, rw_copy : bool = False) -> Optional[Device]: +def get_device( + context_client : ContextClient, device_uuid : str, rw_copy : bool = False, + include_endpoints : bool = True, include_config_rules : bool = True, include_components : bool = True +) -> Optional[Device]: + device_filter = DeviceFilter() + device_id = device_filter.device_ids.device_ids.add() # pylint: disable=no-member + device_id.device_uuid.uuid = device_uuid + device_filter.include_endpoints = include_endpoints + device_filter.include_config_rules = include_config_rules + device_filter.include_components = include_components + try: - # pylint: disable=no-member - device_id = DeviceId() - device_id.device_uuid.uuid = device_uuid - ro_device = context_client.GetDevice(device_id) + ro_devices = context_client.SelectDevice(device_filter) + if len(ro_devices.devices) == 0: return None + assert len(ro_devices.devices) == 1 + ro_device = ro_devices.devices[0] if not rw_copy: return ro_device rw_device = Device() rw_device.CopyFrom(ro_device) return rw_device - except grpc.RpcError: + except grpc.RpcError as e: + if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member #LOGGER.exception('Unable to get Device({:s})'.format(str(device_uuid))) return None diff --git a/src/common/tools/context_queries/Service.py b/src/common/tools/context_queries/Service.py index 25716152c3f37fec93df340073bae8871e16c3a7..b3b74827a5c86838cb4330ae89c1297652dc59b0 100644 --- a/src/common/tools/context_queries/Service.py +++ b/src/common/tools/context_queries/Service.py @@ -15,25 +15,43 @@ import grpc, logging from typing import Optional from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import Service, ServiceId +from common.proto.context_pb2 import Service, ServiceFilter, ServiceId from context.client.ContextClient import ContextClient LOGGER = logging.getLogger(__name__) -def get_service( - context_client : ContextClient, service_uuid : str, context_uuid : str = DEFAULT_CONTEXT_NAME, - rw_copy : bool = False - ) -> Optional[Service]: +def get_service_by_id( + context_client : ContextClient, service_id : ServiceId, rw_copy : bool = False, + include_endpoint_ids : bool = True, include_constraints : bool = True, include_config_rules : bool = True +) -> Optional[Service]: + service_filter = ServiceFilter() + service_filter.service_ids.service_ids.append(service_id) # pylint: disable=no-member + service_filter.include_endpoint_ids = include_endpoint_ids + service_filter.include_constraints = include_constraints + service_filter.include_config_rules = include_config_rules + try: - # pylint: disable=no-member - service_id = ServiceId() - service_id.context_id.context_uuid.uuid = context_uuid - service_id.service_uuid.uuid = service_uuid - ro_service = context_client.GetService(service_id) + ro_services = context_client.SelectService(service_filter) + if len(ro_services.services) == 0: return None + assert len(ro_services.services) == 1 + ro_service = ro_services.services[0] if not rw_copy: return ro_service rw_service = Service() rw_service.CopyFrom(ro_service) return rw_service - except grpc.RpcError: + except grpc.RpcError as e: + if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member #LOGGER.exception('Unable to get service({:s} / {:s})'.format(str(context_uuid), str(service_uuid))) return None + +def get_service_by_uuid( + context_client : ContextClient, service_uuid : str, context_uuid : str = DEFAULT_CONTEXT_NAME, + rw_copy : bool = False, include_endpoint_ids : bool = True, include_constraints : bool = True, + include_config_rules : bool = True +) -> Optional[Service]: + service_id = ServiceId() + service_id.context_id.context_uuid.uuid = context_uuid # pylint: disable=no-member + service_id.service_uuid.uuid = service_uuid # pylint: disable=no-member + return get_service_by_id( + context_client, service_id, rw_copy=rw_copy, include_endpoint_ids=include_endpoint_ids, + include_constraints=include_constraints, include_config_rules=include_config_rules) diff --git a/src/common/tools/context_queries/Slice.py b/src/common/tools/context_queries/Slice.py index e5fb86d7a5aa8c08bf323f641737efcf8eec14ef..c3ce572fce8b3fb209b46b561a4004979dce4913 100644 --- a/src/common/tools/context_queries/Slice.py +++ b/src/common/tools/context_queries/Slice.py @@ -15,25 +15,47 @@ import grpc, logging from typing import Optional from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import Slice, SliceId +from common.proto.context_pb2 import Slice, SliceFilter, SliceId from context.client.ContextClient import ContextClient LOGGER = logging.getLogger(__name__) -def get_slice( - context_client : ContextClient, slice_uuid : str, context_uuid : str = DEFAULT_CONTEXT_NAME, - rw_copy : bool = False - ) -> Optional[Slice]: +def get_slice_by_id( + context_client : ContextClient, slice_id : SliceId, rw_copy : bool = False, include_endpoint_ids : bool = True, + include_constraints : bool = True, include_service_ids : bool = True, include_subslice_ids : bool = True, + include_config_rules : bool = True +) -> Optional[Slice]: + slice_filter = SliceFilter() + slice_id = slice_filter.slice_ids.slice_ids.append(slice_id) # pylint: disable=no-member + slice_filter.include_endpoint_ids = include_endpoint_ids + slice_filter.include_constraints = include_constraints + slice_filter.include_service_ids = include_service_ids + slice_filter.include_subslice_ids = include_subslice_ids + slice_filter.include_config_rules = include_config_rules + try: - # pylint: disable=no-member - slice_id = SliceId() - slice_id.context_id.context_uuid.uuid = context_uuid - slice_id.slice_uuid.uuid = slice_uuid - ro_slice = context_client.GetSlice(slice_id) + ro_slices = context_client.SelectSlice(slice_filter) + if len(ro_slices.slices) == 0: return None + assert len(ro_slices.slices) == 1 + ro_slice = ro_slices.slices[0] if not rw_copy: return ro_slice rw_slice = Slice() rw_slice.CopyFrom(ro_slice) return rw_slice - except grpc.RpcError: + except grpc.RpcError as e: + if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member #LOGGER.exception('Unable to get slice({:s} / {:s})'.format(str(context_uuid), str(slice_uuid))) return None + +def get_slice_by_uuid( + context_client : ContextClient, slice_uuid : str, context_uuid : str = DEFAULT_CONTEXT_NAME, + rw_copy : bool = False, include_endpoint_ids : bool = True, include_constraints : bool = True, + include_service_ids : bool = True, include_subslice_ids : bool = True, include_config_rules : bool = True +) -> Optional[Slice]: + slice_id = SliceId() + slice_id.context_id.context_uuid.uuid = context_uuid # pylint: disable=no-member + slice_id.slice_uuid.uuid = slice_uuid # pylint: disable=no-member + return get_slice_by_id( + context_client, slice_id, rw_copy=rw_copy, include_endpoint_ids=include_endpoint_ids, + include_constraints=include_constraints, include_service_ids=include_service_ids, + include_subslice_ids=include_subslice_ids, include_config_rules=include_config_rules) diff --git a/src/common/tools/descriptor/Loader.py b/src/common/tools/descriptor/Loader.py index 0e1d8c7371e87b47bfc47a4242e00039add48e7f..916a73d300011c62fc008fc7437df8a71f6a9838 100644 --- a/src/common/tools/descriptor/Loader.py +++ b/src/common/tools/descriptor/Loader.py @@ -85,6 +85,7 @@ class DescriptorLoader: service_client : Optional[ServiceClient] = None, slice_client : Optional[SliceClient] = None ) -> None: if (descriptors is None) == (descriptors_file is None): + # pylint: disable=broad-exception-raised raise Exception('Exactly one of "descriptors" or "descriptors_file" is required') if descriptors_file is not None: @@ -222,13 +223,13 @@ class DescriptorLoader: self.__topologies_add = get_descriptors_add_topologies(self.__topologies) if self.__dummy_mode: - self._dummy_mode() + self._load_dummy_mode() else: - self._normal_mode() + self._load_normal_mode() return self.__results - def _dummy_mode(self) -> None: + def _load_dummy_mode(self) -> None: # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. self.__ctx_cli.connect() self._process_descr('context', 'add', self.__ctx_cli.SetContext, Context, self.__contexts_add ) @@ -238,11 +239,16 @@ class DescriptorLoader: self._process_descr('service', 'add', self.__ctx_cli.SetService, Service, self.__services ) self._process_descr('slice', 'add', self.__ctx_cli.SetSlice, Slice, self.__slices ) self._process_descr('connection', 'add', self.__ctx_cli.SetConnection, Connection, self.__connections ) - self._process_descr('context', 'update', self.__ctx_cli.SetContext, Context, self.__contexts ) - self._process_descr('topology', 'update', self.__ctx_cli.SetTopology, Topology, self.__topologies ) + + # Update context and topology is useless: + # - devices and links are assigned to topologies automatically by Context component + # - topologies, services, and slices are assigned to contexts automatically by Context component + #self._process_descr('context', 'update', self.__ctx_cli.SetContext, Context, self.__contexts ) + #self._process_descr('topology', 'update', self.__ctx_cli.SetTopology, Topology, self.__topologies ) + #self.__ctx_cli.close() - def _normal_mode(self) -> None: + def _load_normal_mode(self) -> None: # Normal mode: follows the automated workflows in the different components assert len(self.__connections) == 0, 'in normal mode, connections should not be set' @@ -265,8 +271,12 @@ class DescriptorLoader: self._process_descr('service', 'update', self.__svc_cli.UpdateService, Service, self.__services ) self._process_descr('slice', 'add', self.__slc_cli.CreateSlice, Slice, self.__slices_add ) self._process_descr('slice', 'update', self.__slc_cli.UpdateSlice, Slice, self.__slices ) - self._process_descr('context', 'update', self.__ctx_cli.SetContext, Context, self.__contexts ) - self._process_descr('topology', 'update', self.__ctx_cli.SetTopology, Topology, self.__topologies ) + + # Update context and topology is useless: + # - devices and links are assigned to topologies automatically by Context component + # - topologies, services, and slices are assigned to contexts automatically by Context component + #self._process_descr('context', 'update', self.__ctx_cli.SetContext, Context, self.__contexts ) + #self._process_descr('topology', 'update', self.__ctx_cli.SetTopology, Topology, self.__topologies ) #self.__slc_cli.close() #self.__svc_cli.close() @@ -321,7 +331,35 @@ class DescriptorLoader: response = self.__ctx_cli.ListSlices(ContextId(**json_context_id(context_uuid))) assert len(response.slices) == num_slices - def unload(self) -> None: + def _unload_dummy_mode(self) -> None: + # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. + self.__ctx_cli.connect() + + for _, slice_list in self.slices.items(): + for slice_ in slice_list: + self.__ctx_cli.RemoveSlice(SliceId(**slice_['slice_id'])) + + for _, service_list in self.services.items(): + for service in service_list: + self.__ctx_cli.RemoveService(ServiceId(**service['service_id'])) + + for link in self.links: + self.__ctx_cli.RemoveLink(LinkId(**link['link_id'])) + + for device in self.devices: + self.__ctx_cli.RemoveDevice(DeviceId(**device['device_id'])) + + for _, topology_list in self.topologies.items(): + for topology in topology_list: + self.__ctx_cli.RemoveTopology(TopologyId(**topology['topology_id'])) + + for context in self.contexts: + self.__ctx_cli.RemoveContext(ContextId(**context['context_id'])) + + #self.__ctx_cli.close() + + def _unload_normal_mode(self) -> None: + # Normal mode: follows the automated workflows in the different components self.__ctx_cli.connect() self.__dev_cli.connect() self.__svc_cli.connect() @@ -348,6 +386,17 @@ class DescriptorLoader: for context in self.contexts: self.__ctx_cli.RemoveContext(ContextId(**context['context_id'])) + #self.__ctx_cli.close() + #self.__dev_cli.close() + #self.__svc_cli.close() + #self.__slc_cli.close() + + def unload(self) -> None: + if self.__dummy_mode: + self._unload_dummy_mode() + else: + self._unload_normal_mode() + def compose_notifications(results : TypeResults) -> TypeNotificationList: notifications = [] for entity_name, action_name, num_ok, error_list in results: diff --git a/src/common/tools/object_factory/Device.py b/src/common/tools/object_factory/Device.py index 0cc4555d455bf28ac2143a5d58b87e084a8360c7..66c87b14dd866d44b5d48addf93d172aea962f8e 100644 --- a/src/common/tools/object_factory/Device.py +++ b/src/common/tools/object_factory/Device.py @@ -43,6 +43,9 @@ DEVICE_MICROWAVE_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY] DEVICE_P4_TYPE = DeviceTypeEnum.P4_SWITCH.value DEVICE_P4_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_P4] +DEVICE_TFS_TYPE = DeviceTypeEnum.TERAFLOWSDN_CONTROLLER.value +DEVICE_TFS_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN] + def json_device_id(device_uuid : str): return {'device_uuid': {'uuid': device_uuid}} @@ -120,6 +123,13 @@ def json_device_p4_disabled( return json_device( device_uuid, DEVICE_P4_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers) +def json_device_tfs_disabled( + device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [], + drivers : List[Dict] = DEVICE_TFS_DRIVERS + ): + return json_device( + device_uuid, DEVICE_TFS_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers) + def json_device_connect_rules(address : str, port : int, settings : Dict = {}): return [ json_config_rule_set('_connect/address', address), diff --git a/src/common/type_checkers/Assertions.py b/src/common/type_checkers/Assertions.py index c0442d8770c682ac1eea032980b58e7028be90c4..d5476a9534ca6e2d74ba16d3af71ed367bc5ab51 100644 --- a/src/common/type_checkers/Assertions.py +++ b/src/common/type_checkers/Assertions.py @@ -33,6 +33,7 @@ def validate_device_driver_enum(message): 'DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', 'DEVICEDRIVER_ONF_TR_352', 'DEVICEDRIVER_XR', + 'DEVICEDRIVER_IETF_L2VPN', ] def validate_device_operational_status_enum(message): @@ -68,7 +69,9 @@ def validate_service_state_enum(message): 'SERVICESTATUS_UNDEFINED', 'SERVICESTATUS_PLANNED', 'SERVICESTATUS_ACTIVE', + 'SERVICESTATUS_UPDATING', 'SERVICESTATUS_PENDING_REMOVAL', + 'SERVICESTATUS_SLA_VIOLATED', ] diff --git a/src/common/type_checkers/Checkers.py b/src/common/type_checkers/Checkers.py index 085ba572c39165c8ae11e2a546b9439a4e93962b..e61bd3ccd338b922598a2b7b37af56b22cc11267 100644 --- a/src/common/type_checkers/Checkers.py +++ b/src/common/type_checkers/Checkers.py @@ -30,7 +30,7 @@ def chk_attribute(name : str, container : Dict, container_name : str, **kwargs): if 'default' in kwargs: return kwargs['default'] raise AttributeError('Missing object({:s}) in container({:s})'.format(str(name), str(container_name))) -def chk_type(name : str, value : Any, type_or_types : Union[type, Set[type]] = set()) -> Any: +def chk_type(name : str, value : Any, type_or_types : Union[type, Set[type], Tuple[type]] = set()) -> Any: if isinstance(value, type_or_types): return value msg = '{}({}) is of a wrong type({}). Accepted type_or_types({}).' raise TypeError(msg.format(str(name), str(value), type(value).__name__, str(type_or_types))) diff --git a/src/compute/service/__main__.py b/src/compute/service/__main__.py index 9705e3187ffff633a4d127855c1c57afcf397e39..6c744d0dcef67fef1d8ac719eaba9420b530fe58 100644 --- a/src/compute/service/__main__.py +++ b/src/compute/service/__main__.py @@ -22,6 +22,7 @@ from .ComputeService import ComputeService from .rest_server.RestServer import RestServer from .rest_server.nbi_plugins.debug_api import register_debug_api from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn +from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss terminate = threading.Event() LOGGER = None @@ -58,12 +59,13 @@ def main(): grpc_service.start() rest_server = RestServer() + register_ietf_l2vpn(rest_server) # Registering L2VPN entrypoint + register_ietf_nss(rest_server) # Registering NSS entrypoint register_debug_api(rest_server) - register_ietf_l2vpn(rest_server) rest_server.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py index f95b532af4ba01968d17bc3958e1cffbf84a5e7f..ed25dbab3cd6b07ef73d64c5d37ad64e85353c02 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py @@ -74,4 +74,18 @@ BEARER_MAPPINGS = { 'R3:1/3': ('R3', '1/3', '5.3.1.3', None, 0, None, None, None, None), 'R4:1/2': ('R4', '1/2', '5.4.1.2', None, 0, None, None, None, None), 'R4:1/3': ('R4', '1/3', '5.4.1.3', None, 0, None, None, None, None), + + # OFC'23 + 'PE1:1/1': ('PE1', '1/1', '10.1.1.1', None, 0, None, None, None, None), + 'PE1:1/2': ('PE1', '1/2', '10.1.1.2', None, 0, None, None, None, None), + 'PE2:1/1': ('PE2', '1/1', '10.2.1.1', None, 0, None, None, None, None), + 'PE2:1/2': ('PE2', '1/2', '10.2.1.2', None, 0, None, None, None, None), + 'PE3:1/1': ('PE3', '1/1', '10.3.1.1', None, 0, None, None, None, None), + 'PE3:1/2': ('PE3', '1/2', '10.3.1.2', None, 0, None, None, None, None), + 'PE4:1/1': ('PE4', '1/1', '10.4.1.1', None, 0, None, None, None, None), + 'PE4:1/2': ('PE4', '1/2', '10.4.1.2', None, 0, None, None, None, None), + + 'R149:eth-1/0/22': ('R149', 'eth-1/0/22', '5.5.5.5', None, 0, None, None, '5.5.5.1', '100'), + 'R155:eth-1/0/22': ('R155', 'eth-1/0/22', '5.5.5.1', None, 0, None, None, '5.5.5.5', '100'), + 'R199:eth-1/0/21': ('R199', 'eth-1/0/21', '5.5.5.6', None, 0, None, None, '5.5.5.5', '100'), } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py index 2db231221faad1af2c7f0651dee2b95427e97acd..9a33cd2281d4dfd7a0a8dac964b9b35d7975cf28 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py @@ -17,11 +17,11 @@ from flask import request from flask.json import jsonify from flask_restful import Resource from common.proto.context_pb2 import SliceStatusEnum -from common.tools.context_queries.Slice import get_slice +from common.tools.context_queries.Slice import get_slice_by_uuid from context.client.ContextClient import ContextClient from slice.client.SliceClient import SliceClient -from .tools.Authentication import HTTP_AUTH -from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR +from ..tools.Authentication import HTTP_AUTH +from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR LOGGER = logging.getLogger(__name__) @@ -34,7 +34,7 @@ class L2VPN_Service(Resource): try: context_client = ContextClient() - target = get_slice(context_client, vpn_id, rw_copy=True) + target = get_slice_by_uuid(context_client, vpn_id, rw_copy=True) if target is None: raise Exception('VPN({:s}) not found in database'.format(str(vpn_id))) @@ -59,7 +59,7 @@ class L2VPN_Service(Resource): try: context_client = ContextClient() - target = get_slice(context_client, vpn_id) + target = get_slice_by_uuid(context_client, vpn_id) if target is None: LOGGER.warning('VPN({:s}) not found in database. Nothing done.'.format(str(vpn_id))) else: diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py index dcdecb70ffff4059e557d1dadbbb958a4e264fab..69676bd0d0165160da4e64c515d04b5a3252102c 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py @@ -22,9 +22,9 @@ from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import SliceStatusEnum, Slice from slice.client.SliceClient import SliceClient from .schemas.vpn_service import SCHEMA_VPN_SERVICE -from .tools.Authentication import HTTP_AUTH -from .tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR -from .tools.Validator import validate_message +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR +from compute.service.rest_server.nbi_plugins.tools.Validator import validate_message +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH LOGGER = logging.getLogger(__name__) diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py index b89fa2207d1cd69e30612e8cecc8aa0f325e9dd3..7e829479a0a3dbd4968d488a22dc62219fa5376c 100644 --- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py +++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py @@ -20,7 +20,7 @@ from flask.wrappers import Response from flask_restful import Resource from werkzeug.exceptions import UnsupportedMediaType from common.proto.context_pb2 import Slice -from common.tools.context_queries.Slice import get_slice +from common.tools.context_queries.Slice import get_slice_by_uuid from common.tools.grpc.ConfigRules import update_config_rule_custom from common.tools.grpc.Constraints import ( update_constraint_custom_dict, update_constraint_endpoint_location, update_constraint_endpoint_priority, @@ -30,11 +30,10 @@ from common.tools.grpc.Tools import grpc_message_to_json_string from context.client.ContextClient import ContextClient from slice.client.SliceClient import SliceClient from .schemas.site_network_access import SCHEMA_SITE_NETWORK_ACCESS -from .tools.Authentication import HTTP_AUTH -from .tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR -from .tools.Validator import validate_message -from .Constants import ( - BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU) +from compute.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH +from compute.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR +from compute.service.rest_server.nbi_plugins.tools.Validator import validate_message +from .Constants import BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU LOGGER = logging.getLogger(__name__) @@ -69,7 +68,7 @@ def process_site_network_access(context_client : ContextClient, site_id : str, s address_ip, address_prefix, remote_router, circuit_id ) = mapping - target = get_slice(context_client, vpn_id, rw_copy=True) + target = get_slice_by_uuid(context_client, vpn_id, rw_copy=True) if target is None: raise Exception('VPN({:s}) not found in database'.format(str(vpn_id))) endpoint_ids = target.slice_endpoint_ids # pylint: disable=no-member diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py new file mode 100644 index 0000000000000000000000000000000000000000..32ee81e801e1d93a23a8a752aa6c63cfffe43a82 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Service.py @@ -0,0 +1,78 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 +from flask.json import jsonify +from flask_restful import Resource +from common.proto.context_pb2 import SliceStatusEnum +from common.tools.context_queries.Slice import get_slice_by_uuid +from common.tools.grpc.Tools import grpc_message_to_json +from context.client.ContextClient import ContextClient +from slice.client.SliceClient import SliceClient +from ..tools.Authentication import HTTP_AUTH +from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR + +LOGGER = logging.getLogger(__name__) + +class NSS_Service(Resource): + @HTTP_AUTH.login_required + def get(self, slice_id : str): + LOGGER.debug('GET Slice ID: {:s}'.format(str(slice_id))) + try: + context_client = ContextClient() + + target = get_slice_by_uuid(context_client, slice_id, rw_copy=True) + if target is None: + raise Exception('Slice({:s}) not found in database'.format(str(slice_id))) + + if target.slice_id.slice_uuid.uuid != slice_id: # pylint: disable=no-member + raise Exception('Slice retrieval failed. Wrong Slice Id was returned') + + slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE + slice_status = target.slice_status.slice_status # pylint: disable=no-member + response = jsonify(grpc_message_to_json(target)) + response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT + + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Something went wrong Retrieving Slice({:s})'.format(str(slice_id))) + response = jsonify({'error': str(e)}) + response.status_code = HTTP_SERVERERROR + return response + + + @HTTP_AUTH.login_required + def delete(self, slice_id : str): + LOGGER.debug('DELETE Slice ID: {:s}'.format(str(slice_id))) + try: + context_client = ContextClient() + target = get_slice_by_uuid(context_client, slice_id) + + response = jsonify({}) + response.status_code = HTTP_OK + + if target is None: + LOGGER.warning('Slice({:s}) not found in database. Nothing done.'.format(str(slice_id))) + response.status_code = HTTP_NOCONTENT + else: + if target.slice_id.slice_uuid.uuid != slice_id: # pylint: disable=no-member + raise Exception('Slice retrieval failed. Wrong Slice Id was returned') + slice_client = SliceClient() + slice_client.DeleteSlice(target.slice_id) + LOGGER.debug(f"Slice({slice_id}) successfully deleted") + + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Something went wrong Deleting Slice({:s})'.format(str(slice_id))) + response = jsonify({'error': str(e)}) + response.status_code = HTTP_SERVERERROR + return response \ No newline at end of file diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py new file mode 100644 index 0000000000000000000000000000000000000000..72b09f2b7d1422da2554a3dfe873a6bcff87413d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/NSS_Services.py @@ -0,0 +1,122 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json +import logging +import ssl +import uuid +from typing import Dict +from flask.json import jsonify +from flask_restful import Resource +from flask import request + +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import Slice, SliceStatusEnum, EndPointId, Constraint +from common.tools.grpc.Tools import grpc_message_to_json +from ..tools.Authentication import HTTP_AUTH +from ..tools.HttpStatusCodes import HTTP_BADREQUEST, HTTP_OK, HTTP_CREATED, HTTP_SERVERERROR +from werkzeug.exceptions import UnsupportedMediaType + +from slice.client.SliceClient import SliceClient +from .bindings import load_json_data +from .bindings.network_slice_services import NetworkSliceServices + +LOGGER = logging.getLogger(__name__) + +class NSS_Services(Resource): + @HTTP_AUTH.login_required + def get(self): + response = jsonify({"message": "All went well!"}) + # TODO Return list of current network-slice-services + return response + + @HTTP_AUTH.login_required + def post(self): + if not request.is_json: + raise UnsupportedMediaType('JSON payload is required') + request_data = json.dumps(request.json) + response = jsonify({}) + response.status_code = HTTP_CREATED + + slices: NetworkSliceServices = load_json_data(request_data, NetworkSliceServices)[0] + for ietf_slice in slices.slice_service: + slice_request: Slice = Slice() + # Meta information + # TODO implement name and owner based on "tags" + slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + slice_request.slice_id.slice_uuid.uuid = ietf_slice.service_id() + # TODO map with admin status of IETF Slice + slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED + + list_endpoints = [] + for sdp in ietf_slice.sdps().sdp: + endpoint = EndPointId() + endpoint.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + endpoint.device_id.device_uuid.uuid = sdp.node_id() + endpoint.endpoint_uuid.uuid = sdp.sdp_id() + list_endpoints.append(endpoint) + slice_request.slice_endpoint_ids.extend(list_endpoints) + + # TODO Map connectivity_groups and connectivity constructs to real connections + LOGGER.debug(f"Connection groups detected: {len(ietf_slice.connection_groups().connection_group())}") + list_constraints = [] + for cg in ietf_slice.connection_groups().connection_group: + for cc in cg.connectivity_construct: + if cc.slo_sle_policy.custom: + with cc.slo_sle_policy.custom as slo: + for metric_bound in slo.service_slo_sle_policy().metric_bounds().metric_bound: + metric_type = str(metric_bound.metric_type()).casefold() + if metric_type == "service-slo-two-way-bandwidth": # TODO fix to two way! + constraint = Constraint() + metric_unit = metric_bound.metric_unit().casefold() + capacity = float(metric_bound.bound()) # Assuming capacity already in Gbps + if metric_unit == "mbps": + capacity /= 1E3 + elif metric_unit != "gbps": + LOGGER.warning(f"Invalided metric unit ({metric_bound.metric_unit()}), must be Mbps or Gbps") + response.status_code = HTTP_SERVERERROR + return response + constraint.sla_capacity.capacity_gbps = capacity + list_constraints.append(constraint) + + elif metric_type == "service-slo-one-way-delay": + if metric_bound.metric_unit().casefold() == "ms": + latency = int(metric_bound.bound()) + else: + LOGGER.warning(f"Invalided metric unit ({metric_bound.metric_unit()}), must be \"ms\" ") + response.status_code = HTTP_SERVERERROR + return response + constraint = Constraint() + constraint.sla_latency.e2e_latency_ms = latency + list_constraints.append(constraint) + + elif metric_type == "service-slo-availability": + availability = float(metric_bound.bound()) + if availability > 100.0 or availability < 0.0: + raise Exception(f'Slice SLO availability ({availability}) must be constrained [0,100]') + constraint = Constraint() + constraint.sla_availability.availability = availability + # TODO not really necessary, remove after OFC2023 + constraint.sla_availability.num_disjoint_paths = 0 + constraint.sla_availability.all_active = False + list_constraints.append(constraint) + + slice_request.slice_constraints.extend(list_constraints) + LOGGER.debug(grpc_message_to_json(slice_request)) # TODO remove + # TODO adding owner, needs to be recoded after updating the bindings + owner = request.json["data"]["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["service-tags"][0]["value"] + slice_request.slice_owner.owner_string = owner + slice_request.slice_owner.owner_uuid.uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, owner)) + slice_client = SliceClient() + slice_client.CreateSlice(slice_request) + return response diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8aca124acfd15b2003b4272cf0b3103dbca3bdb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/__init__.py @@ -0,0 +1,31 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +# IETF draft-ietf-teas-ietf-network-slice-nbi-yang-02 - IETF Network Slice Service YANG Model +# Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/ + +from flask_restful import Resource +from compute.service.rest_server.RestServer import RestServer +from .NSS_Services import NSS_Services +from .NSS_Service import NSS_Service + +URL_PREFIX = '/data/ietf-network-slice-service:ietf-nss' + +def _add_resource(rest_server : RestServer, resource : Resource, *urls, **kwargs): + urls = [(URL_PREFIX + url) for url in urls] + rest_server.add_resource(resource, *urls, **kwargs) + +def register_ietf_nss(rest_server : RestServer): + _add_resource(rest_server, NSS_Services, '/network-slice-services') + _add_resource(rest_server, NSS_Service, '/network-slice-services/slice-service=') diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7a0c786e1defad55a4dcc20461b221472d3be687 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/__init__.py @@ -0,0 +1,535 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 itertools import chain +from typing import ( + Any, AnyStr, Dict, Iterator, List, Optional, Tuple, Type, Union) + +import json + + +class YANGMember: + + _yang_name: str = None + _yang_namespace: str = None + _yang_module_name: str = None + + def __init__( + self, yang_name: str, yang_namespace: str, + yang_module_name: str): + + self._yang_name = yang_name + self._yang_namespace = yang_namespace + self._yang_module_name = yang_module_name + + @property + def yang_name(self) -> str: + return self._yang_name + + @property + def yang_namespace(self) -> str: + return self._yang_namespace + + @property + def yang_module_name(self) -> str: + return self._yang_module_name + + +class YANGLeafMember(YANGMember): + + def __get__(self, instance, owner=None): + if instance is None: + return self + + yang_name = self._yang_name + yang_member = self + + class ChildLeaf: + + def __call__(self): + data = instance._data + if (key := yang_name) in data: + return data[key] + + return data.get(':'.join(( + yang_member._yang_module_name, yang_name))) + + @property + def yang_name(self) -> str: + return yang_member._yang_name + + @property + def yang_namespace(self) -> str: + return yang_member._yang_namespace + + @property + def yang_module_name(self) -> str: + return yang_member._yang_module_name + + def __enter__(self): + return self() + + def __exit__(self, exc_type, exc, traceback): + if exc is not None: + raise exc + + def __repr__(self): + return ( + f"<{owner.__qualname__}.{type(self).__name__}: " + + f"{yang_member._yang_module_name}" + + f":{yang_member.yang_name}>") + + return ChildLeaf() + + def __set__(self, instance, value): + if instance is None: + return + + data = instance._data + if ((key := ':'.join((self._yang_module_name, self._yang_name))) + in data): + + data[key] = value + else: + data[self._yang_name] = value + + +class YANGContainerMember(YANGMember): + + _yang_container_type: Type['YANGContainer'] = None + + def __init__(self, yang_container_type: Type['YANGContainer']): + super().__init__( + yang_container_type._yang_name, + yang_container_type._yang_namespace, + yang_container_type._yang_module_name) + + self._yang_container_type = yang_container_type + + def __get__(self, instance, owner=None): + if instance is None: + return self + + yang_container_type = self._yang_container_type + yang_name = self._yang_name + yang_member = self + + class ChildContainer: + + def __call__(self) -> yang_container_type: + data = instance._data + + if (key := ':'.join(( + yang_member._yang_module_name, yang_name))) in data: + + child_data = data[key] + else: + child_data = data.setdefault(yang_name, {}) + + return yang_container_type({yang_name: child_data}) + + @property + def yang_name(self) -> str: + return yang_member._yang_name + + @property + def yang_namespace(self) -> str: + return yang_member._yang_namespace + + @property + def yang_module_name(self) -> str: + return yang_member._yang_module_name + + def __enter__(self): + return self() + + def __exit__(self, exc_type, exc, traceback): + if exc is not None: + raise exc + + def to_json(self, yang_parent_module_name: str=None): + return self().to_json( + yang_parent_module_name=yang_parent_module_name) + + return ChildContainer() + + +class YANGListMember(YANGMember): + + _yang_list_item_type: Type['YANGListItem'] = None + + def __init__(self, yang_list_item_type: Type['YANGListItem']): + super().__init__( + yang_list_item_type._yang_name, + yang_list_item_type._yang_namespace, + yang_list_item_type._yang_module_name) + + self._yang_list_item_type = yang_list_item_type + + def __get__(self, instance, owner=None): + if instance is None: + return self + + yang_list_item_type = self._yang_list_item_type + yang_name = self._yang_name + yang_member = self + + class ChildList: + + @staticmethod + def _child_data_list(): + data = instance._data + if (key := ':'.join(( + yang_member._yang_module_name, yang_name))) in data: + + return data[key] + + return data.setdefault(yang_name, []) + + def __call__(self) -> List[yang_list_item_type]: + return list(iter(self)) + + def __iter__(self) -> Iterator[yang_list_item_type]: + for child_data in self._child_data_list(): + yield yang_list_item_type({yang_name: [child_data]}) + + def __getitem__(self, key) -> yang_list_item_type: + child_data_list = self._child_data_list() + child = yang_list_item_type( + {yang_member._yang_name: child_data_list}, + json_data_list_key=key) + + if not id(child_data := child._data) in map( + id, child_data_list): + child_data_list.append(child_data) + return child + + @property + def yang_name(self) -> str: + return yang_member._yang_name + + @property + def yang_namespace(self) -> str: + return yang_member._yang_namespace + + @property + def yang_module_name(self) -> str: + return yang_member._yang_module_name + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, traceback): + if exc is not None: + raise exc + + def to_json(self, yang_parent_module_name=None): + json_data = {} + for child in self(): + for child_name, child_data_list in (child.to_json( + yang_parent_module_name=( + yang_parent_module_name))).items(): + + json_data.setdefault(child_name, []).extend( + child_data_list) + + return json_data + + return ChildList() + + +class YANGContainer: + """Base class for YANG container handlers.""" + + _yang_name: str = None + _yang_namespace: str = None + _yang_module_name: str = None + + _data: Dict[str, Any] = None + + _yang_leaf_members: Dict[str, YANGLeafMember] = None + _yang_container_members: Dict[str, YANGContainerMember] = None + _yang_list_members: Dict[str, YANGListMember] = None + + _yang_choices: Dict[str, 'YANGChoice'] = None + + def __init__( + self, json_data: Optional[Union[AnyStr, Dict[str, Any]]]=None): + + if json_data is None: + self._data = {} + return + + if isinstance(json_data, bytes): + json_data = json_data.decode('utf8') + + if isinstance(json_data, str): + json_data = json.loads(json_data) + + if (key := ':'.join(( + self._yang_module_name, self._yang_name))) not in json_data: + key = self._yang_name + + data = json_data.get(key, {}) + if not isinstance(data, dict): + raise TypeError(f"{key!r} should be a dict, not: {type(data)}") + + for yang_choice in self._yang_choices.values(): + yang_choice(data) + + self._data = data + + @property + def yang_name(self) -> str: + return self._yang_name + + @property + def yang_namespace(self) -> str: + return self._yang_namespace + + @property + def yang_module_name(self) -> str: + return self._yang_module_name + + def to_json(self, yang_parent_module_name=None) -> Dict[str, Any]: + + def child_items(): + for yang_name, yang_member in self._yang_leaf_members.items(): + if (value := yang_member.__get__(self)()) is not None: + + if (yang_child_module_name := + yang_member.yang_module_name) != ( + self._yang_module_name): + + child_key = ':'.join(( + yang_child_module_name, yang_name)) + else: + child_key = yang_name + + yield child_key, value + + for yang_name, yang_member in ( + self._yang_container_members.items()): + + if yang_name in self._data or ':'.join(( + yang_member._yang_namespace, + yang_name)) in self._data: + + yield from yang_member.__get__(self).to_json( + yang_parent_module_name=( + self._yang_module_name)).items() + + for yang_name, yang_member in self._yang_list_members.items(): + if yang_name in self._data or ':'.join(( + yang_member._yang_namespace, + yang_name)) in self._data: + + yield from yang_member.__get__(self).to_json( + yang_parent_module_name=( + self._yang_module_name)).items() + + for yang_choice in self._yang_choices.values(): + if (yang_case_container := + yang_choice._yang_case_container) is not None: + + yield from next(iter(yang_case_container.to_json( + yang_parent_module_name=( + self._yang_module_name)).values())).items() + + if (yang_module_name := self._yang_module_name) != ( + yang_parent_module_name): + key = ':'.join((yang_module_name, self._yang_name)) + else: + key = self._yang_name + + return {key: dict(child_items())} + + +class YANGListItem(YANGContainer): + """Base class for YANG list item handlers.""" + + _yang_list_key_names: Tuple[str] = None + + def __init__( + self, json_data: Optional[Union[AnyStr, Dict[str, Any]]]=None, + json_data_list_key=None): + + if json_data is None: + raise ValueError(f"{self._yang_name!r} list needs input data") + + if isinstance(json_data, bytes): + json_data = json_data.decode('utf8') + + if isinstance(json_data, str): + json_data = json.loads(json_data) + + if (key := ':'.join(( + self._yang_module_name, self._yang_name))) not in json_data: + key = self._yang_name + + data_list = json_data.get(key, []) + if not isinstance(data_list, list): + raise TypeError( + f"{key!r} should be a list, not: {type(data_list)}") + + if json_data_list_key is None: + if len(data_list) == 1: + data = data_list[0] + else: + raise ValueError(f"{key!r} list key is missing") + + else: + if not isinstance(json_data_list_key, tuple): + json_data_list_key = (json_data_list_key, ) + + for data in json_data.get(key, []): + if tuple( + data.get(yang_name) for yang_name + in self._yang_list_key_names) == json_data_list_key: + + break + else: + data = {key: value for key, value in zip( + self._yang_list_key_names, json_data_list_key)} + + if not isinstance(data, dict): + raise TypeError( + f"{key!r} list item should be a dict, not: {type(data)}") + + for yang_choice in self._yang_choices.values(): + yang_choice(data) + + self._data = data + + def yang_key(self): + if len(self._yang_list_key_names) == 1: + return self._yang_leaf_members[ + self._yang_list_key_names[0]].__get__(self)() + + return tuple( + self._yang_leaf_members[yang_name].__get__(self)() + for yang_name in self._yang_list_key_names) + + def to_json(self, yang_parent_module_name=None) -> Dict[str, list]: + return {key: [data] for key, data in super().to_json( + yang_parent_module_name=yang_parent_module_name).items()} + + +class YANGChoiceCase: + """Base class for YANG choice case handlers.""" + + _yang_name: str = None + + _yang_container_type: Type[YANGContainer] = None + + _yang_container: YANGContainer = None + + def __init__(self, yang_container_type: Type[YANGContainer]): + self._yang_container_type = yang_container_type + self._yang_name = yang_container_type._yang_name + + @property + def yang_name(self) -> str: + return self._yang_name + + def __get__(self, instance, owner=None): + if instance is None: + return self + + yang_case_container_type = self._yang_container_type + yang_name = self._yang_name + yang_choice_case = self + + class Case: + + def __bool__(self) -> bool: + return (yang_case_container := + yang_choice_case._yang_container) is not None and ( + bool(yang_case_container._data)) + + def __call__(self, data: Optional[Dict[str, Any]]=None): + if data: + for yang_member in chain( + yang_case_container_type. + _yang_leaf_members.values(), + + yang_case_container_type. + _yang_container_members.values(), + + yang_case_container_type. + _yang_list_members.values()): + + if yang_member._yang_name in data or ':'.join(( + yang_member._yang_module_name, + yang_member._yang_name)) in data: + break + else: + data = None + + if data: + yang_choice_case._yang_container = ( + yang_case_container_type({yang_name: data})) + + elif yang_choice_case._yang_container is None: + yang_choice_case._yang_container = ( + yang_case_container_type()) + + return yang_choice_case._yang_container + + def __enter__(self): + return self() + + def __exit__(self, exc_type, exc, traceback): + if exc is not None: + raise exc + + return Case() + + +class YANGChoice(YANGMember): + """Base class for YANG choice handlers.""" + + _yang_parent: YANGContainer = None + + _yang_cases: Dict[str, YANGChoiceCase] = None + + def __init__(self, yang_parent: YANGContainer): + self._yang_parent = yang_parent + + def __call__(self, data: Dict[str, Any]): + for yang_case in self._yang_cases.values(): + yang_case.__get__(self)(data) + + @property + def _yang_case_container(self) -> YANGContainer: + for yang_case in self._yang_cases.values(): + if (yang_container := + yang_case._yang_container) is not None and ( + yang_container._data): + return yang_container + + +def load_json_data( + json_data: Union[AnyStr, Dict[str, Any]], + *yang_types: Type[YANGContainer]) -> List[YANGContainer]: + + if isinstance(json_data, bytes): + json_data = json_data.decode('utf8') + + if isinstance(json_data, str): + json_data = json.loads(json_data) + + json_data = json_data.get('data', json_data) + + return [yang_type(json_data) for yang_type in yang_types] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c5a00cae7ce23108a5db10e6192b315330e3a86b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/__init__.py @@ -0,0 +1,141 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NacmMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: nacm + """ + from .groups import Groups + from .rule_list import RuleList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: nacm + """ + + def __init__(self): + super().__init__(Nacm) + + def __get__(self, instance, owner=None) -> ( + 'NacmMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Nacm': + pass + + def __enter__(self) -> 'Nacm': + pass + + +class Nacm( + YANGContainer, + metaclass=NacmMeta): + """ + YANG container handler. + + YANG name: nacm + """ + + _yang_name: Final[str] = 'nacm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'denied-data-writes': ( + denied_data_writes := YANGLeafMember( + 'denied-data-writes', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'exec-default': ( + exec_default := YANGLeafMember( + 'exec-default', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'denied-notifications': ( + denied_notifications := YANGLeafMember( + 'denied-notifications', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'enable-external-groups': ( + enable_external_groups := YANGLeafMember( + 'enable-external-groups', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'enable-nacm': ( + enable_nacm := YANGLeafMember( + 'enable-nacm', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'read-default': ( + read_default := YANGLeafMember( + 'read-default', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'denied-operations': ( + denied_operations := YANGLeafMember( + 'denied-operations', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'write-default': ( + write_default := YANGLeafMember( + 'write-default', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'groups': ( + groups := ( # YANGContainerMember( + NacmMeta. + Groups. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'rule-list': ( + rule_list := ( # YANGListMember( + NacmMeta. + RuleList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Nacm': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/groups/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/groups/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e95275ad804d53820f3fc4a0210d60c645a70d14 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/groups/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GroupsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: groups + """ + from .group import Group + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: groups + """ + + def __init__(self): + super().__init__(Groups) + + def __get__(self, instance, owner=None) -> ( + 'GroupsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Groups': + pass + + def __enter__(self) -> 'Groups': + pass + + +class Groups( + YANGContainer, + metaclass=GroupsMeta): + """ + YANG container handler. + + YANG name: groups + """ + + _yang_name: Final[str] = 'groups' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'group': ( + group := ( # YANGListMember( + GroupsMeta. + Group. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Groups': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/groups/group/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/groups/group/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c294bb266b4b8f6416b1ffe0ea59276c5a109b0f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/groups/group/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GroupMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: group + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: group + """ + + def __init__(self): + super().__init__(Group) + + def __get__(self, instance, owner=None) -> ( + 'GroupMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Group']: + pass + + def __iter__(self, key) -> Iterator['Group']: + return super().__iter__() + + def __getitem__(self, key) -> 'Group': + return super()[key] + + def __enter__(self) -> ( + 'GroupMeta.yang_list_descriptor'): + pass + + +class Group( + YANGListItem, + metaclass=GroupMeta): + """ + YANG list item handler. + + YANG name: group + """ + + _yang_name: Final[str] = 'group' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Group': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..dd0f9808e43dd3930efcec86b5b484b4107b77f6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RuleListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: rule-list + """ + from .rule import Rule + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: rule-list + """ + + def __init__(self): + super().__init__(RuleList) + + def __get__(self, instance, owner=None) -> ( + 'RuleListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RuleList']: + pass + + def __iter__(self, key) -> Iterator['RuleList']: + return super().__iter__() + + def __getitem__(self, key) -> 'RuleList': + return super()[key] + + def __enter__(self) -> ( + 'RuleListMeta.yang_list_descriptor'): + pass + + +class RuleList( + YANGListItem, + metaclass=RuleListMeta): + """ + YANG list item handler. + + YANG name: rule-list + """ + + _yang_name: Final[str] = 'rule-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'rule': ( + rule := ( # YANGListMember( + RuleListMeta. + Rule. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RuleList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4ec5ba06dbf93901881ab6045d1896b85583a642 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/__init__.py @@ -0,0 +1,130 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RuleMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: rule + """ + from .rule_type import RuleType + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: rule + """ + + def __init__(self): + super().__init__(Rule) + + def __get__(self, instance, owner=None) -> ( + 'RuleMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Rule']: + pass + + def __iter__(self, key) -> Iterator['Rule']: + return super().__iter__() + + def __getitem__(self, key) -> 'Rule': + return super()[key] + + def __enter__(self) -> ( + 'RuleMeta.yang_list_descriptor'): + pass + + +class Rule( + YANGListItem, + metaclass=RuleMeta): + """ + YANG list item handler. + + YANG name: rule + """ + + _yang_name: Final[str] = 'rule' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'action': ( + action := YANGLeafMember( + 'action', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'access-operations': ( + access_operations := YANGLeafMember( + 'access-operations', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'comment': ( + comment := YANGLeafMember( + 'comment', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + + 'module-name': ( + module_name := YANGLeafMember( + 'module-name', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Rule': + instance = super().__new__(cls) + instance._yang_choices = { + + 'rule-type': + RuleMeta.RuleType( + instance), + } + return instance + + @property + def rule_type(self) -> ( + RuleMeta.RuleType): + return self._yang_choices['rule-type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d470943c38427e03302d60c52cf22cdb16597d37 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/__init__.py @@ -0,0 +1,130 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RuleTypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: rule-type + """ + + from .notification import Notification + from .protocol_operation import ProtocolOperation + from .data_node import DataNode + + class notification_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: notification + """ + + def __init__(self): + super().__init__( + RuleTypeMeta.Notification) + + def __get__(self, instance, owner=None) -> ( + 'RuleTypeMeta.notification_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'RuleTypeMeta.Notification'): + pass + + def __enter__(self) -> ( + 'RuleTypeMeta.Notification'): + pass + + class protocol_operation_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: protocol-operation + """ + + def __init__(self): + super().__init__( + RuleTypeMeta.ProtocolOperation) + + def __get__(self, instance, owner=None) -> ( + 'RuleTypeMeta.protocol_operation_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'RuleTypeMeta.ProtocolOperation'): + pass + + def __enter__(self) -> ( + 'RuleTypeMeta.ProtocolOperation'): + pass + + class data_node_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: data-node + """ + + def __init__(self): + super().__init__( + RuleTypeMeta.DataNode) + + def __get__(self, instance, owner=None) -> ( + 'RuleTypeMeta.data_node_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'RuleTypeMeta.DataNode'): + pass + + def __enter__(self) -> ( + 'RuleTypeMeta.DataNode'): + pass + + +class RuleType(YANGChoice, metaclass=RuleTypeMeta): + """ + YANG choice handler. + + YANG name: rule-type + """ + + _yang_name: Final[str] = 'rule-type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'notification': ( + notification := ( # YANGChoiceCase( + RuleTypeMeta. + notification_case_descriptor())), + + 'protocol-operation': ( + protocol_operation := ( # YANGChoiceCase( + RuleTypeMeta. + protocol_operation_case_descriptor())), + + 'data-node': ( + data_node := ( # YANGChoiceCase( + RuleTypeMeta. + data_node_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/data_node/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/data_node/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4f7ddf138eefd0c4a086a06a2b846e74bf45b1f6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/data_node/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class DataNodeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: data-node + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: data-node + """ + + def __init__(self): + super().__init__(DataNode) + + def __get__(self, instance, owner=None) -> ( + 'DataNodeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'DataNode': + pass + + def __enter__(self) -> 'DataNode': + pass + + +class DataNode( + YANGContainer, + metaclass=DataNodeMeta): + """ + YANG container handler. + + YANG name: data-node + """ + + _yang_name: Final[str] = 'data-node' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path': ( + path := YANGLeafMember( + 'path', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'DataNode': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/notification/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/notification/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed29784183bf0d387a6c4facd935e0870251e560 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/notification/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NotificationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: notification + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: notification + """ + + def __init__(self): + super().__init__(Notification) + + def __get__(self, instance, owner=None) -> ( + 'NotificationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Notification': + pass + + def __enter__(self) -> 'Notification': + pass + + +class Notification( + YANGContainer, + metaclass=NotificationMeta): + """ + YANG container handler. + + YANG name: notification + """ + + _yang_name: Final[str] = 'notification' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'notification-name': ( + notification_name := YANGLeafMember( + 'notification-name', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Notification': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/protocol_operation/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/protocol_operation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1371c9edb91fac8da7f5bcdb3854d5dbc8cc2d1d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/nacm/rule_list/rule/rule_type/protocol_operation/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ProtocolOperationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: protocol-operation + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: protocol-operation + """ + + def __init__(self): + super().__init__(ProtocolOperation) + + def __get__(self, instance, owner=None) -> ( + 'ProtocolOperationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ProtocolOperation': + pass + + def __enter__(self) -> 'ProtocolOperation': + pass + + +class ProtocolOperation( + YANGContainer, + metaclass=ProtocolOperationMeta): + """ + YANG container handler. + + YANG name: protocol-operation + """ + + _yang_name: Final[str] = 'protocol-operation' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm' + _yang_module_name: Final[str] = 'ietf-netconf-acm' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'rpc-name': ( + rpc_name := YANGLeafMember( + 'rpc-name', + 'urn:ietf:params:xml:ns:yang:ietf-netconf-acm', + 'ietf-netconf-acm')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ProtocolOperation': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..296b880921a48cd2087ba3a9f82c18324e03d7b0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NetworkSliceServicesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: network-slice-services + """ + from .slo_sle_templates import SloSleTemplates + from .slice_service import SliceService + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: network-slice-services + """ + + def __init__(self): + super().__init__(NetworkSliceServices) + + def __get__(self, instance, owner=None) -> ( + 'NetworkSliceServicesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NetworkSliceServices': + pass + + def __enter__(self) -> 'NetworkSliceServices': + pass + + +class NetworkSliceServices( + YANGContainer, + metaclass=NetworkSliceServicesMeta): + """ + YANG container handler. + + YANG name: network-slice-services + """ + + _yang_name: Final[str] = 'network-slice-services' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'slo-sle-templates': ( + slo_sle_templates := ( # YANGContainerMember( + NetworkSliceServicesMeta. + SloSleTemplates. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'slice-service': ( + slice_service := ( # YANGListMember( + NetworkSliceServicesMeta. + SliceService. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NetworkSliceServices': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0e8520f1b36270cbc09d1acddda316eb7198c535 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/__init__.py @@ -0,0 +1,147 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SliceServiceMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: slice-service + """ + from .connection_groups import ConnectionGroups + from .te_topology_identifier import TeTopologyIdentifier + from .status import Status + from .sdps import Sdps + from .service_tags import ServiceTags + from .slo_sle_policy import SloSlePolicy + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: slice-service + """ + + def __init__(self): + super().__init__(SliceService) + + def __get__(self, instance, owner=None) -> ( + 'SliceServiceMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SliceService']: + pass + + def __iter__(self, key) -> Iterator['SliceService']: + return super().__iter__() + + def __getitem__(self, key) -> 'SliceService': + return super()[key] + + def __enter__(self) -> ( + 'SliceServiceMeta.yang_list_descriptor'): + pass + + +class SliceService( + YANGListItem, + metaclass=SliceServiceMeta): + """ + YANG list item handler. + + YANG name: slice-service + """ + + _yang_name: Final[str] = 'slice-service' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'service-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'service-id': ( + service_id := YANGLeafMember( + 'service-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'service-description': ( + service_description := YANGLeafMember( + 'service-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'connection-groups': ( + connection_groups := ( # YANGContainerMember( + SliceServiceMeta. + ConnectionGroups. + yang_container_descriptor())), + + 'te-topology-identifier': ( + te_topology_identifier := ( # YANGContainerMember( + SliceServiceMeta. + TeTopologyIdentifier. + yang_container_descriptor())), + + 'status': ( + status := ( # YANGContainerMember( + SliceServiceMeta. + Status. + yang_container_descriptor())), + + 'sdps': ( + sdps := ( # YANGContainerMember( + SliceServiceMeta. + Sdps. + yang_container_descriptor())), + + 'service-tags': ( + service_tags := ( # YANGContainerMember( + SliceServiceMeta. + ServiceTags. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SliceService': + instance = super().__new__(cls) + instance._yang_choices = { + + 'slo-sle-policy': + SliceServiceMeta.SloSlePolicy( + instance), + } + return instance + + @property + def slo_sle_policy(self) -> ( + SliceServiceMeta.SloSlePolicy): + return self._yang_choices['slo-sle-policy'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a67fcd383e6ecaabe98b4aa1c1d892f68d21840f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectionGroupsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: connection-groups + """ + from .connection_group import ConnectionGroup + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: connection-groups + """ + + def __init__(self): + super().__init__(ConnectionGroups) + + def __get__(self, instance, owner=None) -> ( + 'ConnectionGroupsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ConnectionGroups': + pass + + def __enter__(self) -> 'ConnectionGroups': + pass + + +class ConnectionGroups( + YANGContainer, + metaclass=ConnectionGroupsMeta): + """ + YANG container handler. + + YANG name: connection-groups + """ + + _yang_name: Final[str] = 'connection-groups' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'connection-group': ( + connection_group := ( # YANGListMember( + ConnectionGroupsMeta. + ConnectionGroup. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectionGroups': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38302dd8447f8af0dc7f4e9f133b2337ef8ef3c4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/__init__.py @@ -0,0 +1,132 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectionGroupMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: connection-group + """ + from .connection_group_monitoring import ConnectionGroupMonitoring + from .connectivity_construct import ConnectivityConstruct + from .slo_sle_policy import SloSlePolicy + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: connection-group + """ + + def __init__(self): + super().__init__(ConnectionGroup) + + def __get__(self, instance, owner=None) -> ( + 'ConnectionGroupMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['ConnectionGroup']: + pass + + def __iter__(self, key) -> Iterator['ConnectionGroup']: + return super().__iter__() + + def __getitem__(self, key) -> 'ConnectionGroup': + return super()[key] + + def __enter__(self) -> ( + 'ConnectionGroupMeta.yang_list_descriptor'): + pass + + +class ConnectionGroup( + YANGListItem, + metaclass=ConnectionGroupMeta): + """ + YANG list item handler. + + YANG name: connection-group + """ + + _yang_name: Final[str] = 'connection-group' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'connection-group-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'connectivity-type': ( + connectivity_type := YANGLeafMember( + 'connectivity-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'connection-group-id': ( + connection_group_id := YANGLeafMember( + 'connection-group-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'service-slo-sle-policy-override': ( + service_slo_sle_policy_override := YANGLeafMember( + 'service-slo-sle-policy-override', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'connection-group-monitoring': ( + connection_group_monitoring := ( # YANGContainerMember( + ConnectionGroupMeta. + ConnectionGroupMonitoring. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'connectivity-construct': ( + connectivity_construct := ( # YANGListMember( + ConnectionGroupMeta. + ConnectivityConstruct. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectionGroup': + instance = super().__new__(cls) + instance._yang_choices = { + + 'slo-sle-policy': + ConnectionGroupMeta.SloSlePolicy( + instance), + } + return instance + + @property + def slo_sle_policy(self) -> ( + ConnectionGroupMeta.SloSlePolicy): + return self._yang_choices['slo-sle-policy'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connection_group_monitoring/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connection_group_monitoring/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..395aabd46097a05d51746b4298b5fa845a369068 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connection_group_monitoring/__init__.py @@ -0,0 +1,127 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectionGroupMonitoringMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: connection-group-monitoring + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: connection-group-monitoring + """ + + def __init__(self): + super().__init__(ConnectionGroupMonitoring) + + def __get__(self, instance, owner=None) -> ( + 'ConnectionGroupMonitoringMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ConnectionGroupMonitoring': + pass + + def __enter__(self) -> 'ConnectionGroupMonitoring': + pass + + +class ConnectionGroupMonitoring( + YANGContainer, + metaclass=ConnectionGroupMonitoringMeta): + """ + YANG container handler. + + YANG name: connection-group-monitoring + """ + + _yang_name: Final[str] = 'connection-group-monitoring' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'one-way-delay-variation': ( + one_way_delay_variation := YANGLeafMember( + 'one-way-delay-variation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'one-way-max-delay': ( + one_way_max_delay := YANGLeafMember( + 'one-way-max-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'one-way-packet-loss': ( + one_way_packet_loss := YANGLeafMember( + 'one-way-packet-loss', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-max-delay': ( + two_way_max_delay := YANGLeafMember( + 'two-way-max-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-min-delay': ( + two_way_min_delay := YANGLeafMember( + 'two-way-min-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'one-way-min-delay': ( + one_way_min_delay := YANGLeafMember( + 'one-way-min-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-packet-loss': ( + two_way_packet_loss := YANGLeafMember( + 'two-way-packet-loss', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-delay-variation': ( + two_way_delay_variation := YANGLeafMember( + 'two-way-delay-variation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectionGroupMonitoring': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..124ac4ddc30dc414c79160077a4fc4042924472e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityConstructMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: connectivity-construct + """ + from .connectivity_construct_monitoring import ConnectivityConstructMonitoring + from .slo_sle_policy import SloSlePolicy + from .connectivity_construct_type import ConnectivityConstructType + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: connectivity-construct + """ + + def __init__(self): + super().__init__(ConnectivityConstruct) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityConstructMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['ConnectivityConstruct']: + pass + + def __iter__(self, key) -> Iterator['ConnectivityConstruct']: + return super().__iter__() + + def __getitem__(self, key) -> 'ConnectivityConstruct': + return super()[key] + + def __enter__(self) -> ( + 'ConnectivityConstructMeta.yang_list_descriptor'): + pass + + +class ConnectivityConstruct( + YANGListItem, + metaclass=ConnectivityConstructMeta): + """ + YANG list item handler. + + YANG name: connectivity-construct + """ + + _yang_name: Final[str] = 'connectivity-construct' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'cc-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'service-slo-sle-policy-override': ( + service_slo_sle_policy_override := YANGLeafMember( + 'service-slo-sle-policy-override', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'cc-id': ( + cc_id := YANGLeafMember( + 'cc-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'connectivity-construct-monitoring': ( + connectivity_construct_monitoring := ( # YANGContainerMember( + ConnectivityConstructMeta. + ConnectivityConstructMonitoring. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityConstruct': + instance = super().__new__(cls) + instance._yang_choices = { + + 'slo-sle-policy': + ConnectivityConstructMeta.SloSlePolicy( + instance), + + 'connectivity-construct-type': + ConnectivityConstructMeta.ConnectivityConstructType( + instance), + } + return instance + + @property + def slo_sle_policy(self) -> ( + ConnectivityConstructMeta.SloSlePolicy): + return self._yang_choices['slo-sle-policy'] + + @property + def connectivity_construct_type(self) -> ( + ConnectivityConstructMeta.ConnectivityConstructType): + return self._yang_choices['connectivity-construct-type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_monitoring/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_monitoring/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bfca50ba90e73161807ba1173e7d5113348a7581 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_monitoring/__init__.py @@ -0,0 +1,127 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityConstructMonitoringMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: connectivity-construct-monitoring + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: connectivity-construct-monitoring + """ + + def __init__(self): + super().__init__(ConnectivityConstructMonitoring) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityConstructMonitoringMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ConnectivityConstructMonitoring': + pass + + def __enter__(self) -> 'ConnectivityConstructMonitoring': + pass + + +class ConnectivityConstructMonitoring( + YANGContainer, + metaclass=ConnectivityConstructMonitoringMeta): + """ + YANG container handler. + + YANG name: connectivity-construct-monitoring + """ + + _yang_name: Final[str] = 'connectivity-construct-monitoring' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'one-way-delay-variation': ( + one_way_delay_variation := YANGLeafMember( + 'one-way-delay-variation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-max-delay': ( + two_way_max_delay := YANGLeafMember( + 'two-way-max-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-packet-loss': ( + two_way_packet_loss := YANGLeafMember( + 'two-way-packet-loss', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'one-way-packet-loss': ( + one_way_packet_loss := YANGLeafMember( + 'one-way-packet-loss', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'one-way-max-delay': ( + one_way_max_delay := YANGLeafMember( + 'one-way-max-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-delay-variation': ( + two_way_delay_variation := YANGLeafMember( + 'two-way-delay-variation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'two-way-min-delay': ( + two_way_min_delay := YANGLeafMember( + 'two-way-min-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'one-way-min-delay': ( + one_way_min_delay := YANGLeafMember( + 'one-way-min-delay', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityConstructMonitoring': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6e1424075780ca5a04525d4124fb2af47404ec23 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/__init__.py @@ -0,0 +1,130 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityConstructTypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: connectivity-construct-type + """ + + from .p2mp import P2mp + from .a2a import A2a + from .p2p import P2p + + class p2mp_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: p2mp + """ + + def __init__(self): + super().__init__( + ConnectivityConstructTypeMeta.P2mp) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityConstructTypeMeta.p2mp_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'ConnectivityConstructTypeMeta.P2mp'): + pass + + def __enter__(self) -> ( + 'ConnectivityConstructTypeMeta.P2mp'): + pass + + class a2a_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: a2a + """ + + def __init__(self): + super().__init__( + ConnectivityConstructTypeMeta.A2a) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityConstructTypeMeta.a2a_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'ConnectivityConstructTypeMeta.A2a'): + pass + + def __enter__(self) -> ( + 'ConnectivityConstructTypeMeta.A2a'): + pass + + class p2p_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: p2p + """ + + def __init__(self): + super().__init__( + ConnectivityConstructTypeMeta.P2p) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityConstructTypeMeta.p2p_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'ConnectivityConstructTypeMeta.P2p'): + pass + + def __enter__(self) -> ( + 'ConnectivityConstructTypeMeta.P2p'): + pass + + +class ConnectivityConstructType(YANGChoice, metaclass=ConnectivityConstructTypeMeta): + """ + YANG choice handler. + + YANG name: connectivity-construct-type + """ + + _yang_name: Final[str] = 'connectivity-construct-type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'p2mp': ( + p2mp := ( # YANGChoiceCase( + ConnectivityConstructTypeMeta. + p2mp_case_descriptor())), + + 'a2a': ( + a2a := ( # YANGChoiceCase( + ConnectivityConstructTypeMeta. + a2a_case_descriptor())), + + 'p2p': ( + p2p := ( # YANGChoiceCase( + ConnectivityConstructTypeMeta. + p2p_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1e9d402c2c675f5f6b65fc17952ad0909b8059d2 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class A2aMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: a2a + """ + from .a2a_sdp import A2aSdp + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: a2a + """ + + def __init__(self): + super().__init__(A2a) + + def __get__(self, instance, owner=None) -> ( + 'A2aMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'A2a': + pass + + def __enter__(self) -> 'A2a': + pass + + +class A2a( + YANGContainer, + metaclass=A2aMeta): + """ + YANG container handler. + + YANG name: a2a + """ + + _yang_name: Final[str] = 'a2a' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'a2a-sdp': ( + a2a_sdp := ( # YANGListMember( + A2aMeta. + A2aSdp. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'A2a': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fa176413be0dab678f83a0d9a41737c4bdd90859 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class A2aSdpMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: a2a-sdp + """ + from .slo_sle_policy import SloSlePolicy + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: a2a-sdp + """ + + def __init__(self): + super().__init__(A2aSdp) + + def __get__(self, instance, owner=None) -> ( + 'A2aSdpMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['A2aSdp']: + pass + + def __iter__(self, key) -> Iterator['A2aSdp']: + return super().__iter__() + + def __getitem__(self, key) -> 'A2aSdp': + return super()[key] + + def __enter__(self) -> ( + 'A2aSdpMeta.yang_list_descriptor'): + pass + + +class A2aSdp( + YANGListItem, + metaclass=A2aSdpMeta): + """ + YANG list item handler. + + YANG name: a2a-sdp + """ + + _yang_name: Final[str] = 'a2a-sdp' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'sdp-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sdp-id': ( + sdp_id := YANGLeafMember( + 'sdp-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'A2aSdp': + instance = super().__new__(cls) + instance._yang_choices = { + + 'slo-sle-policy': + A2aSdpMeta.SloSlePolicy( + instance), + } + return instance + + @property + def slo_sle_policy(self) -> ( + A2aSdpMeta.SloSlePolicy): + return self._yang_choices['slo-sle-policy'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b239a65e175236f7873bd8165ac2a2c423e1f448 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SloSlePolicyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: slo-sle-policy + """ + + from .standard import Standard + from .custom import Custom + + class standard_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Standard) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.standard_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + class custom_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Custom) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.custom_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + +class SloSlePolicy(YANGChoice, metaclass=SloSlePolicyMeta): + """ + YANG choice handler. + + YANG name: slo-sle-policy + """ + + _yang_name: Final[str] = 'slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'standard': ( + standard := ( # YANGChoiceCase( + SloSlePolicyMeta. + standard_case_descriptor())), + + 'custom': ( + custom := ( # YANGChoiceCase( + SloSlePolicyMeta. + custom_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0c87599d2b498607615d75ec2bbaab7318af15 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class CustomMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: custom + """ + from .service_slo_sle_policy import ServiceSloSlePolicy + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__(Custom) + + def __get__(self, instance, owner=None) -> ( + 'CustomMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Custom': + pass + + def __enter__(self) -> 'Custom': + pass + + +class Custom( + YANGContainer, + metaclass=CustomMeta): + """ + YANG container handler. + + YANG name: custom + """ + + _yang_name: Final[str] = 'custom' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-slo-sle-policy': ( + service_slo_sle_policy := ( # YANGContainerMember( + CustomMeta. + ServiceSloSlePolicy. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Custom': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..afe092733209a8030bf14f62f3baf77eaabdd6bb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceSloSlePolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-slo-sle-policy + """ + from .metric_bounds import MetricBounds + from .steering_constraints import SteeringConstraints + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-slo-sle-policy + """ + + def __init__(self): + super().__init__(ServiceSloSlePolicy) + + def __get__(self, instance, owner=None) -> ( + 'ServiceSloSlePolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceSloSlePolicy': + pass + + def __enter__(self) -> 'ServiceSloSlePolicy': + pass + + +class ServiceSloSlePolicy( + YANGContainer, + metaclass=ServiceSloSlePolicyMeta): + """ + YANG container handler. + + YANG name: service-slo-sle-policy + """ + + _yang_name: Final[str] = 'service-slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'policy-description': ( + policy_description := YANGLeafMember( + 'policy-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'isolation': ( + isolation := YANGLeafMember( + 'isolation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'max-occupancy-level': ( + max_occupancy_level := YANGLeafMember( + 'max-occupancy-level', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'mtu': ( + mtu := YANGLeafMember( + 'mtu', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'metric-bounds': ( + metric_bounds := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + MetricBounds. + yang_container_descriptor())), + + 'steering-constraints': ( + steering_constraints := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + SteeringConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceSloSlePolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..85730b2d943861ca804a89d0a32ab69bcc27f5c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric-bounds + """ + from .metric_bound import MetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric-bounds + """ + + def __init__(self): + super().__init__(MetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MetricBounds': + pass + + def __enter__(self) -> 'MetricBounds': + pass + + +class MetricBounds( + YANGContainer, + metaclass=MetricBoundsMeta): + """ + YANG container handler. + + YANG name: metric-bounds + """ + + _yang_name: Final[str] = 'metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'metric-bound': ( + metric_bound := ( # YANGListMember( + MetricBoundsMeta. + MetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..07832b8f39b43c7edd743e03c369c60d5c63624d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py @@ -0,0 +1,114 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: metric-bound + """ + + def __init__(self): + super().__init__(MetricBound) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MetricBound']: + pass + + def __iter__(self, key) -> Iterator['MetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'MetricBound': + return super()[key] + + def __enter__(self) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + pass + + +class MetricBound( + YANGListItem, + metaclass=MetricBoundMeta): + """ + YANG list item handler. + + YANG name: metric-bound + """ + + _yang_name: Final[str] = 'metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'bound': ( + bound := YANGLeafMember( + 'bound', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-unit': ( + metric_unit := YANGLeafMember( + 'metric-unit', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'value-description': ( + value_description := YANGLeafMember( + 'value-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c308b850384ee650e0ea222b7776b52b378718fd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SteeringConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: steering-constraints + """ + from .path_constraints import PathConstraints + from .service_function import ServiceFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: steering-constraints + """ + + def __init__(self): + super().__init__(SteeringConstraints) + + def __get__(self, instance, owner=None) -> ( + 'SteeringConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SteeringConstraints': + pass + + def __enter__(self) -> 'SteeringConstraints': + pass + + +class SteeringConstraints( + YANGContainer, + metaclass=SteeringConstraintsMeta): + """ + YANG container handler. + + YANG name: steering-constraints + """ + + _yang_name: Final[str] = 'steering-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + SteeringConstraintsMeta. + PathConstraints. + yang_container_descriptor())), + + 'service-function': ( + service_function := ( # YANGContainerMember( + SteeringConstraintsMeta. + ServiceFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SteeringConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d34f1d097105a51fd50e9f351f61e915352319bd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2593c301f7b0b52ce5c155c0a8672714de5dae84 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-function + """ + + def __init__(self): + super().__init__(ServiceFunction) + + def __get__(self, instance, owner=None) -> ( + 'ServiceFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceFunction': + pass + + def __enter__(self) -> 'ServiceFunction': + pass + + +class ServiceFunction( + YANGContainer, + metaclass=ServiceFunctionMeta): + """ + YANG container handler. + + YANG name: service-function + """ + + _yang_name: Final[str] = 'service-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/standard/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/standard/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..46e20b7346f1d22e7a61b81a4afb170d9ed36a5b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/a2a/a2a_sdp/slo_sle_policy/standard/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StandardMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: standard + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__(Standard) + + def __get__(self, instance, owner=None) -> ( + 'StandardMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Standard': + pass + + def __enter__(self) -> 'Standard': + pass + + +class Standard( + YANGContainer, + metaclass=StandardMeta): + """ + YANG container handler. + + YANG name: standard + """ + + _yang_name: Final[str] = 'standard' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'slo-sle-template': ( + slo_sle_template := YANGLeafMember( + 'slo-sle-template', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Standard': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/p2mp/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/p2mp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..26189213c12a3803a76ecbcf06ff15c598e6dbce --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/p2mp/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class P2mpMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: p2mp + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: p2mp + """ + + def __init__(self): + super().__init__(P2mp) + + def __get__(self, instance, owner=None) -> ( + 'P2mpMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'P2mp': + pass + + def __enter__(self) -> 'P2mp': + pass + + +class P2mp( + YANGContainer, + metaclass=P2mpMeta): + """ + YANG container handler. + + YANG name: p2mp + """ + + _yang_name: Final[str] = 'p2mp' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'p2mp-sender-sdp': ( + p2mp_sender_sdp := YANGLeafMember( + 'p2mp-sender-sdp', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'P2mp': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/p2p/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/p2p/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5abb50263afbcf98d9fa2036fa274ba69695984f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/connectivity_construct_type/p2p/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class P2pMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: p2p + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: p2p + """ + + def __init__(self): + super().__init__(P2p) + + def __get__(self, instance, owner=None) -> ( + 'P2pMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'P2p': + pass + + def __enter__(self) -> 'P2p': + pass + + +class P2p( + YANGContainer, + metaclass=P2pMeta): + """ + YANG container handler. + + YANG name: p2p + """ + + _yang_name: Final[str] = 'p2p' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'p2p-sender-sdp': ( + p2p_sender_sdp := YANGLeafMember( + 'p2p-sender-sdp', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'p2p-receiver-sdp': ( + p2p_receiver_sdp := YANGLeafMember( + 'p2p-receiver-sdp', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'P2p': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b239a65e175236f7873bd8165ac2a2c423e1f448 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SloSlePolicyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: slo-sle-policy + """ + + from .standard import Standard + from .custom import Custom + + class standard_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Standard) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.standard_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + class custom_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Custom) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.custom_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + +class SloSlePolicy(YANGChoice, metaclass=SloSlePolicyMeta): + """ + YANG choice handler. + + YANG name: slo-sle-policy + """ + + _yang_name: Final[str] = 'slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'standard': ( + standard := ( # YANGChoiceCase( + SloSlePolicyMeta. + standard_case_descriptor())), + + 'custom': ( + custom := ( # YANGChoiceCase( + SloSlePolicyMeta. + custom_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0c87599d2b498607615d75ec2bbaab7318af15 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class CustomMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: custom + """ + from .service_slo_sle_policy import ServiceSloSlePolicy + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__(Custom) + + def __get__(self, instance, owner=None) -> ( + 'CustomMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Custom': + pass + + def __enter__(self) -> 'Custom': + pass + + +class Custom( + YANGContainer, + metaclass=CustomMeta): + """ + YANG container handler. + + YANG name: custom + """ + + _yang_name: Final[str] = 'custom' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-slo-sle-policy': ( + service_slo_sle_policy := ( # YANGContainerMember( + CustomMeta. + ServiceSloSlePolicy. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Custom': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..afe092733209a8030bf14f62f3baf77eaabdd6bb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceSloSlePolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-slo-sle-policy + """ + from .metric_bounds import MetricBounds + from .steering_constraints import SteeringConstraints + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-slo-sle-policy + """ + + def __init__(self): + super().__init__(ServiceSloSlePolicy) + + def __get__(self, instance, owner=None) -> ( + 'ServiceSloSlePolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceSloSlePolicy': + pass + + def __enter__(self) -> 'ServiceSloSlePolicy': + pass + + +class ServiceSloSlePolicy( + YANGContainer, + metaclass=ServiceSloSlePolicyMeta): + """ + YANG container handler. + + YANG name: service-slo-sle-policy + """ + + _yang_name: Final[str] = 'service-slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'policy-description': ( + policy_description := YANGLeafMember( + 'policy-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'isolation': ( + isolation := YANGLeafMember( + 'isolation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'max-occupancy-level': ( + max_occupancy_level := YANGLeafMember( + 'max-occupancy-level', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'mtu': ( + mtu := YANGLeafMember( + 'mtu', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'metric-bounds': ( + metric_bounds := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + MetricBounds. + yang_container_descriptor())), + + 'steering-constraints': ( + steering_constraints := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + SteeringConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceSloSlePolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..85730b2d943861ca804a89d0a32ab69bcc27f5c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric-bounds + """ + from .metric_bound import MetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric-bounds + """ + + def __init__(self): + super().__init__(MetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MetricBounds': + pass + + def __enter__(self) -> 'MetricBounds': + pass + + +class MetricBounds( + YANGContainer, + metaclass=MetricBoundsMeta): + """ + YANG container handler. + + YANG name: metric-bounds + """ + + _yang_name: Final[str] = 'metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'metric-bound': ( + metric_bound := ( # YANGListMember( + MetricBoundsMeta. + MetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..32ab7d60c22d534b878f967b4bf57e0509583bbb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py @@ -0,0 +1,114 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: metric-bound + """ + + def __init__(self): + super().__init__(MetricBound) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MetricBound']: + pass + + def __iter__(self, key) -> Iterator['MetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'MetricBound': + return super()[key] + + def __enter__(self) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + pass + + +class MetricBound( + YANGListItem, + metaclass=MetricBoundMeta): + """ + YANG list item handler. + + YANG name: metric-bound + """ + + _yang_name: Final[str] = 'metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value-description': ( + value_description := YANGLeafMember( + 'value-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'bound': ( + bound := YANGLeafMember( + 'bound', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-unit': ( + metric_unit := YANGLeafMember( + 'metric-unit', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e2c022caf902743b8abe798b61b8f1439d276862 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SteeringConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: steering-constraints + """ + from .service_function import ServiceFunction + from .path_constraints import PathConstraints + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: steering-constraints + """ + + def __init__(self): + super().__init__(SteeringConstraints) + + def __get__(self, instance, owner=None) -> ( + 'SteeringConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SteeringConstraints': + pass + + def __enter__(self) -> 'SteeringConstraints': + pass + + +class SteeringConstraints( + YANGContainer, + metaclass=SteeringConstraintsMeta): + """ + YANG container handler. + + YANG name: steering-constraints + """ + + _yang_name: Final[str] = 'steering-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-function': ( + service_function := ( # YANGContainerMember( + SteeringConstraintsMeta. + ServiceFunction. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + SteeringConstraintsMeta. + PathConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SteeringConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d34f1d097105a51fd50e9f351f61e915352319bd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2593c301f7b0b52ce5c155c0a8672714de5dae84 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-function + """ + + def __init__(self): + super().__init__(ServiceFunction) + + def __get__(self, instance, owner=None) -> ( + 'ServiceFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceFunction': + pass + + def __enter__(self) -> 'ServiceFunction': + pass + + +class ServiceFunction( + YANGContainer, + metaclass=ServiceFunctionMeta): + """ + YANG container handler. + + YANG name: service-function + """ + + _yang_name: Final[str] = 'service-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/standard/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/standard/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..46e20b7346f1d22e7a61b81a4afb170d9ed36a5b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/connectivity_construct/slo_sle_policy/standard/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StandardMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: standard + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__(Standard) + + def __get__(self, instance, owner=None) -> ( + 'StandardMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Standard': + pass + + def __enter__(self) -> 'Standard': + pass + + +class Standard( + YANGContainer, + metaclass=StandardMeta): + """ + YANG container handler. + + YANG name: standard + """ + + _yang_name: Final[str] = 'standard' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'slo-sle-template': ( + slo_sle_template := YANGLeafMember( + 'slo-sle-template', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Standard': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b239a65e175236f7873bd8165ac2a2c423e1f448 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SloSlePolicyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: slo-sle-policy + """ + + from .standard import Standard + from .custom import Custom + + class standard_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Standard) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.standard_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + class custom_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Custom) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.custom_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + +class SloSlePolicy(YANGChoice, metaclass=SloSlePolicyMeta): + """ + YANG choice handler. + + YANG name: slo-sle-policy + """ + + _yang_name: Final[str] = 'slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'standard': ( + standard := ( # YANGChoiceCase( + SloSlePolicyMeta. + standard_case_descriptor())), + + 'custom': ( + custom := ( # YANGChoiceCase( + SloSlePolicyMeta. + custom_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0c87599d2b498607615d75ec2bbaab7318af15 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class CustomMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: custom + """ + from .service_slo_sle_policy import ServiceSloSlePolicy + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__(Custom) + + def __get__(self, instance, owner=None) -> ( + 'CustomMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Custom': + pass + + def __enter__(self) -> 'Custom': + pass + + +class Custom( + YANGContainer, + metaclass=CustomMeta): + """ + YANG container handler. + + YANG name: custom + """ + + _yang_name: Final[str] = 'custom' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-slo-sle-policy': ( + service_slo_sle_policy := ( # YANGContainerMember( + CustomMeta. + ServiceSloSlePolicy. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Custom': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ea6d366eb1ff15535bea20dc431827e5f859bc4f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceSloSlePolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-slo-sle-policy + """ + from .steering_constraints import SteeringConstraints + from .metric_bounds import MetricBounds + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-slo-sle-policy + """ + + def __init__(self): + super().__init__(ServiceSloSlePolicy) + + def __get__(self, instance, owner=None) -> ( + 'ServiceSloSlePolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceSloSlePolicy': + pass + + def __enter__(self) -> 'ServiceSloSlePolicy': + pass + + +class ServiceSloSlePolicy( + YANGContainer, + metaclass=ServiceSloSlePolicyMeta): + """ + YANG container handler. + + YANG name: service-slo-sle-policy + """ + + _yang_name: Final[str] = 'service-slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'isolation': ( + isolation := YANGLeafMember( + 'isolation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'mtu': ( + mtu := YANGLeafMember( + 'mtu', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'max-occupancy-level': ( + max_occupancy_level := YANGLeafMember( + 'max-occupancy-level', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'policy-description': ( + policy_description := YANGLeafMember( + 'policy-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'steering-constraints': ( + steering_constraints := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + SteeringConstraints. + yang_container_descriptor())), + + 'metric-bounds': ( + metric_bounds := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + MetricBounds. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceSloSlePolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..85730b2d943861ca804a89d0a32ab69bcc27f5c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric-bounds + """ + from .metric_bound import MetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric-bounds + """ + + def __init__(self): + super().__init__(MetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MetricBounds': + pass + + def __enter__(self) -> 'MetricBounds': + pass + + +class MetricBounds( + YANGContainer, + metaclass=MetricBoundsMeta): + """ + YANG container handler. + + YANG name: metric-bounds + """ + + _yang_name: Final[str] = 'metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'metric-bound': ( + metric_bound := ( # YANGListMember( + MetricBoundsMeta. + MetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..23374967999723000d8649da5d3ec8d5489a5794 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py @@ -0,0 +1,114 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: metric-bound + """ + + def __init__(self): + super().__init__(MetricBound) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MetricBound']: + pass + + def __iter__(self, key) -> Iterator['MetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'MetricBound': + return super()[key] + + def __enter__(self) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + pass + + +class MetricBound( + YANGListItem, + metaclass=MetricBoundMeta): + """ + YANG list item handler. + + YANG name: metric-bound + """ + + _yang_name: Final[str] = 'metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value-description': ( + value_description := YANGLeafMember( + 'value-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'bound': ( + bound := YANGLeafMember( + 'bound', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-unit': ( + metric_unit := YANGLeafMember( + 'metric-unit', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e2c022caf902743b8abe798b61b8f1439d276862 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SteeringConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: steering-constraints + """ + from .service_function import ServiceFunction + from .path_constraints import PathConstraints + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: steering-constraints + """ + + def __init__(self): + super().__init__(SteeringConstraints) + + def __get__(self, instance, owner=None) -> ( + 'SteeringConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SteeringConstraints': + pass + + def __enter__(self) -> 'SteeringConstraints': + pass + + +class SteeringConstraints( + YANGContainer, + metaclass=SteeringConstraintsMeta): + """ + YANG container handler. + + YANG name: steering-constraints + """ + + _yang_name: Final[str] = 'steering-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-function': ( + service_function := ( # YANGContainerMember( + SteeringConstraintsMeta. + ServiceFunction. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + SteeringConstraintsMeta. + PathConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SteeringConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d34f1d097105a51fd50e9f351f61e915352319bd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2593c301f7b0b52ce5c155c0a8672714de5dae84 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-function + """ + + def __init__(self): + super().__init__(ServiceFunction) + + def __get__(self, instance, owner=None) -> ( + 'ServiceFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceFunction': + pass + + def __enter__(self) -> 'ServiceFunction': + pass + + +class ServiceFunction( + YANGContainer, + metaclass=ServiceFunctionMeta): + """ + YANG container handler. + + YANG name: service-function + """ + + _yang_name: Final[str] = 'service-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/standard/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/standard/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..46e20b7346f1d22e7a61b81a4afb170d9ed36a5b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/connection_groups/connection_group/slo_sle_policy/standard/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StandardMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: standard + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__(Standard) + + def __get__(self, instance, owner=None) -> ( + 'StandardMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Standard': + pass + + def __enter__(self) -> 'Standard': + pass + + +class Standard( + YANGContainer, + metaclass=StandardMeta): + """ + YANG container handler. + + YANG name: standard + """ + + _yang_name: Final[str] = 'standard' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'slo-sle-template': ( + slo_sle_template := YANGLeafMember( + 'slo-sle-template', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Standard': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3239d57811ab3ddff018c0347524513d77934aa --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SdpsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: sdps + """ + from .sdp import Sdp + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: sdps + """ + + def __init__(self): + super().__init__(Sdps) + + def __get__(self, instance, owner=None) -> ( + 'SdpsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Sdps': + pass + + def __enter__(self) -> 'Sdps': + pass + + +class Sdps( + YANGContainer, + metaclass=SdpsMeta): + """ + YANG container handler. + + YANG name: sdps + """ + + _yang_name: Final[str] = 'sdps' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'sdp': ( + sdp := ( # YANGListMember( + SdpsMeta. + Sdp. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Sdps': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5fc0ff62c3ed5a5ea1a7d64e77edeb84d3edf286 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/__init__.py @@ -0,0 +1,182 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SdpMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: sdp + """ + from .sdp_monitoring import SdpMonitoring + from .outgoing_qos_policy import OutgoingQosPolicy + from .service_match_criteria import ServiceMatchCriteria + from .sdp_peering import SdpPeering + from .status import Status + from .attachment_circuits import AttachmentCircuits + from .location import Location + from .incoming_qos_policy import IncomingQosPolicy + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: sdp + """ + + def __init__(self): + super().__init__(Sdp) + + def __get__(self, instance, owner=None) -> ( + 'SdpMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Sdp']: + pass + + def __iter__(self, key) -> Iterator['Sdp']: + return super().__iter__() + + def __getitem__(self, key) -> 'Sdp': + return super()[key] + + def __enter__(self) -> ( + 'SdpMeta.yang_list_descriptor'): + pass + + +class Sdp( + YANGListItem, + metaclass=SdpMeta): + """ + YANG list item handler. + + YANG name: sdp + """ + + _yang_name: Final[str] = 'sdp' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'sdp-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sdp-id': ( + sdp_id := YANGLeafMember( + 'sdp-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'peer-sap-id': ( + peer_sap_id := YANGLeafMember( + 'peer-sap-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'sdp-description': ( + sdp_description := YANGLeafMember( + 'sdp-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'sdp-ip': ( + sdp_ip := YANGLeafMember( + 'sdp-ip', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ltp': ( + ltp := YANGLeafMember( + 'ltp', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'sdp-monitoring': ( + sdp_monitoring := ( # YANGContainerMember( + SdpMeta. + SdpMonitoring. + yang_container_descriptor())), + + 'outgoing-qos-policy': ( + outgoing_qos_policy := ( # YANGContainerMember( + SdpMeta. + OutgoingQosPolicy. + yang_container_descriptor())), + + 'service-match-criteria': ( + service_match_criteria := ( # YANGContainerMember( + SdpMeta. + ServiceMatchCriteria. + yang_container_descriptor())), + + 'sdp-peering': ( + sdp_peering := ( # YANGContainerMember( + SdpMeta. + SdpPeering. + yang_container_descriptor())), + + 'status': ( + status := ( # YANGContainerMember( + SdpMeta. + Status. + yang_container_descriptor())), + + 'attachment-circuits': ( + attachment_circuits := ( # YANGContainerMember( + SdpMeta. + AttachmentCircuits. + yang_container_descriptor())), + + 'location': ( + location := ( # YANGContainerMember( + SdpMeta. + Location. + yang_container_descriptor())), + + 'incoming-qos-policy': ( + incoming_qos_policy := ( # YANGContainerMember( + SdpMeta. + IncomingQosPolicy. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Sdp': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..624b09988064151b30cfd5286a6a0ef6681e3dd0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AttachmentCircuitsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: attachment-circuits + """ + from .attachment_circuit import AttachmentCircuit + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: attachment-circuits + """ + + def __init__(self): + super().__init__(AttachmentCircuits) + + def __get__(self, instance, owner=None) -> ( + 'AttachmentCircuitsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AttachmentCircuits': + pass + + def __enter__(self) -> 'AttachmentCircuits': + pass + + +class AttachmentCircuits( + YANGContainer, + metaclass=AttachmentCircuitsMeta): + """ + YANG container handler. + + YANG name: attachment-circuits + """ + + _yang_name: Final[str] = 'attachment-circuits' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'attachment-circuit': ( + attachment_circuit := ( # YANGListMember( + AttachmentCircuitsMeta. + AttachmentCircuit. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AttachmentCircuits': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..93194779e9c37ccae0bca5adcb51ccfb0ff7c349 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/__init__.py @@ -0,0 +1,166 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AttachmentCircuitMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: attachment-circuit + """ + from .ac_tags import AcTags + from .outgoing_qos_policy import OutgoingQosPolicy + from .incoming_qos_policy import IncomingQosPolicy + from .sdp_peering import SdpPeering + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: attachment-circuit + """ + + def __init__(self): + super().__init__(AttachmentCircuit) + + def __get__(self, instance, owner=None) -> ( + 'AttachmentCircuitMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AttachmentCircuit']: + pass + + def __iter__(self, key) -> Iterator['AttachmentCircuit']: + return super().__iter__() + + def __getitem__(self, key) -> 'AttachmentCircuit': + return super()[key] + + def __enter__(self) -> ( + 'AttachmentCircuitMeta.yang_list_descriptor'): + pass + + +class AttachmentCircuit( + YANGListItem, + metaclass=AttachmentCircuitMeta): + """ + YANG list item handler. + + YANG name: attachment-circuit + """ + + _yang_name: Final[str] = 'attachment-circuit' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'ac-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'ac-node-id': ( + ac_node_id := YANGLeafMember( + 'ac-node-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ac-tp-id': ( + ac_tp_id := YANGLeafMember( + 'ac-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ac-ip-prefix-length': ( + ac_ip_prefix_length := YANGLeafMember( + 'ac-ip-prefix-length', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ac-ip-address': ( + ac_ip_address := YANGLeafMember( + 'ac-ip-address', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'mtu': ( + mtu := YANGLeafMember( + 'mtu', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ac-description': ( + ac_description := YANGLeafMember( + 'ac-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ac-id': ( + ac_id := YANGLeafMember( + 'ac-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'peer-sap-id': ( + peer_sap_id := YANGLeafMember( + 'peer-sap-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'ac-tags': ( + ac_tags := ( # YANGContainerMember( + AttachmentCircuitMeta. + AcTags. + yang_container_descriptor())), + + 'outgoing-qos-policy': ( + outgoing_qos_policy := ( # YANGContainerMember( + AttachmentCircuitMeta. + OutgoingQosPolicy. + yang_container_descriptor())), + + 'incoming-qos-policy': ( + incoming_qos_policy := ( # YANGContainerMember( + AttachmentCircuitMeta. + IncomingQosPolicy. + yang_container_descriptor())), + + 'sdp-peering': ( + sdp_peering := ( # YANGContainerMember( + AttachmentCircuitMeta. + SdpPeering. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AttachmentCircuit': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a18ad45c114040f6b3d58ff592ea6cfd9461a8ef --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AcTagsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: ac-tags + """ + from .ac_tags import AcTags + from .ac_tag_opaque import AcTagOpaque + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: ac-tags + """ + + def __init__(self): + super().__init__(AcTags) + + def __get__(self, instance, owner=None) -> ( + 'AcTagsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AcTags': + pass + + def __enter__(self) -> 'AcTags': + pass + + +class AcTags( + YANGContainer, + metaclass=AcTagsMeta): + """ + YANG container handler. + + YANG name: ac-tags + """ + + _yang_name: Final[str] = 'ac-tags' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'ac-tags': ( + ac_tags := ( # YANGListMember( + AcTagsMeta. + AcTags. + yang_list_descriptor())), + + 'ac-tag-opaque': ( + ac_tag_opaque := ( # YANGListMember( + AcTagsMeta. + AcTagOpaque. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AcTags': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/ac_tag_opaque/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/ac_tag_opaque/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d56e829739daeecc91ead77fb6e40c954532a15e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/ac_tag_opaque/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AcTagOpaqueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: ac-tag-opaque + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: ac-tag-opaque + """ + + def __init__(self): + super().__init__(AcTagOpaque) + + def __get__(self, instance, owner=None) -> ( + 'AcTagOpaqueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AcTagOpaque']: + pass + + def __iter__(self, key) -> Iterator['AcTagOpaque']: + return super().__iter__() + + def __getitem__(self, key) -> 'AcTagOpaque': + return super()[key] + + def __enter__(self) -> ( + 'AcTagOpaqueMeta.yang_list_descriptor'): + pass + + +class AcTagOpaque( + YANGListItem, + metaclass=AcTagOpaqueMeta): + """ + YANG list item handler. + + YANG name: ac-tag-opaque + """ + + _yang_name: Final[str] = 'ac-tag-opaque' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tag-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tag-name': ( + tag_name := YANGLeafMember( + 'tag-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AcTagOpaque': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/ac_tags/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/ac_tags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8ef753261d2bf1b99a0fd2a2cf198785baffff1e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/ac_tags/ac_tags/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AcTagsMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: ac-tags + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: ac-tags + """ + + def __init__(self): + super().__init__(AcTags) + + def __get__(self, instance, owner=None) -> ( + 'AcTagsMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AcTags']: + pass + + def __iter__(self, key) -> Iterator['AcTags']: + return super().__iter__() + + def __getitem__(self, key) -> 'AcTags': + return super()[key] + + def __enter__(self) -> ( + 'AcTagsMeta.yang_list_descriptor'): + pass + + +class AcTags( + YANGListItem, + metaclass=AcTagsMeta): + """ + YANG list item handler. + + YANG name: ac-tags + """ + + _yang_name: Final[str] = 'ac-tags' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'ac-tag-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'ac-tag-type': ( + ac_tag_type := YANGLeafMember( + 'ac-tag-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AcTags': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/incoming_qos_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/incoming_qos_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..abad77461c9f94149dc016054d669526c83570af --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/incoming_qos_policy/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class IncomingQosPolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: incoming-qos-policy + """ + from .rate_limits import RateLimits + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: incoming-qos-policy + """ + + def __init__(self): + super().__init__(IncomingQosPolicy) + + def __get__(self, instance, owner=None) -> ( + 'IncomingQosPolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'IncomingQosPolicy': + pass + + def __enter__(self) -> 'IncomingQosPolicy': + pass + + +class IncomingQosPolicy( + YANGContainer, + metaclass=IncomingQosPolicyMeta): + """ + YANG container handler. + + YANG name: incoming-qos-policy + """ + + _yang_name: Final[str] = 'incoming-qos-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'qos-policy-name': ( + qos_policy_name := YANGLeafMember( + 'qos-policy-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'rate-limits': ( + rate_limits := ( # YANGContainerMember( + IncomingQosPolicyMeta. + RateLimits. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'IncomingQosPolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/incoming_qos_policy/rate_limits/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/incoming_qos_policy/rate_limits/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..492759055bf57b40705a54dfd087f89fa61a87dc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/incoming_qos_policy/rate_limits/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RateLimitsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: rate-limits + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: rate-limits + """ + + def __init__(self): + super().__init__(RateLimits) + + def __get__(self, instance, owner=None) -> ( + 'RateLimitsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'RateLimits': + pass + + def __enter__(self) -> 'RateLimits': + pass + + +class RateLimits( + YANGContainer, + metaclass=RateLimitsMeta): + """ + YANG container handler. + + YANG name: rate-limits + """ + + _yang_name: Final[str] = 'rate-limits' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'cir': ( + cir := YANGLeafMember( + 'cir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'cbs': ( + cbs := YANGLeafMember( + 'cbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pir': ( + pir := YANGLeafMember( + 'pir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pbs': ( + pbs := YANGLeafMember( + 'pbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'eir': ( + eir := YANGLeafMember( + 'eir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ebs': ( + ebs := YANGLeafMember( + 'ebs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RateLimits': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/outgoing_qos_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/outgoing_qos_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..893cb264eba6e98af718d8244d262d0888793ca0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/outgoing_qos_policy/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OutgoingQosPolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: outgoing-qos-policy + """ + from .rate_limits import RateLimits + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: outgoing-qos-policy + """ + + def __init__(self): + super().__init__(OutgoingQosPolicy) + + def __get__(self, instance, owner=None) -> ( + 'OutgoingQosPolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'OutgoingQosPolicy': + pass + + def __enter__(self) -> 'OutgoingQosPolicy': + pass + + +class OutgoingQosPolicy( + YANGContainer, + metaclass=OutgoingQosPolicyMeta): + """ + YANG container handler. + + YANG name: outgoing-qos-policy + """ + + _yang_name: Final[str] = 'outgoing-qos-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'qos-policy-name': ( + qos_policy_name := YANGLeafMember( + 'qos-policy-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'rate-limits': ( + rate_limits := ( # YANGContainerMember( + OutgoingQosPolicyMeta. + RateLimits. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OutgoingQosPolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/outgoing_qos_policy/rate_limits/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/outgoing_qos_policy/rate_limits/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..445a7a5df5d7db2b92ecb59f0f54a4c316328d78 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/outgoing_qos_policy/rate_limits/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RateLimitsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: rate-limits + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: rate-limits + """ + + def __init__(self): + super().__init__(RateLimits) + + def __get__(self, instance, owner=None) -> ( + 'RateLimitsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'RateLimits': + pass + + def __enter__(self) -> 'RateLimits': + pass + + +class RateLimits( + YANGContainer, + metaclass=RateLimitsMeta): + """ + YANG container handler. + + YANG name: rate-limits + """ + + _yang_name: Final[str] = 'rate-limits' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'cbs': ( + cbs := YANGLeafMember( + 'cbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ebs': ( + ebs := YANGLeafMember( + 'ebs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pbs': ( + pbs := YANGLeafMember( + 'pbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'cir': ( + cir := YANGLeafMember( + 'cir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pir': ( + pir := YANGLeafMember( + 'pir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'eir': ( + eir := YANGLeafMember( + 'eir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RateLimits': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c7b5e10b24076aa3928995dc846b4e138516379b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SdpPeeringMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: sdp-peering + """ + from .opaque import Opaque + from .protocol import Protocol + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: sdp-peering + """ + + def __init__(self): + super().__init__(SdpPeering) + + def __get__(self, instance, owner=None) -> ( + 'SdpPeeringMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SdpPeering': + pass + + def __enter__(self) -> 'SdpPeering': + pass + + +class SdpPeering( + YANGContainer, + metaclass=SdpPeeringMeta): + """ + YANG container handler. + + YANG name: sdp-peering + """ + + _yang_name: Final[str] = 'sdp-peering' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'opaque': ( + opaque := ( # YANGListMember( + SdpPeeringMeta. + Opaque. + yang_list_descriptor())), + + 'protocol': ( + protocol := ( # YANGListMember( + SdpPeeringMeta. + Protocol. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SdpPeering': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/opaque/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/opaque/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b367227c3d43cd31c1b3df857ed944d62d371806 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/opaque/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OpaqueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: opaque + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: opaque + """ + + def __init__(self): + super().__init__(Opaque) + + def __get__(self, instance, owner=None) -> ( + 'OpaqueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Opaque']: + pass + + def __iter__(self, key) -> Iterator['Opaque']: + return super().__iter__() + + def __getitem__(self, key) -> 'Opaque': + return super()[key] + + def __enter__(self) -> ( + 'OpaqueMeta.yang_list_descriptor'): + pass + + +class Opaque( + YANGListItem, + metaclass=OpaqueMeta): + """ + YANG list item handler. + + YANG name: opaque + """ + + _yang_name: Final[str] = 'opaque' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'attribute-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'attribute-name': ( + attribute_name := YANGLeafMember( + 'attribute-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Opaque': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/protocol/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/protocol/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..850f7d924c02b4a89030c1a7757b1e728ad35326 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/protocol/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ProtocolMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: protocol + """ + from .attribute import Attribute + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: protocol + """ + + def __init__(self): + super().__init__(Protocol) + + def __get__(self, instance, owner=None) -> ( + 'ProtocolMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Protocol']: + pass + + def __iter__(self, key) -> Iterator['Protocol']: + return super().__iter__() + + def __getitem__(self, key) -> 'Protocol': + return super()[key] + + def __enter__(self) -> ( + 'ProtocolMeta.yang_list_descriptor'): + pass + + +class Protocol( + YANGListItem, + metaclass=ProtocolMeta): + """ + YANG list item handler. + + YANG name: protocol + """ + + _yang_name: Final[str] = 'protocol' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'protocol-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'protocol-type': ( + protocol_type := YANGLeafMember( + 'protocol-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'attribute': ( + attribute := ( # YANGListMember( + ProtocolMeta. + Attribute. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Protocol': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/protocol/attribute/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/protocol/attribute/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..76180637c83f2a158838bacaae99add6e9fe5b61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/attachment_circuits/attachment_circuit/sdp_peering/protocol/attribute/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AttributeMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: attribute + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: attribute + """ + + def __init__(self): + super().__init__(Attribute) + + def __get__(self, instance, owner=None) -> ( + 'AttributeMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Attribute']: + pass + + def __iter__(self, key) -> Iterator['Attribute']: + return super().__iter__() + + def __getitem__(self, key) -> 'Attribute': + return super()[key] + + def __enter__(self) -> ( + 'AttributeMeta.yang_list_descriptor'): + pass + + +class Attribute( + YANGListItem, + metaclass=AttributeMeta): + """ + YANG list item handler. + + YANG name: attribute + """ + + _yang_name: Final[str] = 'attribute' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'attribute-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'attribute-type': ( + attribute_type := YANGLeafMember( + 'attribute-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Attribute': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/incoming_qos_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/incoming_qos_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..abad77461c9f94149dc016054d669526c83570af --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/incoming_qos_policy/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class IncomingQosPolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: incoming-qos-policy + """ + from .rate_limits import RateLimits + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: incoming-qos-policy + """ + + def __init__(self): + super().__init__(IncomingQosPolicy) + + def __get__(self, instance, owner=None) -> ( + 'IncomingQosPolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'IncomingQosPolicy': + pass + + def __enter__(self) -> 'IncomingQosPolicy': + pass + + +class IncomingQosPolicy( + YANGContainer, + metaclass=IncomingQosPolicyMeta): + """ + YANG container handler. + + YANG name: incoming-qos-policy + """ + + _yang_name: Final[str] = 'incoming-qos-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'qos-policy-name': ( + qos_policy_name := YANGLeafMember( + 'qos-policy-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'rate-limits': ( + rate_limits := ( # YANGContainerMember( + IncomingQosPolicyMeta. + RateLimits. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'IncomingQosPolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/incoming_qos_policy/rate_limits/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/incoming_qos_policy/rate_limits/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..49a7b3deeb46fce3abf89af50e4e3b922a00bcc5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/incoming_qos_policy/rate_limits/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RateLimitsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: rate-limits + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: rate-limits + """ + + def __init__(self): + super().__init__(RateLimits) + + def __get__(self, instance, owner=None) -> ( + 'RateLimitsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'RateLimits': + pass + + def __enter__(self) -> 'RateLimits': + pass + + +class RateLimits( + YANGContainer, + metaclass=RateLimitsMeta): + """ + YANG container handler. + + YANG name: rate-limits + """ + + _yang_name: Final[str] = 'rate-limits' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'cbs': ( + cbs := YANGLeafMember( + 'cbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'eir': ( + eir := YANGLeafMember( + 'eir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pir': ( + pir := YANGLeafMember( + 'pir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pbs': ( + pbs := YANGLeafMember( + 'pbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'cir': ( + cir := YANGLeafMember( + 'cir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ebs': ( + ebs := YANGLeafMember( + 'ebs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RateLimits': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/location/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/location/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a88123d6c81ab2c15db96d13ffa2af9458fa904e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/location/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LocationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: location + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: location + """ + + def __init__(self): + super().__init__(Location) + + def __get__(self, instance, owner=None) -> ( + 'LocationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Location': + pass + + def __enter__(self) -> 'Location': + pass + + +class Location( + YANGContainer, + metaclass=LocationMeta): + """ + YANG container handler. + + YANG name: location + """ + + _yang_name: Final[str] = 'location' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'altitude': ( + altitude := YANGLeafMember( + 'altitude', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'latitude': ( + latitude := YANGLeafMember( + 'latitude', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'longitude': ( + longitude := YANGLeafMember( + 'longitude', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Location': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/outgoing_qos_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/outgoing_qos_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..893cb264eba6e98af718d8244d262d0888793ca0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/outgoing_qos_policy/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OutgoingQosPolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: outgoing-qos-policy + """ + from .rate_limits import RateLimits + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: outgoing-qos-policy + """ + + def __init__(self): + super().__init__(OutgoingQosPolicy) + + def __get__(self, instance, owner=None) -> ( + 'OutgoingQosPolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'OutgoingQosPolicy': + pass + + def __enter__(self) -> 'OutgoingQosPolicy': + pass + + +class OutgoingQosPolicy( + YANGContainer, + metaclass=OutgoingQosPolicyMeta): + """ + YANG container handler. + + YANG name: outgoing-qos-policy + """ + + _yang_name: Final[str] = 'outgoing-qos-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'qos-policy-name': ( + qos_policy_name := YANGLeafMember( + 'qos-policy-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'rate-limits': ( + rate_limits := ( # YANGContainerMember( + OutgoingQosPolicyMeta. + RateLimits. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OutgoingQosPolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/outgoing_qos_policy/rate_limits/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/outgoing_qos_policy/rate_limits/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fdf96f15c5ceeb7ae878052b998c9658202e04d0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/outgoing_qos_policy/rate_limits/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RateLimitsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: rate-limits + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: rate-limits + """ + + def __init__(self): + super().__init__(RateLimits) + + def __get__(self, instance, owner=None) -> ( + 'RateLimitsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'RateLimits': + pass + + def __enter__(self) -> 'RateLimits': + pass + + +class RateLimits( + YANGContainer, + metaclass=RateLimitsMeta): + """ + YANG container handler. + + YANG name: rate-limits + """ + + _yang_name: Final[str] = 'rate-limits' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'eir': ( + eir := YANGLeafMember( + 'eir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'cir': ( + cir := YANGLeafMember( + 'cir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pir': ( + pir := YANGLeafMember( + 'pir', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'pbs': ( + pbs := YANGLeafMember( + 'pbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'cbs': ( + cbs := YANGLeafMember( + 'cbs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'ebs': ( + ebs := YANGLeafMember( + 'ebs', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RateLimits': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_monitoring/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_monitoring/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a65f09fc30c0324738fdabb36a717bcfddf3496e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_monitoring/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SdpMonitoringMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: sdp-monitoring + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: sdp-monitoring + """ + + def __init__(self): + super().__init__(SdpMonitoring) + + def __get__(self, instance, owner=None) -> ( + 'SdpMonitoringMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SdpMonitoring': + pass + + def __enter__(self) -> 'SdpMonitoring': + pass + + +class SdpMonitoring( + YANGContainer, + metaclass=SdpMonitoringMeta): + """ + YANG container handler. + + YANG name: sdp-monitoring + """ + + _yang_name: Final[str] = 'sdp-monitoring' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'incoming-utilized-bandwidth': ( + incoming_utilized_bandwidth := YANGLeafMember( + 'incoming-utilized-bandwidth', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'incoming-bw-utilization': ( + incoming_bw_utilization := YANGLeafMember( + 'incoming-bw-utilization', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'outgoing-bw-utilization': ( + outgoing_bw_utilization := YANGLeafMember( + 'outgoing-bw-utilization', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'outgoing-utilized-bandwidth': ( + outgoing_utilized_bandwidth := YANGLeafMember( + 'outgoing-utilized-bandwidth', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SdpMonitoring': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d745437bd534e2fa460f16fb2ca3bb982d4ce3fc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SdpPeeringMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: sdp-peering + """ + from .protocol import Protocol + from .opaque import Opaque + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: sdp-peering + """ + + def __init__(self): + super().__init__(SdpPeering) + + def __get__(self, instance, owner=None) -> ( + 'SdpPeeringMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SdpPeering': + pass + + def __enter__(self) -> 'SdpPeering': + pass + + +class SdpPeering( + YANGContainer, + metaclass=SdpPeeringMeta): + """ + YANG container handler. + + YANG name: sdp-peering + """ + + _yang_name: Final[str] = 'sdp-peering' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'protocol': ( + protocol := ( # YANGListMember( + SdpPeeringMeta. + Protocol. + yang_list_descriptor())), + + 'opaque': ( + opaque := ( # YANGListMember( + SdpPeeringMeta. + Opaque. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SdpPeering': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/opaque/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/opaque/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b367227c3d43cd31c1b3df857ed944d62d371806 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/opaque/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OpaqueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: opaque + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: opaque + """ + + def __init__(self): + super().__init__(Opaque) + + def __get__(self, instance, owner=None) -> ( + 'OpaqueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Opaque']: + pass + + def __iter__(self, key) -> Iterator['Opaque']: + return super().__iter__() + + def __getitem__(self, key) -> 'Opaque': + return super()[key] + + def __enter__(self) -> ( + 'OpaqueMeta.yang_list_descriptor'): + pass + + +class Opaque( + YANGListItem, + metaclass=OpaqueMeta): + """ + YANG list item handler. + + YANG name: opaque + """ + + _yang_name: Final[str] = 'opaque' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'attribute-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'attribute-name': ( + attribute_name := YANGLeafMember( + 'attribute-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Opaque': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/protocol/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/protocol/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..850f7d924c02b4a89030c1a7757b1e728ad35326 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/protocol/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ProtocolMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: protocol + """ + from .attribute import Attribute + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: protocol + """ + + def __init__(self): + super().__init__(Protocol) + + def __get__(self, instance, owner=None) -> ( + 'ProtocolMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Protocol']: + pass + + def __iter__(self, key) -> Iterator['Protocol']: + return super().__iter__() + + def __getitem__(self, key) -> 'Protocol': + return super()[key] + + def __enter__(self) -> ( + 'ProtocolMeta.yang_list_descriptor'): + pass + + +class Protocol( + YANGListItem, + metaclass=ProtocolMeta): + """ + YANG list item handler. + + YANG name: protocol + """ + + _yang_name: Final[str] = 'protocol' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'protocol-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'protocol-type': ( + protocol_type := YANGLeafMember( + 'protocol-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'attribute': ( + attribute := ( # YANGListMember( + ProtocolMeta. + Attribute. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Protocol': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/protocol/attribute/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/protocol/attribute/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..76180637c83f2a158838bacaae99add6e9fe5b61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/sdp_peering/protocol/attribute/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AttributeMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: attribute + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: attribute + """ + + def __init__(self): + super().__init__(Attribute) + + def __get__(self, instance, owner=None) -> ( + 'AttributeMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Attribute']: + pass + + def __iter__(self, key) -> Iterator['Attribute']: + return super().__iter__() + + def __getitem__(self, key) -> 'Attribute': + return super()[key] + + def __enter__(self) -> ( + 'AttributeMeta.yang_list_descriptor'): + pass + + +class Attribute( + YANGListItem, + metaclass=AttributeMeta): + """ + YANG list item handler. + + YANG name: attribute + """ + + _yang_name: Final[str] = 'attribute' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'attribute-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'attribute-type': ( + attribute_type := YANGLeafMember( + 'attribute-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Attribute': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/service_match_criteria/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/service_match_criteria/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f39dc9971795fd83eb61a09ca7a4fea42352ac18 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/service_match_criteria/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceMatchCriteriaMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-match-criteria + """ + from .match_criterion import MatchCriterion + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-match-criteria + """ + + def __init__(self): + super().__init__(ServiceMatchCriteria) + + def __get__(self, instance, owner=None) -> ( + 'ServiceMatchCriteriaMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceMatchCriteria': + pass + + def __enter__(self) -> 'ServiceMatchCriteria': + pass + + +class ServiceMatchCriteria( + YANGContainer, + metaclass=ServiceMatchCriteriaMeta): + """ + YANG container handler. + + YANG name: service-match-criteria + """ + + _yang_name: Final[str] = 'service-match-criteria' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'match-criterion': ( + match_criterion := ( # YANGListMember( + ServiceMatchCriteriaMeta. + MatchCriterion. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceMatchCriteria': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/service_match_criteria/match_criterion/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/service_match_criteria/match_criterion/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..99d87b7934889ec3665b1e4af12f836ec76016e0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/service_match_criteria/match_criterion/__init__.py @@ -0,0 +1,120 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MatchCriterionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: match-criterion + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: match-criterion + """ + + def __init__(self): + super().__init__(MatchCriterion) + + def __get__(self, instance, owner=None) -> ( + 'MatchCriterionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MatchCriterion']: + pass + + def __iter__(self, key) -> Iterator['MatchCriterion']: + return super().__iter__() + + def __getitem__(self, key) -> 'MatchCriterion': + return super()[key] + + def __enter__(self) -> ( + 'MatchCriterionMeta.yang_list_descriptor'): + pass + + +class MatchCriterion( + YANGListItem, + metaclass=MatchCriterionMeta): + """ + YANG list item handler. + + YANG name: match-criterion + """ + + _yang_name: Final[str] = 'match-criterion' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'connection-group-sdp-role': ( + connection_group_sdp_role := YANGLeafMember( + 'connection-group-sdp-role', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'target-connection-group-id': ( + target_connection_group_id := YANGLeafMember( + 'target-connection-group-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'target-connectivity-construct-id': ( + target_connectivity_construct_id := YANGLeafMember( + 'target-connectivity-construct-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'match-type': ( + match_type := YANGLeafMember( + 'match-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MatchCriterion': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f802183296df337e7ebacca0d3290f433341130d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StatusMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: status + """ + from .oper_status import OperStatus + from .admin_status import AdminStatus + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: status + """ + + def __init__(self): + super().__init__(Status) + + def __get__(self, instance, owner=None) -> ( + 'StatusMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Status': + pass + + def __enter__(self) -> 'Status': + pass + + +class Status( + YANGContainer, + metaclass=StatusMeta): + """ + YANG container handler. + + YANG name: status + """ + + _yang_name: Final[str] = 'status' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'oper-status': ( + oper_status := ( # YANGContainerMember( + StatusMeta. + OperStatus. + yang_container_descriptor())), + + 'admin-status': ( + admin_status := ( # YANGContainerMember( + StatusMeta. + AdminStatus. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Status': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/admin_status/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/admin_status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f5581ef12dac29ce3050652c8c969a76f0ac88fb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/admin_status/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AdminStatusMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: admin-status + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: admin-status + """ + + def __init__(self): + super().__init__(AdminStatus) + + def __get__(self, instance, owner=None) -> ( + 'AdminStatusMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AdminStatus': + pass + + def __enter__(self) -> 'AdminStatus': + pass + + +class AdminStatus( + YANGContainer, + metaclass=AdminStatusMeta): + """ + YANG container handler. + + YANG name: admin-status + """ + + _yang_name: Final[str] = 'admin-status' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'last-change': ( + last_change := YANGLeafMember( + 'last-change', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'status': ( + status := YANGLeafMember( + 'status', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AdminStatus': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/oper_status/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/oper_status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ab3508c5b8babc01483e2d3a2e2996481a28ef43 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/sdps/sdp/status/oper_status/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OperStatusMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: oper-status + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: oper-status + """ + + def __init__(self): + super().__init__(OperStatus) + + def __get__(self, instance, owner=None) -> ( + 'OperStatusMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'OperStatus': + pass + + def __enter__(self) -> 'OperStatus': + pass + + +class OperStatus( + YANGContainer, + metaclass=OperStatusMeta): + """ + YANG container handler. + + YANG name: oper-status + """ + + _yang_name: Final[str] = 'oper-status' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'status': ( + status := YANGLeafMember( + 'status', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'last-change': ( + last_change := YANGLeafMember( + 'last-change', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OperStatus': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fceafd62985c5230276d129779bf35378d84e87d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceTagsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-tags + """ + from .tag_opaque import TagOpaque + from .tag_type import TagType + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-tags + """ + + def __init__(self): + super().__init__(ServiceTags) + + def __get__(self, instance, owner=None) -> ( + 'ServiceTagsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceTags': + pass + + def __enter__(self) -> 'ServiceTags': + pass + + +class ServiceTags( + YANGContainer, + metaclass=ServiceTagsMeta): + """ + YANG container handler. + + YANG name: service-tags + """ + + _yang_name: Final[str] = 'service-tags' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tag-opaque': ( + tag_opaque := ( # YANGListMember( + ServiceTagsMeta. + TagOpaque. + yang_list_descriptor())), + + 'tag-type': ( + tag_type := ( # YANGListMember( + ServiceTagsMeta. + TagType. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceTags': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/tag_opaque/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/tag_opaque/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d40d27cb705b0fbf4970fa215054e46b4743d885 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/tag_opaque/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TagOpaqueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tag-opaque + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tag-opaque + """ + + def __init__(self): + super().__init__(TagOpaque) + + def __get__(self, instance, owner=None) -> ( + 'TagOpaqueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['TagOpaque']: + pass + + def __iter__(self, key) -> Iterator['TagOpaque']: + return super().__iter__() + + def __getitem__(self, key) -> 'TagOpaque': + return super()[key] + + def __enter__(self) -> ( + 'TagOpaqueMeta.yang_list_descriptor'): + pass + + +class TagOpaque( + YANGListItem, + metaclass=TagOpaqueMeta): + """ + YANG list item handler. + + YANG name: tag-opaque + """ + + _yang_name: Final[str] = 'tag-opaque' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tag-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tag-name': ( + tag_name := YANGLeafMember( + 'tag-name', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TagOpaque': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/tag_type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/tag_type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b4fff2c3b44b9e1649b5eabb6b12cb36d376b6e1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/service_tags/tag_type/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TagTypeMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tag-type + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tag-type + """ + + def __init__(self): + super().__init__(TagType) + + def __get__(self, instance, owner=None) -> ( + 'TagTypeMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['TagType']: + pass + + def __iter__(self, key) -> Iterator['TagType']: + return super().__iter__() + + def __getitem__(self, key) -> 'TagType': + return super()[key] + + def __enter__(self) -> ( + 'TagTypeMeta.yang_list_descriptor'): + pass + + +class TagType( + YANGListItem, + metaclass=TagTypeMeta): + """ + YANG list item handler. + + YANG name: tag-type + """ + + _yang_name: Final[str] = 'tag-type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tag-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tag-type': ( + tag_type := YANGLeafMember( + 'tag-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TagType': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b239a65e175236f7873bd8165ac2a2c423e1f448 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SloSlePolicyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: slo-sle-policy + """ + + from .standard import Standard + from .custom import Custom + + class standard_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Standard) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.standard_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Standard'): + pass + + class custom_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__( + SloSlePolicyMeta.Custom) + + def __get__(self, instance, owner=None) -> ( + 'SloSlePolicyMeta.custom_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + def __enter__(self) -> ( + 'SloSlePolicyMeta.Custom'): + pass + + +class SloSlePolicy(YANGChoice, metaclass=SloSlePolicyMeta): + """ + YANG choice handler. + + YANG name: slo-sle-policy + """ + + _yang_name: Final[str] = 'slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'standard': ( + standard := ( # YANGChoiceCase( + SloSlePolicyMeta. + standard_case_descriptor())), + + 'custom': ( + custom := ( # YANGChoiceCase( + SloSlePolicyMeta. + custom_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0c87599d2b498607615d75ec2bbaab7318af15 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class CustomMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: custom + """ + from .service_slo_sle_policy import ServiceSloSlePolicy + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: custom + """ + + def __init__(self): + super().__init__(Custom) + + def __get__(self, instance, owner=None) -> ( + 'CustomMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Custom': + pass + + def __enter__(self) -> 'Custom': + pass + + +class Custom( + YANGContainer, + metaclass=CustomMeta): + """ + YANG container handler. + + YANG name: custom + """ + + _yang_name: Final[str] = 'custom' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-slo-sle-policy': ( + service_slo_sle_policy := ( # YANGContainerMember( + CustomMeta. + ServiceSloSlePolicy. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Custom': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f20900d5bafe087db15381e30cca8d6c7555875c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceSloSlePolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-slo-sle-policy + """ + from .steering_constraints import SteeringConstraints + from .metric_bounds import MetricBounds + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-slo-sle-policy + """ + + def __init__(self): + super().__init__(ServiceSloSlePolicy) + + def __get__(self, instance, owner=None) -> ( + 'ServiceSloSlePolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceSloSlePolicy': + pass + + def __enter__(self) -> 'ServiceSloSlePolicy': + pass + + +class ServiceSloSlePolicy( + YANGContainer, + metaclass=ServiceSloSlePolicyMeta): + """ + YANG container handler. + + YANG name: service-slo-sle-policy + """ + + _yang_name: Final[str] = 'service-slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'mtu': ( + mtu := YANGLeafMember( + 'mtu', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'max-occupancy-level': ( + max_occupancy_level := YANGLeafMember( + 'max-occupancy-level', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'isolation': ( + isolation := YANGLeafMember( + 'isolation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'policy-description': ( + policy_description := YANGLeafMember( + 'policy-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'steering-constraints': ( + steering_constraints := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + SteeringConstraints. + yang_container_descriptor())), + + 'metric-bounds': ( + metric_bounds := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + MetricBounds. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceSloSlePolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..85730b2d943861ca804a89d0a32ab69bcc27f5c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric-bounds + """ + from .metric_bound import MetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric-bounds + """ + + def __init__(self): + super().__init__(MetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MetricBounds': + pass + + def __enter__(self) -> 'MetricBounds': + pass + + +class MetricBounds( + YANGContainer, + metaclass=MetricBoundsMeta): + """ + YANG container handler. + + YANG name: metric-bounds + """ + + _yang_name: Final[str] = 'metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'metric-bound': ( + metric_bound := ( # YANGListMember( + MetricBoundsMeta. + MetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0cd58260dfa621982847da9dc6fd2bfd5c74331b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py @@ -0,0 +1,114 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: metric-bound + """ + + def __init__(self): + super().__init__(MetricBound) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MetricBound']: + pass + + def __iter__(self, key) -> Iterator['MetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'MetricBound': + return super()[key] + + def __enter__(self) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + pass + + +class MetricBound( + YANGListItem, + metaclass=MetricBoundMeta): + """ + YANG list item handler. + + YANG name: metric-bound + """ + + _yang_name: Final[str] = 'metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value-description': ( + value_description := YANGLeafMember( + 'value-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'bound': ( + bound := YANGLeafMember( + 'bound', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-unit': ( + metric_unit := YANGLeafMember( + 'metric-unit', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c308b850384ee650e0ea222b7776b52b378718fd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SteeringConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: steering-constraints + """ + from .path_constraints import PathConstraints + from .service_function import ServiceFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: steering-constraints + """ + + def __init__(self): + super().__init__(SteeringConstraints) + + def __get__(self, instance, owner=None) -> ( + 'SteeringConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SteeringConstraints': + pass + + def __enter__(self) -> 'SteeringConstraints': + pass + + +class SteeringConstraints( + YANGContainer, + metaclass=SteeringConstraintsMeta): + """ + YANG container handler. + + YANG name: steering-constraints + """ + + _yang_name: Final[str] = 'steering-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + SteeringConstraintsMeta. + PathConstraints. + yang_container_descriptor())), + + 'service-function': ( + service_function := ( # YANGContainerMember( + SteeringConstraintsMeta. + ServiceFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SteeringConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d34f1d097105a51fd50e9f351f61e915352319bd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2593c301f7b0b52ce5c155c0a8672714de5dae84 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/custom/service_slo_sle_policy/steering_constraints/service_function/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-function + """ + + def __init__(self): + super().__init__(ServiceFunction) + + def __get__(self, instance, owner=None) -> ( + 'ServiceFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceFunction': + pass + + def __enter__(self) -> 'ServiceFunction': + pass + + +class ServiceFunction( + YANGContainer, + metaclass=ServiceFunctionMeta): + """ + YANG container handler. + + YANG name: service-function + """ + + _yang_name: Final[str] = 'service-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/standard/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/standard/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..46e20b7346f1d22e7a61b81a4afb170d9ed36a5b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/slo_sle_policy/standard/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StandardMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: standard + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: standard + """ + + def __init__(self): + super().__init__(Standard) + + def __get__(self, instance, owner=None) -> ( + 'StandardMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Standard': + pass + + def __enter__(self) -> 'Standard': + pass + + +class Standard( + YANGContainer, + metaclass=StandardMeta): + """ + YANG container handler. + + YANG name: standard + """ + + _yang_name: Final[str] = 'standard' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'slo-sle-template': ( + slo_sle_template := YANGLeafMember( + 'slo-sle-template', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Standard': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b4239eb7df15eb9629be735267d4fb31ae46af03 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StatusMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: status + """ + from .admin_status import AdminStatus + from .oper_status import OperStatus + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: status + """ + + def __init__(self): + super().__init__(Status) + + def __get__(self, instance, owner=None) -> ( + 'StatusMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Status': + pass + + def __enter__(self) -> 'Status': + pass + + +class Status( + YANGContainer, + metaclass=StatusMeta): + """ + YANG container handler. + + YANG name: status + """ + + _yang_name: Final[str] = 'status' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'admin-status': ( + admin_status := ( # YANGContainerMember( + StatusMeta. + AdminStatus. + yang_container_descriptor())), + + 'oper-status': ( + oper_status := ( # YANGContainerMember( + StatusMeta. + OperStatus. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Status': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/admin_status/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/admin_status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f5581ef12dac29ce3050652c8c969a76f0ac88fb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/admin_status/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AdminStatusMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: admin-status + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: admin-status + """ + + def __init__(self): + super().__init__(AdminStatus) + + def __get__(self, instance, owner=None) -> ( + 'AdminStatusMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AdminStatus': + pass + + def __enter__(self) -> 'AdminStatus': + pass + + +class AdminStatus( + YANGContainer, + metaclass=AdminStatusMeta): + """ + YANG container handler. + + YANG name: admin-status + """ + + _yang_name: Final[str] = 'admin-status' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'last-change': ( + last_change := YANGLeafMember( + 'last-change', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'status': ( + status := YANGLeafMember( + 'status', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AdminStatus': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/oper_status/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/oper_status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69e53ef62d967bc5dbd072cf4f405d60c28be30 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/status/oper_status/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OperStatusMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: oper-status + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: oper-status + """ + + def __init__(self): + super().__init__(OperStatus) + + def __get__(self, instance, owner=None) -> ( + 'OperStatusMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'OperStatus': + pass + + def __enter__(self) -> 'OperStatus': + pass + + +class OperStatus( + YANGContainer, + metaclass=OperStatusMeta): + """ + YANG container handler. + + YANG name: oper-status + """ + + _yang_name: Final[str] = 'oper-status' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'last-change': ( + last_change := YANGLeafMember( + 'last-change', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'status': ( + status := YANGLeafMember( + 'status', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OperStatus': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/te_topology_identifier/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/te_topology_identifier/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b76cce7a32018d0f77c2a9ac3c7fbbc94665680f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slice_service/te_topology_identifier/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeTopologyIdentifierMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-topology-identifier + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-topology-identifier + """ + + def __init__(self): + super().__init__(TeTopologyIdentifier) + + def __get__(self, instance, owner=None) -> ( + 'TeTopologyIdentifierMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeTopologyIdentifier': + pass + + def __enter__(self) -> 'TeTopologyIdentifier': + pass + + +class TeTopologyIdentifier( + YANGContainer, + metaclass=TeTopologyIdentifierMeta): + """ + YANG container handler. + + YANG name: te-topology-identifier + """ + + _yang_name: Final[str] = 'te-topology-identifier' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'client-id': ( + client_id := YANGLeafMember( + 'client-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'topology-id': ( + topology_id := YANGLeafMember( + 'topology-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'provider-id': ( + provider_id := YANGLeafMember( + 'provider-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeTopologyIdentifier': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..27cda68070b24236354d46b094d0ad3787ab4485 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SloSleTemplatesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: slo-sle-templates + """ + from .slo_sle_template import SloSleTemplate + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: slo-sle-templates + """ + + def __init__(self): + super().__init__(SloSleTemplates) + + def __get__(self, instance, owner=None) -> ( + 'SloSleTemplatesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SloSleTemplates': + pass + + def __enter__(self) -> 'SloSleTemplates': + pass + + +class SloSleTemplates( + YANGContainer, + metaclass=SloSleTemplatesMeta): + """ + YANG container handler. + + YANG name: slo-sle-templates + """ + + _yang_name: Final[str] = 'slo-sle-templates' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'slo-sle-template': ( + slo_sle_template := ( # YANGListMember( + SloSleTemplatesMeta. + SloSleTemplate. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SloSleTemplates': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e97edc736f2f5435711ad71a78313fa2f98b446b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SloSleTemplateMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: slo-sle-template + """ + from .service_slo_sle_policy import ServiceSloSlePolicy + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: slo-sle-template + """ + + def __init__(self): + super().__init__(SloSleTemplate) + + def __get__(self, instance, owner=None) -> ( + 'SloSleTemplateMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SloSleTemplate']: + pass + + def __iter__(self, key) -> Iterator['SloSleTemplate']: + return super().__iter__() + + def __getitem__(self, key) -> 'SloSleTemplate': + return super()[key] + + def __enter__(self) -> ( + 'SloSleTemplateMeta.yang_list_descriptor'): + pass + + +class SloSleTemplate( + YANGListItem, + metaclass=SloSleTemplateMeta): + """ + YANG list item handler. + + YANG name: slo-sle-template + """ + + _yang_name: Final[str] = 'slo-sle-template' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'id': ( + id := YANGLeafMember( + 'id', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'template-ref': ( + template_ref := YANGLeafMember( + 'template-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'template-description': ( + template_description := YANGLeafMember( + 'template-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-slo-sle-policy': ( + service_slo_sle_policy := ( # YANGContainerMember( + SloSleTemplateMeta. + ServiceSloSlePolicy. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SloSleTemplate': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6992f5bf7f3fc87ff009bcf075de2cf2cd698f12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceSloSlePolicyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-slo-sle-policy + """ + from .metric_bounds import MetricBounds + from .steering_constraints import SteeringConstraints + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-slo-sle-policy + """ + + def __init__(self): + super().__init__(ServiceSloSlePolicy) + + def __get__(self, instance, owner=None) -> ( + 'ServiceSloSlePolicyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceSloSlePolicy': + pass + + def __enter__(self) -> 'ServiceSloSlePolicy': + pass + + +class ServiceSloSlePolicy( + YANGContainer, + metaclass=ServiceSloSlePolicyMeta): + """ + YANG container handler. + + YANG name: service-slo-sle-policy + """ + + _yang_name: Final[str] = 'service-slo-sle-policy' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'mtu': ( + mtu := YANGLeafMember( + 'mtu', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'max-occupancy-level': ( + max_occupancy_level := YANGLeafMember( + 'max-occupancy-level', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'isolation': ( + isolation := YANGLeafMember( + 'isolation', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'policy-description': ( + policy_description := YANGLeafMember( + 'policy-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'metric-bounds': ( + metric_bounds := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + MetricBounds. + yang_container_descriptor())), + + 'steering-constraints': ( + steering_constraints := ( # YANGContainerMember( + ServiceSloSlePolicyMeta. + SteeringConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceSloSlePolicy': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..85730b2d943861ca804a89d0a32ab69bcc27f5c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric-bounds + """ + from .metric_bound import MetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric-bounds + """ + + def __init__(self): + super().__init__(MetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MetricBounds': + pass + + def __enter__(self) -> 'MetricBounds': + pass + + +class MetricBounds( + YANGContainer, + metaclass=MetricBoundsMeta): + """ + YANG container handler. + + YANG name: metric-bounds + """ + + _yang_name: Final[str] = 'metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'metric-bound': ( + metric_bound := ( # YANGListMember( + MetricBoundsMeta. + MetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2664a9278a5332d04479df4c5026f38ec2f379d9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/metric_bounds/metric_bound/__init__.py @@ -0,0 +1,114 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: metric-bound + """ + + def __init__(self): + super().__init__(MetricBound) + + def __get__(self, instance, owner=None) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MetricBound']: + pass + + def __iter__(self, key) -> Iterator['MetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'MetricBound': + return super()[key] + + def __enter__(self) -> ( + 'MetricBoundMeta.yang_list_descriptor'): + pass + + +class MetricBound( + YANGListItem, + metaclass=MetricBoundMeta): + """ + YANG list item handler. + + YANG name: metric-bound + """ + + _yang_name: Final[str] = 'metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-unit': ( + metric_unit := YANGLeafMember( + 'metric-unit', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'value-description': ( + value_description := YANGLeafMember( + 'value-description', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + + 'bound': ( + bound := YANGLeafMember( + 'bound', + 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service', + 'ietf-network-slice-service')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e2c022caf902743b8abe798b61b8f1439d276862 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SteeringConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: steering-constraints + """ + from .service_function import ServiceFunction + from .path_constraints import PathConstraints + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: steering-constraints + """ + + def __init__(self): + super().__init__(SteeringConstraints) + + def __get__(self, instance, owner=None) -> ( + 'SteeringConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'SteeringConstraints': + pass + + def __enter__(self) -> 'SteeringConstraints': + pass + + +class SteeringConstraints( + YANGContainer, + metaclass=SteeringConstraintsMeta): + """ + YANG container handler. + + YANG name: steering-constraints + """ + + _yang_name: Final[str] = 'steering-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'service-function': ( + service_function := ( # YANGContainerMember( + SteeringConstraintsMeta. + ServiceFunction. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + SteeringConstraintsMeta. + PathConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SteeringConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d34f1d097105a51fd50e9f351f61e915352319bd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/path_constraints/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/service_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/service_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2593c301f7b0b52ce5c155c0a8672714de5dae84 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/network_slice_services/slo_sle_templates/slo_sle_template/service_slo_sle_policy/steering_constraints/service_function/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ServiceFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: service-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: service-function + """ + + def __init__(self): + super().__init__(ServiceFunction) + + def __get__(self, instance, owner=None) -> ( + 'ServiceFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ServiceFunction': + pass + + def __enter__(self) -> 'ServiceFunction': + pass + + +class ServiceFunction( + YANGContainer, + metaclass=ServiceFunctionMeta): + """ + YANG container handler. + + YANG name: service-function + """ + + _yang_name: Final[str] = 'service-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-slice-service' + _yang_module_name: Final[str] = 'ietf-network-slice-service' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ServiceFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..55faa977ba04330042964cb79ab2a3bdd8a6571c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NetworksMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: networks + """ + from .te import Te + from .network import Network + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: networks + """ + + def __init__(self): + super().__init__(Networks) + + def __get__(self, instance, owner=None) -> ( + 'NetworksMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Networks': + pass + + def __enter__(self) -> 'Networks': + pass + + +class Networks( + YANGContainer, + metaclass=NetworksMeta): + """ + YANG container handler. + + YANG name: networks + """ + + _yang_name: Final[str] = 'networks' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network' + _yang_module_name: Final[str] = 'ietf-network' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te': ( + te := ( # YANGContainerMember( + NetworksMeta. + Te. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'network': ( + network := ( # YANGListMember( + NetworksMeta. + Network. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Networks': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..44952bf764009ce37b74d8ab45cf20dc0e0e450e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/__init__.py @@ -0,0 +1,138 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NetworkMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: network + """ + from .te import Te + from .te_topology_identifier import TeTopologyIdentifier + from .network_types import NetworkTypes + from .node import Node + from .supporting_network import SupportingNetwork + from .link import Link + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: network + """ + + def __init__(self): + super().__init__(Network) + + def __get__(self, instance, owner=None) -> ( + 'NetworkMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Network']: + pass + + def __iter__(self, key) -> Iterator['Network']: + return super().__iter__() + + def __getitem__(self, key) -> 'Network': + return super()[key] + + def __enter__(self) -> ( + 'NetworkMeta.yang_list_descriptor'): + pass + + +class Network( + YANGListItem, + metaclass=NetworkMeta): + """ + YANG list item handler. + + YANG name: network + """ + + _yang_name: Final[str] = 'network' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network' + _yang_module_name: Final[str] = 'ietf-network' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'network-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-id': ( + network_id := YANGLeafMember( + 'network-id', + 'urn:ietf:params:xml:ns:yang:ietf-network', + 'ietf-network')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te': ( + te := ( # YANGContainerMember( + NetworkMeta. + Te. + yang_container_descriptor())), + + 'te-topology-identifier': ( + te_topology_identifier := ( # YANGContainerMember( + NetworkMeta. + TeTopologyIdentifier. + yang_container_descriptor())), + + 'network-types': ( + network_types := ( # YANGContainerMember( + NetworkMeta. + NetworkTypes. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'node': ( + node := ( # YANGListMember( + NetworkMeta. + Node. + yang_list_descriptor())), + + 'supporting-network': ( + supporting_network := ( # YANGListMember( + NetworkMeta. + SupportingNetwork. + yang_list_descriptor())), + + 'link': ( + link := ( # YANGListMember( + NetworkMeta. + Link. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Network': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3efc3e1518f16330422d43ba925ea7713a2cef25 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/__init__.py @@ -0,0 +1,124 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LinkMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: link + """ + from .source import Source + from .destination import Destination + from .te import Te + from .supporting_link import SupportingLink + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: link + """ + + def __init__(self): + super().__init__(Link) + + def __get__(self, instance, owner=None) -> ( + 'LinkMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Link']: + pass + + def __iter__(self, key) -> Iterator['Link']: + return super().__iter__() + + def __getitem__(self, key) -> 'Link': + return super()[key] + + def __enter__(self) -> ( + 'LinkMeta.yang_list_descriptor'): + pass + + +class Link( + YANGListItem, + metaclass=LinkMeta): + """ + YANG list item handler. + + YANG name: link + """ + + _yang_name: Final[str] = 'link' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-topology' + _yang_module_name: Final[str] = 'ietf-network-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'link-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-id': ( + link_id := YANGLeafMember( + 'link-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'source': ( + source := ( # YANGContainerMember( + LinkMeta. + Source. + yang_container_descriptor())), + + 'destination': ( + destination := ( # YANGContainerMember( + LinkMeta. + Destination. + yang_container_descriptor())), + + 'te': ( + te := ( # YANGContainerMember( + LinkMeta. + Te. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'supporting-link': ( + supporting_link := ( # YANGListMember( + LinkMeta. + SupportingLink. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Link': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/destination/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/destination/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..387af3071c585daebb4f11cb2bc7890a37967e56 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/destination/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class DestinationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: destination + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: destination + """ + + def __init__(self): + super().__init__(Destination) + + def __get__(self, instance, owner=None) -> ( + 'DestinationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Destination': + pass + + def __enter__(self) -> 'Destination': + pass + + +class Destination( + YANGContainer, + metaclass=DestinationMeta): + """ + YANG container handler. + + YANG name: destination + """ + + _yang_name: Final[str] = 'destination' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-topology' + _yang_module_name: Final[str] = 'ietf-network-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'dest-node': ( + dest_node := YANGLeafMember( + 'dest-node', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + + 'dest-tp': ( + dest_tp := YANGLeafMember( + 'dest-tp', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Destination': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/source/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/source/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f1ea95f113d40f596ea39edaa5d1b07273f22148 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/source/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SourceMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: source + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: source + """ + + def __init__(self): + super().__init__(Source) + + def __get__(self, instance, owner=None) -> ( + 'SourceMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Source': + pass + + def __enter__(self) -> 'Source': + pass + + +class Source( + YANGContainer, + metaclass=SourceMeta): + """ + YANG container handler. + + YANG name: source + """ + + _yang_name: Final[str] = 'source' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-topology' + _yang_module_name: Final[str] = 'ietf-network-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'source-tp': ( + source_tp := YANGLeafMember( + 'source-tp', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + + 'source-node': ( + source_node := YANGLeafMember( + 'source-node', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Source': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/supporting_link/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/supporting_link/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..dc99caa282f1b3c61577107a169430654949fe3f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/supporting_link/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SupportingLinkMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: supporting-link + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: supporting-link + """ + + def __init__(self): + super().__init__(SupportingLink) + + def __get__(self, instance, owner=None) -> ( + 'SupportingLinkMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SupportingLink']: + pass + + def __iter__(self, key) -> Iterator['SupportingLink']: + return super().__iter__() + + def __getitem__(self, key) -> 'SupportingLink': + return super()[key] + + def __enter__(self) -> ( + 'SupportingLinkMeta.yang_list_descriptor'): + pass + + +class SupportingLink( + YANGListItem, + metaclass=SupportingLinkMeta): + """ + YANG list item handler. + + YANG name: supporting-link + """ + + _yang_name: Final[str] = 'supporting-link' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-topology' + _yang_module_name: Final[str] = 'ietf-network-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'network-ref', + 'link-ref', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-ref': ( + link_ref := YANGLeafMember( + 'link-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SupportingLink': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2fac1a941b3f2b45da7b78f3f4eef6cace58f3b5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/__init__.py @@ -0,0 +1,155 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te + """ + from .statistics import Statistics + from .te_link_attributes import TeLinkAttributes + from .underlay import Underlay + from .recovery import Recovery + from .information_source_state import InformationSourceState + from .information_source_entry import InformationSourceEntry + from .bundle_stack_level import BundleStackLevel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te + """ + + def __init__(self): + super().__init__(Te) + + def __get__(self, instance, owner=None) -> ( + 'TeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Te': + pass + + def __enter__(self) -> 'Te': + pass + + +class Te( + YANGContainer, + metaclass=TeMeta): + """ + YANG container handler. + + YANG name: te + """ + + _yang_name: Final[str] = 'te' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'is-transitional': ( + is_transitional := YANGLeafMember( + 'is-transitional', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'information-source-instance': ( + information_source_instance := YANGLeafMember( + 'information-source-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'oper-status': ( + oper_status := YANGLeafMember( + 'oper-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'information-source': ( + information_source := YANGLeafMember( + 'information-source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'statistics': ( + statistics := ( # YANGContainerMember( + TeMeta. + Statistics. + yang_container_descriptor())), + + 'te-link-attributes': ( + te_link_attributes := ( # YANGContainerMember( + TeMeta. + TeLinkAttributes. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + TeMeta. + Underlay. + yang_container_descriptor())), + + 'recovery': ( + recovery := ( # YANGContainerMember( + TeMeta. + Recovery. + yang_container_descriptor())), + + 'information-source-state': ( + information_source_state := ( # YANGContainerMember( + TeMeta. + InformationSourceState. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'information-source-entry': ( + information_source_entry := ( # YANGListMember( + TeMeta. + InformationSourceEntry. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Te': + instance = super().__new__(cls) + instance._yang_choices = { + + 'bundle-stack-level': + TeMeta.BundleStackLevel( + instance), + } + return instance + + @property + def bundle_stack_level(self) -> ( + TeMeta.BundleStackLevel): + return self._yang_choices['bundle-stack-level'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..225c39aa448d3165a61a66735cb5755c9eaa4908 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BundleStackLevelMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: bundle-stack-level + """ + + from .component import Component + from .bundle import Bundle + + class component_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: component + """ + + def __init__(self): + super().__init__( + BundleStackLevelMeta.Component) + + def __get__(self, instance, owner=None) -> ( + 'BundleStackLevelMeta.component_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'BundleStackLevelMeta.Component'): + pass + + def __enter__(self) -> ( + 'BundleStackLevelMeta.Component'): + pass + + class bundle_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: bundle + """ + + def __init__(self): + super().__init__( + BundleStackLevelMeta.Bundle) + + def __get__(self, instance, owner=None) -> ( + 'BundleStackLevelMeta.bundle_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'BundleStackLevelMeta.Bundle'): + pass + + def __enter__(self) -> ( + 'BundleStackLevelMeta.Bundle'): + pass + + +class BundleStackLevel(YANGChoice, metaclass=BundleStackLevelMeta): + """ + YANG choice handler. + + YANG name: bundle-stack-level + """ + + _yang_name: Final[str] = 'bundle-stack-level' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'component': ( + component := ( # YANGChoiceCase( + BundleStackLevelMeta. + component_case_descriptor())), + + 'bundle': ( + bundle := ( # YANGChoiceCase( + BundleStackLevelMeta. + bundle_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2ac76501adeb07f82ad08b8084a64534cca4a163 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BundleMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: bundle + """ + from .bundled_links import BundledLinks + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: bundle + """ + + def __init__(self): + super().__init__(Bundle) + + def __get__(self, instance, owner=None) -> ( + 'BundleMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Bundle': + pass + + def __enter__(self) -> 'Bundle': + pass + + +class Bundle( + YANGContainer, + metaclass=BundleMeta): + """ + YANG container handler. + + YANG name: bundle + """ + + _yang_name: Final[str] = 'bundle' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'bundled-links': ( + bundled_links := ( # YANGContainerMember( + BundleMeta. + BundledLinks. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Bundle': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/bundled_links/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/bundled_links/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fc2b9edfb5c0d0a12233c23e4b0982fc72020ae0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/bundled_links/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BundledLinksMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: bundled-links + """ + from .bundled_link import BundledLink + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: bundled-links + """ + + def __init__(self): + super().__init__(BundledLinks) + + def __get__(self, instance, owner=None) -> ( + 'BundledLinksMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'BundledLinks': + pass + + def __enter__(self) -> 'BundledLinks': + pass + + +class BundledLinks( + YANGContainer, + metaclass=BundledLinksMeta): + """ + YANG container handler. + + YANG name: bundled-links + """ + + _yang_name: Final[str] = 'bundled-links' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'bundled-link': ( + bundled_link := ( # YANGListMember( + BundledLinksMeta. + BundledLink. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BundledLinks': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/bundled_links/bundled_link/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/bundled_links/bundled_link/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b10b2d452b813e8821571384ff36553830cea9b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/bundle/bundled_links/bundled_link/__init__.py @@ -0,0 +1,108 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BundledLinkMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: bundled-link + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: bundled-link + """ + + def __init__(self): + super().__init__(BundledLink) + + def __get__(self, instance, owner=None) -> ( + 'BundledLinkMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BundledLink']: + pass + + def __iter__(self, key) -> Iterator['BundledLink']: + return super().__iter__() + + def __getitem__(self, key) -> 'BundledLink': + return super()[key] + + def __enter__(self) -> ( + 'BundledLinkMeta.yang_list_descriptor'): + pass + + +class BundledLink( + YANGListItem, + metaclass=BundledLinkMeta): + """ + YANG list item handler. + + YANG name: bundled-link + """ + + _yang_name: Final[str] = 'bundled-link' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'sequence', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sequence': ( + sequence := YANGLeafMember( + 'sequence', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'src-tp-ref': ( + src_tp_ref := YANGLeafMember( + 'src-tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'des-tp-ref': ( + des_tp_ref := YANGLeafMember( + 'des-tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BundledLink': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8cd4a23746aa284e47784cb4fccdf7278ebce34 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ComponentMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: component + """ + from .component_links import ComponentLinks + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: component + """ + + def __init__(self): + super().__init__(Component) + + def __get__(self, instance, owner=None) -> ( + 'ComponentMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Component': + pass + + def __enter__(self) -> 'Component': + pass + + +class Component( + YANGContainer, + metaclass=ComponentMeta): + """ + YANG container handler. + + YANG name: component + """ + + _yang_name: Final[str] = 'component' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'component-links': ( + component_links := ( # YANGContainerMember( + ComponentMeta. + ComponentLinks. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Component': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/component_links/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/component_links/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2dea8fc98c2766683324fb1271d8adb121b4dea8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/component_links/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ComponentLinksMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: component-links + """ + from .component_link import ComponentLink + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: component-links + """ + + def __init__(self): + super().__init__(ComponentLinks) + + def __get__(self, instance, owner=None) -> ( + 'ComponentLinksMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ComponentLinks': + pass + + def __enter__(self) -> 'ComponentLinks': + pass + + +class ComponentLinks( + YANGContainer, + metaclass=ComponentLinksMeta): + """ + YANG container handler. + + YANG name: component-links + """ + + _yang_name: Final[str] = 'component-links' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'component-link': ( + component_link := ( # YANGListMember( + ComponentLinksMeta. + ComponentLink. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ComponentLinks': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/component_links/component_link/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/component_links/component_link/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6195320b1b05440e98cb09c672a9286f7ac08017 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/bundle_stack_level/component/component_links/component_link/__init__.py @@ -0,0 +1,108 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ComponentLinkMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: component-link + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: component-link + """ + + def __init__(self): + super().__init__(ComponentLink) + + def __get__(self, instance, owner=None) -> ( + 'ComponentLinkMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['ComponentLink']: + pass + + def __iter__(self, key) -> Iterator['ComponentLink']: + return super().__iter__() + + def __getitem__(self, key) -> 'ComponentLink': + return super()[key] + + def __enter__(self) -> ( + 'ComponentLinkMeta.yang_list_descriptor'): + pass + + +class ComponentLink( + YANGListItem, + metaclass=ComponentLinkMeta): + """ + YANG list item handler. + + YANG name: component-link + """ + + _yang_name: Final[str] = 'component-link' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'sequence', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'src-interface-ref': ( + src_interface_ref := YANGLeafMember( + 'src-interface-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'sequence': ( + sequence := YANGLeafMember( + 'sequence', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'des-interface-ref': ( + des_interface_ref := YANGLeafMember( + 'des-interface-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ComponentLink': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aacb98f85b2ac241f3599daa93b27fc0f520c8ff --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/__init__.py @@ -0,0 +1,195 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InformationSourceEntryMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: information-source-entry + """ + from .max_link_bandwidth import MaxLinkBandwidth + from .label_restrictions import LabelRestrictions + from .information_source_state import InformationSourceState + from .max_resv_link_bandwidth import MaxResvLinkBandwidth + from .te_srlgs import TeSrlgs + from .te_nsrlgs import TeNsrlgs + from .interface_switching_capability import InterfaceSwitchingCapability + from .unreserved_bandwidth import UnreservedBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: information-source-entry + """ + + def __init__(self): + super().__init__(InformationSourceEntry) + + def __get__(self, instance, owner=None) -> ( + 'InformationSourceEntryMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['InformationSourceEntry']: + pass + + def __iter__(self, key) -> Iterator['InformationSourceEntry']: + return super().__iter__() + + def __getitem__(self, key) -> 'InformationSourceEntry': + return super()[key] + + def __enter__(self) -> ( + 'InformationSourceEntryMeta.yang_list_descriptor'): + pass + + +class InformationSourceEntry( + YANGListItem, + metaclass=InformationSourceEntryMeta): + """ + YANG list item handler. + + YANG name: information-source-entry + """ + + _yang_name: Final[str] = 'information-source-entry' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'information-source', + 'information-source-instance', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'information-source-instance': ( + information_source_instance := YANGLeafMember( + 'information-source-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-igp-metric': ( + te_igp_metric := YANGLeafMember( + 'te-igp-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-default-metric': ( + te_default_metric := YANGLeafMember( + 'te-default-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-delay-metric': ( + te_delay_metric := YANGLeafMember( + 'te-delay-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-index': ( + link_index := YANGLeafMember( + 'link-index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection-type': ( + link_protection_type := YANGLeafMember( + 'link-protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'administrative-group': ( + administrative_group := YANGLeafMember( + 'administrative-group', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'information-source': ( + information_source := YANGLeafMember( + 'information-source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'max-link-bandwidth': ( + max_link_bandwidth := ( # YANGContainerMember( + InformationSourceEntryMeta. + MaxLinkBandwidth. + yang_container_descriptor())), + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + InformationSourceEntryMeta. + LabelRestrictions. + yang_container_descriptor())), + + 'information-source-state': ( + information_source_state := ( # YANGContainerMember( + InformationSourceEntryMeta. + InformationSourceState. + yang_container_descriptor())), + + 'max-resv-link-bandwidth': ( + max_resv_link_bandwidth := ( # YANGContainerMember( + InformationSourceEntryMeta. + MaxResvLinkBandwidth. + yang_container_descriptor())), + + 'te-srlgs': ( + te_srlgs := ( # YANGContainerMember( + InformationSourceEntryMeta. + TeSrlgs. + yang_container_descriptor())), + + 'te-nsrlgs': ( + te_nsrlgs := ( # YANGContainerMember( + InformationSourceEntryMeta. + TeNsrlgs. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'interface-switching-capability': ( + interface_switching_capability := ( # YANGListMember( + InformationSourceEntryMeta. + InterfaceSwitchingCapability. + yang_list_descriptor())), + + 'unreserved-bandwidth': ( + unreserved_bandwidth := ( # YANGListMember( + InformationSourceEntryMeta. + UnreservedBandwidth. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InformationSourceEntry': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/information_source_state/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/information_source_state/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..26d315f6a43287274e5b410c83c64a950c07014d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/information_source_state/__init__.py @@ -0,0 +1,104 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InformationSourceStateMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: information-source-state + """ + from .topology import Topology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: information-source-state + """ + + def __init__(self): + super().__init__(InformationSourceState) + + def __get__(self, instance, owner=None) -> ( + 'InformationSourceStateMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'InformationSourceState': + pass + + def __enter__(self) -> 'InformationSourceState': + pass + + +class InformationSourceState( + YANGContainer, + metaclass=InformationSourceStateMeta): + """ + YANG container handler. + + YANG name: information-source-state + """ + + _yang_name: Final[str] = 'information-source-state' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-instance': ( + network_instance := YANGLeafMember( + 'network-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'credibility-preference': ( + credibility_preference := YANGLeafMember( + 'credibility-preference', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'logical-network-element': ( + logical_network_element := YANGLeafMember( + 'logical-network-element', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'topology': ( + topology := ( # YANGContainerMember( + InformationSourceStateMeta. + Topology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InformationSourceState': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/information_source_state/topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/information_source_state/topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..63598ce3305f3b8b540d2d10d31cf66604ea175c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/information_source_state/topology/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: topology + """ + + def __init__(self): + super().__init__(Topology) + + def __get__(self, instance, owner=None) -> ( + 'TopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Topology': + pass + + def __enter__(self) -> 'Topology': + pass + + +class Topology( + YANGContainer, + metaclass=TopologyMeta): + """ + YANG container handler. + + YANG name: topology + """ + + _yang_name: Final[str] = 'topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-ref': ( + link_ref := YANGLeafMember( + 'link-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Topology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42361e143910d3dc4963a100c961f548c4740f4a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InterfaceSwitchingCapabilityMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: interface-switching-capability + """ + from .max_lsp_bandwidth import MaxLspBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: interface-switching-capability + """ + + def __init__(self): + super().__init__(InterfaceSwitchingCapability) + + def __get__(self, instance, owner=None) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['InterfaceSwitchingCapability']: + pass + + def __iter__(self, key) -> Iterator['InterfaceSwitchingCapability']: + return super().__iter__() + + def __getitem__(self, key) -> 'InterfaceSwitchingCapability': + return super()[key] + + def __enter__(self) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + pass + + +class InterfaceSwitchingCapability( + YANGListItem, + metaclass=InterfaceSwitchingCapabilityMeta): + """ + YANG list item handler. + + YANG name: interface-switching-capability + """ + + _yang_name: Final[str] = 'interface-switching-capability' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'switching-capability', + 'encoding', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'switching-capability': ( + switching_capability := YANGLeafMember( + 'switching-capability', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'encoding': ( + encoding := YANGLeafMember( + 'encoding', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'max-lsp-bandwidth': ( + max_lsp_bandwidth := ( # YANGListMember( + InterfaceSwitchingCapabilityMeta. + MaxLspBandwidth. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InterfaceSwitchingCapability': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ddad298bbc0cc7c626bd869965fe6da4630b6fb5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLspBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: max-lsp-bandwidth + """ + + def __init__(self): + super().__init__(MaxLspBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MaxLspBandwidth']: + pass + + def __iter__(self, key) -> Iterator['MaxLspBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'MaxLspBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + pass + + +class MaxLspBandwidth( + YANGListItem, + metaclass=MaxLspBandwidthMeta): + """ + YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + + _yang_name: Final[str] = 'max-lsp-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLspBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLspBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1f85292e3a5a398b30f523c488c31588fc79925c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_step import LabelStep + from .label_end import LabelEnd + from .label_start import LabelStart + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8dbcffdcef6a5a8e5db53b62fce3a3f123ea450f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLinkBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: max-link-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: max-link-bandwidth + """ + + def __init__(self): + super().__init__(MaxLinkBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLinkBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MaxLinkBandwidth': + pass + + def __enter__(self) -> 'MaxLinkBandwidth': + pass + + +class MaxLinkBandwidth( + YANGContainer, + metaclass=MaxLinkBandwidthMeta): + """ + YANG container handler. + + YANG name: max-link-bandwidth + """ + + _yang_name: Final[str] = 'max-link-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLinkBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLinkBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..92e8cf6bf3d3ec018101b740c97d4721224527f7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxResvLinkBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: max-resv-link-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: max-resv-link-bandwidth + """ + + def __init__(self): + super().__init__(MaxResvLinkBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxResvLinkBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MaxResvLinkBandwidth': + pass + + def __enter__(self) -> 'MaxResvLinkBandwidth': + pass + + +class MaxResvLinkBandwidth( + YANGContainer, + metaclass=MaxResvLinkBandwidthMeta): + """ + YANG container handler. + + YANG name: max-resv-link-bandwidth + """ + + _yang_name: Final[str] = 'max-resv-link-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxResvLinkBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxResvLinkBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/te_nsrlgs/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/te_nsrlgs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e5e97fc164047e8b36086ca3700f75d61848220c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/te_nsrlgs/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeNsrlgsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-nsrlgs + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-nsrlgs + """ + + def __init__(self): + super().__init__(TeNsrlgs) + + def __get__(self, instance, owner=None) -> ( + 'TeNsrlgsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeNsrlgs': + pass + + def __enter__(self) -> 'TeNsrlgs': + pass + + +class TeNsrlgs( + YANGContainer, + metaclass=TeNsrlgsMeta): + """ + YANG container handler. + + YANG name: te-nsrlgs + """ + + _yang_name: Final[str] = 'te-nsrlgs' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeNsrlgs': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/te_srlgs/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/te_srlgs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..561b31be827190ecd2cf49c88adb2118e8018b00 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/te_srlgs/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeSrlgsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-srlgs + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-srlgs + """ + + def __init__(self): + super().__init__(TeSrlgs) + + def __get__(self, instance, owner=None) -> ( + 'TeSrlgsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeSrlgs': + pass + + def __enter__(self) -> 'TeSrlgs': + pass + + +class TeSrlgs( + YANGContainer, + metaclass=TeSrlgsMeta): + """ + YANG container handler. + + YANG name: te-srlgs + """ + + _yang_name: Final[str] = 'te-srlgs' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeSrlgs': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fd4e9d8a913ee8fb4ba711c3d10310583ea16711 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnreservedBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: unreserved-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: unreserved-bandwidth + """ + + def __init__(self): + super().__init__(UnreservedBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'UnreservedBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['UnreservedBandwidth']: + pass + + def __iter__(self, key) -> Iterator['UnreservedBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'UnreservedBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'UnreservedBandwidthMeta.yang_list_descriptor'): + pass + + +class UnreservedBandwidth( + YANGListItem, + metaclass=UnreservedBandwidthMeta): + """ + YANG list item handler. + + YANG name: unreserved-bandwidth + """ + + _yang_name: Final[str] = 'unreserved-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + UnreservedBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnreservedBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_entry/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_state/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_state/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..91fd095ce45cdfe4669215874ed2aeabfc57b835 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_state/__init__.py @@ -0,0 +1,104 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InformationSourceStateMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: information-source-state + """ + from .topology import Topology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: information-source-state + """ + + def __init__(self): + super().__init__(InformationSourceState) + + def __get__(self, instance, owner=None) -> ( + 'InformationSourceStateMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'InformationSourceState': + pass + + def __enter__(self) -> 'InformationSourceState': + pass + + +class InformationSourceState( + YANGContainer, + metaclass=InformationSourceStateMeta): + """ + YANG container handler. + + YANG name: information-source-state + """ + + _yang_name: Final[str] = 'information-source-state' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'credibility-preference': ( + credibility_preference := YANGLeafMember( + 'credibility-preference', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-instance': ( + network_instance := YANGLeafMember( + 'network-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'logical-network-element': ( + logical_network_element := YANGLeafMember( + 'logical-network-element', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'topology': ( + topology := ( # YANGContainerMember( + InformationSourceStateMeta. + Topology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InformationSourceState': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_state/topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_state/topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..63598ce3305f3b8b540d2d10d31cf66604ea175c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/information_source_state/topology/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: topology + """ + + def __init__(self): + super().__init__(Topology) + + def __get__(self, instance, owner=None) -> ( + 'TopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Topology': + pass + + def __enter__(self) -> 'Topology': + pass + + +class Topology( + YANGContainer, + metaclass=TopologyMeta): + """ + YANG container handler. + + YANG name: topology + """ + + _yang_name: Final[str] = 'topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-ref': ( + link_ref := YANGLeafMember( + 'link-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Topology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/recovery/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/recovery/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ecaf0b0c27bf56b948e42a76356e755c71ebf360 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/recovery/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RecoveryMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: recovery + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: recovery + """ + + def __init__(self): + super().__init__(Recovery) + + def __get__(self, instance, owner=None) -> ( + 'RecoveryMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Recovery': + pass + + def __enter__(self) -> 'Recovery': + pass + + +class Recovery( + YANGContainer, + metaclass=RecoveryMeta): + """ + YANG container handler. + + YANG name: recovery + """ + + _yang_name: Final[str] = 'recovery' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'restoration-status': ( + restoration_status := YANGLeafMember( + 'restoration-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-status': ( + protection_status := YANGLeafMember( + 'protection-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Recovery': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/statistics/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/statistics/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..08e82ba9e2412515916a0d1c4aeb8cb819cf7ba8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/statistics/__init__.py @@ -0,0 +1,187 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StatisticsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: statistics + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: statistics + """ + + def __init__(self): + super().__init__(Statistics) + + def __get__(self, instance, owner=None) -> ( + 'StatisticsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Statistics': + pass + + def __enter__(self) -> 'Statistics': + pass + + +class Statistics( + YANGContainer, + metaclass=StatisticsMeta): + """ + YANG container handler. + + YANG name: statistics + """ + + _yang_name: Final[str] = 'statistics' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enables': ( + enables := YANGLeafMember( + 'enables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'modifies': ( + modifies := YANGLeafMember( + 'modifies', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'fault-detects': ( + fault_detects := YANGLeafMember( + 'fault-detects', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restoration-failures': ( + restoration_failures := YANGLeafMember( + 'restoration-failures', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-switches': ( + protection_switches := YANGLeafMember( + 'protection-switches', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'downs': ( + downs := YANGLeafMember( + 'downs', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restoration-successes': ( + restoration_successes := YANGLeafMember( + 'restoration-successes', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restoration-reversion-starts': ( + restoration_reversion_starts := YANGLeafMember( + 'restoration-reversion-starts', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'maintenance-clears': ( + maintenance_clears := YANGLeafMember( + 'maintenance-clears', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-reverts': ( + protection_reverts := YANGLeafMember( + 'protection-reverts', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restoration-reversion-successes': ( + restoration_reversion_successes := YANGLeafMember( + 'restoration-reversion-successes', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'ups': ( + ups := YANGLeafMember( + 'ups', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restoration-starts': ( + restoration_starts := YANGLeafMember( + 'restoration-starts', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'discontinuity-time': ( + discontinuity_time := YANGLeafMember( + 'discontinuity-time', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disables': ( + disables := YANGLeafMember( + 'disables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'fault-clears': ( + fault_clears := YANGLeafMember( + 'fault-clears', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'maintenance-sets': ( + maintenance_sets := YANGLeafMember( + 'maintenance-sets', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restoration-reversion-failures': ( + restoration_reversion_failures := YANGLeafMember( + 'restoration-reversion-failures', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Statistics': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..706a755fae50b2e463f93632ba44e2dafcf21661 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/__init__.py @@ -0,0 +1,202 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLinkAttributesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-link-attributes + """ + from .max_resv_link_bandwidth import MaxResvLinkBandwidth + from .max_link_bandwidth import MaxLinkBandwidth + from .underlay import Underlay + from .te_srlgs import TeSrlgs + from .label_restrictions import LabelRestrictions + from .external_domain import ExternalDomain + from .te_nsrlgs import TeNsrlgs + from .unreserved_bandwidth import UnreservedBandwidth + from .interface_switching_capability import InterfaceSwitchingCapability + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-link-attributes + """ + + def __init__(self): + super().__init__(TeLinkAttributes) + + def __get__(self, instance, owner=None) -> ( + 'TeLinkAttributesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLinkAttributes': + pass + + def __enter__(self) -> 'TeLinkAttributes': + pass + + +class TeLinkAttributes( + YANGContainer, + metaclass=TeLinkAttributesMeta): + """ + YANG container handler. + + YANG name: te-link-attributes + """ + + _yang_name: Final[str] = 'te-link-attributes' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'is-abstract': ( + is_abstract := YANGLeafMember( + 'is-abstract', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-index': ( + link_index := YANGLeafMember( + 'link-index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-default-metric': ( + te_default_metric := YANGLeafMember( + 'te-default-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection-type': ( + link_protection_type := YANGLeafMember( + 'link-protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'admin-status': ( + admin_status := YANGLeafMember( + 'admin-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-igp-metric': ( + te_igp_metric := YANGLeafMember( + 'te-igp-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'access-type': ( + access_type := YANGLeafMember( + 'access-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-delay-metric': ( + te_delay_metric := YANGLeafMember( + 'te-delay-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'administrative-group': ( + administrative_group := YANGLeafMember( + 'administrative-group', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'max-resv-link-bandwidth': ( + max_resv_link_bandwidth := ( # YANGContainerMember( + TeLinkAttributesMeta. + MaxResvLinkBandwidth. + yang_container_descriptor())), + + 'max-link-bandwidth': ( + max_link_bandwidth := ( # YANGContainerMember( + TeLinkAttributesMeta. + MaxLinkBandwidth. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + TeLinkAttributesMeta. + Underlay. + yang_container_descriptor())), + + 'te-srlgs': ( + te_srlgs := ( # YANGContainerMember( + TeLinkAttributesMeta. + TeSrlgs. + yang_container_descriptor())), + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + TeLinkAttributesMeta. + LabelRestrictions. + yang_container_descriptor())), + + 'external-domain': ( + external_domain := ( # YANGContainerMember( + TeLinkAttributesMeta. + ExternalDomain. + yang_container_descriptor())), + + 'te-nsrlgs': ( + te_nsrlgs := ( # YANGContainerMember( + TeLinkAttributesMeta. + TeNsrlgs. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'unreserved-bandwidth': ( + unreserved_bandwidth := ( # YANGListMember( + TeLinkAttributesMeta. + UnreservedBandwidth. + yang_list_descriptor())), + + 'interface-switching-capability': ( + interface_switching_capability := ( # YANGListMember( + TeLinkAttributesMeta. + InterfaceSwitchingCapability. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLinkAttributes': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/external_domain/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/external_domain/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..58a1d9d4dcf0f87fa40fddfc379b3245219a8ef0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/external_domain/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExternalDomainMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: external-domain + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: external-domain + """ + + def __init__(self): + super().__init__(ExternalDomain) + + def __get__(self, instance, owner=None) -> ( + 'ExternalDomainMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExternalDomain': + pass + + def __enter__(self) -> 'ExternalDomain': + pass + + +class ExternalDomain( + YANGContainer, + metaclass=ExternalDomainMeta): + """ + YANG container handler. + + YANG name: external-domain + """ + + _yang_name: Final[str] = 'external-domain' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'remote-te-node-id': ( + remote_te_node_id := YANGLeafMember( + 'remote-te-node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'remote-te-link-tp-id': ( + remote_te_link_tp_id := YANGLeafMember( + 'remote-te-link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExternalDomain': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42361e143910d3dc4963a100c961f548c4740f4a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InterfaceSwitchingCapabilityMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: interface-switching-capability + """ + from .max_lsp_bandwidth import MaxLspBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: interface-switching-capability + """ + + def __init__(self): + super().__init__(InterfaceSwitchingCapability) + + def __get__(self, instance, owner=None) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['InterfaceSwitchingCapability']: + pass + + def __iter__(self, key) -> Iterator['InterfaceSwitchingCapability']: + return super().__iter__() + + def __getitem__(self, key) -> 'InterfaceSwitchingCapability': + return super()[key] + + def __enter__(self) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + pass + + +class InterfaceSwitchingCapability( + YANGListItem, + metaclass=InterfaceSwitchingCapabilityMeta): + """ + YANG list item handler. + + YANG name: interface-switching-capability + """ + + _yang_name: Final[str] = 'interface-switching-capability' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'switching-capability', + 'encoding', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'switching-capability': ( + switching_capability := YANGLeafMember( + 'switching-capability', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'encoding': ( + encoding := YANGLeafMember( + 'encoding', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'max-lsp-bandwidth': ( + max_lsp_bandwidth := ( # YANGListMember( + InterfaceSwitchingCapabilityMeta. + MaxLspBandwidth. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InterfaceSwitchingCapability': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ddad298bbc0cc7c626bd869965fe6da4630b6fb5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLspBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: max-lsp-bandwidth + """ + + def __init__(self): + super().__init__(MaxLspBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MaxLspBandwidth']: + pass + + def __iter__(self, key) -> Iterator['MaxLspBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'MaxLspBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + pass + + +class MaxLspBandwidth( + YANGListItem, + metaclass=MaxLspBandwidthMeta): + """ + YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + + _yang_name: Final[str] = 'max-lsp-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLspBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLspBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4a396a20af1746df44dc4e4f479436fde2d35e17 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_start import LabelStart + from .label_step import LabelStep + from .label_end import LabelEnd + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8dbcffdcef6a5a8e5db53b62fce3a3f123ea450f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLinkBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: max-link-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: max-link-bandwidth + """ + + def __init__(self): + super().__init__(MaxLinkBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLinkBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MaxLinkBandwidth': + pass + + def __enter__(self) -> 'MaxLinkBandwidth': + pass + + +class MaxLinkBandwidth( + YANGContainer, + metaclass=MaxLinkBandwidthMeta): + """ + YANG container handler. + + YANG name: max-link-bandwidth + """ + + _yang_name: Final[str] = 'max-link-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLinkBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLinkBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..92e8cf6bf3d3ec018101b740c97d4721224527f7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxResvLinkBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: max-resv-link-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: max-resv-link-bandwidth + """ + + def __init__(self): + super().__init__(MaxResvLinkBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxResvLinkBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MaxResvLinkBandwidth': + pass + + def __enter__(self) -> 'MaxResvLinkBandwidth': + pass + + +class MaxResvLinkBandwidth( + YANGContainer, + metaclass=MaxResvLinkBandwidthMeta): + """ + YANG container handler. + + YANG name: max-resv-link-bandwidth + """ + + _yang_name: Final[str] = 'max-resv-link-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxResvLinkBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxResvLinkBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/te_nsrlgs/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/te_nsrlgs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e5e97fc164047e8b36086ca3700f75d61848220c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/te_nsrlgs/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeNsrlgsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-nsrlgs + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-nsrlgs + """ + + def __init__(self): + super().__init__(TeNsrlgs) + + def __get__(self, instance, owner=None) -> ( + 'TeNsrlgsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeNsrlgs': + pass + + def __enter__(self) -> 'TeNsrlgs': + pass + + +class TeNsrlgs( + YANGContainer, + metaclass=TeNsrlgsMeta): + """ + YANG container handler. + + YANG name: te-nsrlgs + """ + + _yang_name: Final[str] = 'te-nsrlgs' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeNsrlgs': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/te_srlgs/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/te_srlgs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..561b31be827190ecd2cf49c88adb2118e8018b00 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/te_srlgs/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeSrlgsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-srlgs + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-srlgs + """ + + def __init__(self): + super().__init__(TeSrlgs) + + def __get__(self, instance, owner=None) -> ( + 'TeSrlgsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeSrlgs': + pass + + def __enter__(self) -> 'TeSrlgs': + pass + + +class TeSrlgs( + YANGContainer, + metaclass=TeSrlgsMeta): + """ + YANG container handler. + + YANG name: te-srlgs + """ + + _yang_name: Final[str] = 'te-srlgs' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeSrlgs': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9ef388cd63aa7c8947fc3391bad703bb01f3d827 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .primary_path import PrimaryPath + from .tunnel_termination_points import TunnelTerminationPoints + from .tunnels import Tunnels + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..eee438314ebe12c55dba835cf5f6839760a31c61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95deb32ec877a103436ef7b54fd1a23501216fab --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .label import Label + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..652da89e61bd32067e97591a11a2970e965bed4a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e6792cd8e4b1e1a843abf183eea400e13dbb78be --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .label import Label + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2aa767b55c350d6b4b7ec04998c04f5fa568d051 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c5cccf39482c3497e05c1c7ab8f4fdd3e2d7490b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f854dfd329ce016317b7b9743ace874769f03094 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fd4e9d8a913ee8fb4ba711c3d10310583ea16711 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnreservedBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: unreserved-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: unreserved-bandwidth + """ + + def __init__(self): + super().__init__(UnreservedBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'UnreservedBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['UnreservedBandwidth']: + pass + + def __iter__(self, key) -> Iterator['UnreservedBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'UnreservedBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'UnreservedBandwidthMeta.yang_list_descriptor'): + pass + + +class UnreservedBandwidth( + YANGListItem, + metaclass=UnreservedBandwidthMeta): + """ + YANG list item handler. + + YANG name: unreserved-bandwidth + """ + + _yang_name: Final[str] = 'unreserved-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + UnreservedBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnreservedBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ea01121d057b002c61d31fe6f49e50049c04b952 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/link/te/underlay/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'dynamic': ( + dynamic := YANGLeafMember( + 'dynamic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'committed': ( + committed := YANGLeafMember( + 'committed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/network_types/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/network_types/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0fb174b74c14bff912498e9c690c949d93d2b76b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/network_types/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NetworkTypesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: network-types + """ + from .te_topology import TeTopology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: network-types + """ + + def __init__(self): + super().__init__(NetworkTypes) + + def __get__(self, instance, owner=None) -> ( + 'NetworkTypesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NetworkTypes': + pass + + def __enter__(self) -> 'NetworkTypes': + pass + + +class NetworkTypes( + YANGContainer, + metaclass=NetworkTypesMeta): + """ + YANG container handler. + + YANG name: network-types + """ + + _yang_name: Final[str] = 'network-types' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network' + _yang_module_name: Final[str] = 'ietf-network' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-topology': ( + te_topology := ( # YANGContainerMember( + NetworkTypesMeta. + TeTopology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NetworkTypes': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/network_types/te_topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/network_types/te_topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d41731af61cc5a91e1178ed27ff7a5634149f15 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/network_types/te_topology/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeTopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-topology + """ + + def __init__(self): + super().__init__(TeTopology) + + def __get__(self, instance, owner=None) -> ( + 'TeTopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeTopology': + pass + + def __enter__(self) -> 'TeTopology': + pass + + +class TeTopology( + YANGContainer, + metaclass=TeTopologyMeta): + """ + YANG container handler. + + YANG name: te-topology + """ + + _yang_name: Final[str] = 'te-topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeTopology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c6a31d9a0e3b49286b2df219900fc10df3c39c56 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/__init__.py @@ -0,0 +1,123 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NodeMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: node + """ + from .te import Te + from .termination_point import TerminationPoint + from .supporting_node import SupportingNode + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: node + """ + + def __init__(self): + super().__init__(Node) + + def __get__(self, instance, owner=None) -> ( + 'NodeMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Node']: + pass + + def __iter__(self, key) -> Iterator['Node']: + return super().__iter__() + + def __getitem__(self, key) -> 'Node': + return super()[key] + + def __enter__(self) -> ( + 'NodeMeta.yang_list_descriptor'): + pass + + +class Node( + YANGListItem, + metaclass=NodeMeta): + """ + YANG list item handler. + + YANG name: node + """ + + _yang_name: Final[str] = 'node' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network' + _yang_module_name: Final[str] = 'ietf-network' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'node-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'te-node-id': ( + te_node_id := YANGLeafMember( + 'te-node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-network', + 'ietf-network')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te': ( + te := ( # YANGContainerMember( + NodeMeta. + Te. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'termination-point': ( + termination_point := ( # YANGListMember( + NodeMeta. + TerminationPoint. + yang_list_descriptor())), + + 'supporting-node': ( + supporting_node := ( # YANGListMember( + NodeMeta. + SupportingNode. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Node': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/supporting_node/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/supporting_node/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..abeb4a984b9b0c939ae51217ac7144f568841550 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/supporting_node/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SupportingNodeMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: supporting-node + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: supporting-node + """ + + def __init__(self): + super().__init__(SupportingNode) + + def __get__(self, instance, owner=None) -> ( + 'SupportingNodeMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SupportingNode']: + pass + + def __iter__(self, key) -> Iterator['SupportingNode']: + return super().__iter__() + + def __getitem__(self, key) -> 'SupportingNode': + return super()[key] + + def __enter__(self) -> ( + 'SupportingNodeMeta.yang_list_descriptor'): + pass + + +class SupportingNode( + YANGListItem, + metaclass=SupportingNodeMeta): + """ + YANG list item handler. + + YANG name: supporting-node + """ + + _yang_name: Final[str] = 'supporting-node' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network' + _yang_module_name: Final[str] = 'ietf-network' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'network-ref', + 'node-ref', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network', + 'ietf-network')), + + 'node-ref': ( + node_ref := YANGLeafMember( + 'node-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network', + 'ietf-network')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SupportingNode': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2ad66ed994421c34ac0e36ef0189e6f5a21b646f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/__init__.py @@ -0,0 +1,145 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te + """ + from .statistics import Statistics + from .geolocation import Geolocation + from .te_node_attributes import TeNodeAttributes + from .information_source_state import InformationSourceState + from .tunnel_termination_point import TunnelTerminationPoint + from .information_source_entry import InformationSourceEntry + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te + """ + + def __init__(self): + super().__init__(Te) + + def __get__(self, instance, owner=None) -> ( + 'TeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Te': + pass + + def __enter__(self) -> 'Te': + pass + + +class Te( + YANGContainer, + metaclass=TeMeta): + """ + YANG container handler. + + YANG name: te + """ + + _yang_name: Final[str] = 'te' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'oper-status': ( + oper_status := YANGLeafMember( + 'oper-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'information-source': ( + information_source := YANGLeafMember( + 'information-source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'information-source-instance': ( + information_source_instance := YANGLeafMember( + 'information-source-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-multi-access-dr': ( + is_multi_access_dr := YANGLeafMember( + 'is-multi-access-dr', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'statistics': ( + statistics := ( # YANGContainerMember( + TeMeta. + Statistics. + yang_container_descriptor())), + + 'geolocation': ( + geolocation := ( # YANGContainerMember( + TeMeta. + Geolocation. + yang_container_descriptor())), + + 'te-node-attributes': ( + te_node_attributes := ( # YANGContainerMember( + TeMeta. + TeNodeAttributes. + yang_container_descriptor())), + + 'information-source-state': ( + information_source_state := ( # YANGContainerMember( + TeMeta. + InformationSourceState. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel-termination-point': ( + tunnel_termination_point := ( # YANGListMember( + TeMeta. + TunnelTerminationPoint. + yang_list_descriptor())), + + 'information-source-entry': ( + information_source_entry := ( # YANGListMember( + TeMeta. + InformationSourceEntry. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Te': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/geolocation/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/geolocation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5a631c3553d9ab5ce7b22b799dbf338a0f87fa43 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/geolocation/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GeolocationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: geolocation + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: geolocation + """ + + def __init__(self): + super().__init__(Geolocation) + + def __get__(self, instance, owner=None) -> ( + 'GeolocationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Geolocation': + pass + + def __enter__(self) -> 'Geolocation': + pass + + +class Geolocation( + YANGContainer, + metaclass=GeolocationMeta): + """ + YANG container handler. + + YANG name: geolocation + """ + + _yang_name: Final[str] = 'geolocation' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'latitude': ( + latitude := YANGLeafMember( + 'latitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'altitude': ( + altitude := YANGLeafMember( + 'altitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'longitude': ( + longitude := YANGLeafMember( + 'longitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Geolocation': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21bfe84df044875786766febf0915d7c70737106 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/__init__.py @@ -0,0 +1,142 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InformationSourceEntryMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: information-source-entry + """ + from .information_source_state import InformationSourceState + from .underlay_topology import UnderlayTopology + from .connectivity_matrices import ConnectivityMatrices + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: information-source-entry + """ + + def __init__(self): + super().__init__(InformationSourceEntry) + + def __get__(self, instance, owner=None) -> ( + 'InformationSourceEntryMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['InformationSourceEntry']: + pass + + def __iter__(self, key) -> Iterator['InformationSourceEntry']: + return super().__iter__() + + def __getitem__(self, key) -> 'InformationSourceEntry': + return super()[key] + + def __enter__(self) -> ( + 'InformationSourceEntryMeta.yang_list_descriptor'): + pass + + +class InformationSourceEntry( + YANGListItem, + metaclass=InformationSourceEntryMeta): + """ + YANG list item handler. + + YANG name: information-source-entry + """ + + _yang_name: Final[str] = 'information-source-entry' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'information-source', + 'information-source-instance', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'information-source': ( + information_source := YANGLeafMember( + 'information-source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'domain-id': ( + domain_id := YANGLeafMember( + 'domain-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-abstract': ( + is_abstract := YANGLeafMember( + 'is-abstract', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'information-source-instance': ( + information_source_instance := YANGLeafMember( + 'information-source-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'information-source-state': ( + information_source_state := ( # YANGContainerMember( + InformationSourceEntryMeta. + InformationSourceState. + yang_container_descriptor())), + + 'underlay-topology': ( + underlay_topology := ( # YANGContainerMember( + InformationSourceEntryMeta. + UnderlayTopology. + yang_container_descriptor())), + + 'connectivity-matrices': ( + connectivity_matrices := ( # YANGContainerMember( + InformationSourceEntryMeta. + ConnectivityMatrices. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InformationSourceEntry': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..08c000d9b26dfa8e9c926a9ef5705a9e9fa0fa31 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/__init__.py @@ -0,0 +1,133 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityMatricesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: connectivity-matrices + """ + from .path_properties import PathProperties + from .path_constraints import PathConstraints + from .optimizations import Optimizations + from .underlay import Underlay + from .label_restrictions import LabelRestrictions + from .connectivity_matrix import ConnectivityMatrix + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: connectivity-matrices + """ + + def __init__(self): + super().__init__(ConnectivityMatrices) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityMatricesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ConnectivityMatrices': + pass + + def __enter__(self) -> 'ConnectivityMatrices': + pass + + +class ConnectivityMatrices( + YANGContainer, + metaclass=ConnectivityMatricesMeta): + """ + YANG container handler. + + YANG name: connectivity-matrices + """ + + _yang_name: Final[str] = 'connectivity-matrices' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'number-of-entries': ( + number_of_entries := YANGLeafMember( + 'number-of-entries', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-allowed': ( + is_allowed := YANGLeafMember( + 'is-allowed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-properties': ( + path_properties := ( # YANGContainerMember( + ConnectivityMatricesMeta. + PathProperties. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + ConnectivityMatricesMeta. + PathConstraints. + yang_container_descriptor())), + + 'optimizations': ( + optimizations := ( # YANGContainerMember( + ConnectivityMatricesMeta. + Optimizations. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + ConnectivityMatricesMeta. + Underlay. + yang_container_descriptor())), + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + ConnectivityMatricesMeta. + LabelRestrictions. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'connectivity-matrix': ( + connectivity_matrix := ( # YANGListMember( + ConnectivityMatricesMeta. + ConnectivityMatrix. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityMatrices': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bc57f620463762241042a9afbb5d5fa46368dc55 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/__init__.py @@ -0,0 +1,144 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityMatrixMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: connectivity-matrix + """ + from .to import To + from .underlay import Underlay + from .path_properties import PathProperties + from .optimizations import Optimizations + from .from import From + from .path_constraints import PathConstraints + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: connectivity-matrix + """ + + def __init__(self): + super().__init__(ConnectivityMatrix) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityMatrixMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['ConnectivityMatrix']: + pass + + def __iter__(self, key) -> Iterator['ConnectivityMatrix']: + return super().__iter__() + + def __getitem__(self, key) -> 'ConnectivityMatrix': + return super()[key] + + def __enter__(self) -> ( + 'ConnectivityMatrixMeta.yang_list_descriptor'): + pass + + +class ConnectivityMatrix( + YANGListItem, + metaclass=ConnectivityMatrixMeta): + """ + YANG list item handler. + + YANG name: connectivity-matrix + """ + + _yang_name: Final[str] = 'connectivity-matrix' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'id': ( + id := YANGLeafMember( + 'id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-allowed': ( + is_allowed := YANGLeafMember( + 'is-allowed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'to': ( + to := ( # YANGContainerMember( + ConnectivityMatrixMeta. + To. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + ConnectivityMatrixMeta. + Underlay. + yang_container_descriptor())), + + 'path-properties': ( + path_properties := ( # YANGContainerMember( + ConnectivityMatrixMeta. + PathProperties. + yang_container_descriptor())), + + 'optimizations': ( + optimizations := ( # YANGContainerMember( + ConnectivityMatrixMeta. + Optimizations. + yang_container_descriptor())), + + 'from': ( + from := ( # YANGContainerMember( + ConnectivityMatrixMeta. + From. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + ConnectivityMatrixMeta. + PathConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityMatrix': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..14cbae7304f9e1b80e18a1547974269f00b66621 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class FromMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: from + """ + from .label_restrictions import LabelRestrictions + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: from + """ + + def __init__(self): + super().__init__(From) + + def __get__(self, instance, owner=None) -> ( + 'FromMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'From': + pass + + def __enter__(self) -> 'From': + pass + + +class From( + YANGContainer, + metaclass=FromMeta): + """ + YANG container handler. + + YANG name: from + """ + + _yang_name: Final[str] = 'from' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tp-ref': ( + tp_ref := YANGLeafMember( + 'tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + FromMeta. + LabelRestrictions. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'From': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..86c3a10ff67557b730c7883f68f60a5220014139 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_start import LabelStart + from .label_step import LabelStep + from .label_end import LabelEnd + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c8d4f4c8def0e90dabe399cc305dc3b8d3d500 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: optimizations + """ + from .algorithm import Algorithm + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: optimizations + """ + + def __init__(self): + super().__init__(Optimizations) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Optimizations': + pass + + def __enter__(self) -> 'Optimizations': + pass + + +class Optimizations( + YANGContainer, + metaclass=OptimizationsMeta): + """ + YANG container handler. + + YANG name: optimizations + """ + + _yang_name: Final[str] = 'optimizations' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Optimizations': + instance = super().__new__(cls) + instance._yang_choices = { + + 'algorithm': + OptimizationsMeta.Algorithm( + instance), + } + return instance + + @property + def algorithm(self) -> ( + OptimizationsMeta.Algorithm): + return self._yang_choices['algorithm'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9e0ca52a42ed25af1b7e0612d3e9a6b3d43b6ef9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AlgorithmMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: algorithm + """ + + from .objective_function import ObjectiveFunction + from .metric import Metric + + class objective_function_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.objective_function_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + class metric_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.Metric) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.metric_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + +class Algorithm(YANGChoice, metaclass=AlgorithmMeta): + """ + YANG choice handler. + + YANG name: algorithm + """ + + _yang_name: Final[str] = 'algorithm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'objective-function': ( + objective_function := ( # YANGChoiceCase( + AlgorithmMeta. + objective_function_case_descriptor())), + + 'metric': ( + metric := ( # YANGChoiceCase( + AlgorithmMeta. + metric_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e7d1da8ee3719d0d6a3c401df7340fbd3517e8ed --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric + """ + from .tiebreakers import Tiebreakers + from .optimization_metric import OptimizationMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__(Metric) + + def __get__(self, instance, owner=None) -> ( + 'MetricMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Metric': + pass + + def __enter__(self) -> 'Metric': + pass + + +class Metric( + YANGContainer, + metaclass=MetricMeta): + """ + YANG container handler. + + YANG name: metric + """ + + _yang_name: Final[str] = 'metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tiebreakers': ( + tiebreakers := ( # YANGContainerMember( + MetricMeta. + Tiebreakers. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'optimization-metric': ( + optimization_metric := ( # YANGListMember( + MetricMeta. + OptimizationMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Metric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e0b3f85a0993ca8184c4cec6a891f373b0666767 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: optimization-metric + """ + from .explicit_route_include_objects import ExplicitRouteIncludeObjects + from .explicit_route_exclude_objects import ExplicitRouteExcludeObjects + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: optimization-metric + """ + + def __init__(self): + super().__init__(OptimizationMetric) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['OptimizationMetric']: + pass + + def __iter__(self, key) -> Iterator['OptimizationMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'OptimizationMetric': + return super()[key] + + def __enter__(self) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + pass + + +class OptimizationMetric( + YANGListItem, + metaclass=OptimizationMetricMeta): + """ + YANG list item handler. + + YANG name: optimization-metric + """ + + _yang_name: Final[str] = 'optimization-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'weight': ( + weight := YANGLeafMember( + 'weight', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'explicit-route-include-objects': ( + explicit_route_include_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteIncludeObjects. + yang_container_descriptor())), + + 'explicit-route-exclude-objects': ( + explicit_route_exclude_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteExcludeObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OptimizationMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aea7bdd4cd5ed1743a1764899878a1ac8035348e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteExcludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + from .route_object_exclude_object import RouteObjectExcludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-exclude-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteExcludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteExcludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteExcludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteExcludeObjects': + pass + + +class ExplicitRouteExcludeObjects( + YANGContainer, + metaclass=ExplicitRouteExcludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + + _yang_name: Final[str] = 'explicit-route-exclude-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-exclude-object': ( + route_object_exclude_object := ( # YANGListMember( + ExplicitRouteExcludeObjectsMeta. + RouteObjectExcludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteExcludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..405906d3e6d9dd1eda79aae3a6302c37e0e24988 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectExcludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-exclude-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-exclude-object + """ + + def __init__(self): + super().__init__(RouteObjectExcludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectExcludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectExcludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectExcludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectExcludeObject( + YANGListItem, + metaclass=RouteObjectExcludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-exclude-object + """ + + _yang_name: Final[str] = 'route-object-exclude-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectExcludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectExcludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectExcludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e00223044020f31fddaff4d0a41e5b5c2c7181bc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py @@ -0,0 +1,217 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + from .srlg import Srlg + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class srlg_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__( + TypeMeta.Srlg) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.srlg_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Srlg'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Srlg'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'srlg': ( + srlg := ( # YANGChoiceCase( + TypeMeta. + srlg_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..64a8ec6d5e2fd4a77c59c13b3e37cacb001c91fe --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..420f996a13a20bf122ec87f0fbb109b34246eb61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + from .srlg import Srlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'srlg': ( + srlg := ( # YANGContainerMember( + SrlgMeta. + Srlg. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95a1628e4caf545e0d31823f89ea93178ffb76c7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'srlg': ( + srlg := YANGLeafMember( + 'srlg', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2aa767b55c350d6b4b7ec04998c04f5fa568d051 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3209b99bad73493077e9e91a8053f320b05c11c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteIncludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-include-objects + """ + from .route_object_include_object import RouteObjectIncludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-include-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteIncludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteIncludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteIncludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteIncludeObjects': + pass + + +class ExplicitRouteIncludeObjects( + YANGContainer, + metaclass=ExplicitRouteIncludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-include-objects + """ + + _yang_name: Final[str] = 'explicit-route-include-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-include-object': ( + route_object_include_object := ( # YANGListMember( + ExplicitRouteIncludeObjectsMeta. + RouteObjectIncludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteIncludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c9f24330ff35e20e47be0db730f6ec682dd71d2d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectIncludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-include-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-include-object + """ + + def __init__(self): + super().__init__(RouteObjectIncludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectIncludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectIncludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectIncludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectIncludeObject( + YANGListItem, + metaclass=RouteObjectIncludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-include-object + """ + + _yang_name: Final[str] = 'route-object-include-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectIncludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectIncludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectIncludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..99085dad5868ea8d4f63c188ccd69653b0d7a1d4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .label import Label + from .as_number import AsNumber + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2aa767b55c350d6b4b7ec04998c04f5fa568d051 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d345b57b342afaa50a04c5782794f34b810b795c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakersMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tiebreakers + """ + from .tiebreaker import Tiebreaker + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tiebreakers + """ + + def __init__(self): + super().__init__(Tiebreakers) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakersMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tiebreakers': + pass + + def __enter__(self) -> 'Tiebreakers': + pass + + +class Tiebreakers( + YANGContainer, + metaclass=TiebreakersMeta): + """ + YANG container handler. + + YANG name: tiebreakers + """ + + _yang_name: Final[str] = 'tiebreakers' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tiebreaker': ( + tiebreaker := ( # YANGListMember( + TiebreakersMeta. + Tiebreaker. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreakers': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..500d880ad6ad48b8079aa3bea0b1e644f7008f49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakerMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tiebreaker + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tiebreaker + """ + + def __init__(self): + super().__init__(Tiebreaker) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tiebreaker']: + pass + + def __iter__(self, key) -> Iterator['Tiebreaker']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tiebreaker': + return super()[key] + + def __enter__(self) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + pass + + +class Tiebreaker( + YANGListItem, + metaclass=TiebreakerMeta): + """ + YANG list item handler. + + YANG name: tiebreaker + """ + + _yang_name: Final[str] = 'tiebreaker' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tiebreaker-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tiebreaker-type': ( + tiebreaker_type := YANGLeafMember( + 'tiebreaker-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreaker': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd32a2bb98c6e47f795103fbc122cbf7957e1e6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + from .objective_function import ObjectiveFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'objective-function': ( + objective_function := ( # YANGContainerMember( + ObjectiveFunctionMeta. + ObjectiveFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af72bcf2702ccee1d360bad39000241d1abfdc19 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/objective_function/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'objective-function-type': ( + objective_function_type := YANGLeafMember( + 'objective-function-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b473367cc49ea6b9b116af98e3d25cf058f70ffc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/__init__.py @@ -0,0 +1,151 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + from .te_bandwidth import TeBandwidth + from .path_srlgs_lists import PathSrlgsLists + from .path_srlgs_names import PathSrlgsNames + from .path_affinity_names import PathAffinityNames + from .path_metric_bounds import PathMetricBounds + from .path_affinities_values import PathAffinitiesValues + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hold-priority': ( + hold_priority := YANGLeafMember( + 'hold-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'setup-priority': ( + setup_priority := YANGLeafMember( + 'setup-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'signaling-type': ( + signaling_type := YANGLeafMember( + 'signaling-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection': ( + link_protection := YANGLeafMember( + 'link-protection', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + PathConstraintsMeta. + TeBandwidth. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-metric-bounds': ( + path_metric_bounds := ( # YANGContainerMember( + PathConstraintsMeta. + PathMetricBounds. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinitiesValues. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e4a21b11accc2103aa85169cb46c386658d5cc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..356f7761b99b2e313b0638407dbaaa3996e6c418 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-metric-bounds + """ + from .path_metric_bound import PathMetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-metric-bounds + """ + + def __init__(self): + super().__init__(PathMetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathMetricBounds': + pass + + def __enter__(self) -> 'PathMetricBounds': + pass + + +class PathMetricBounds( + YANGContainer, + metaclass=PathMetricBoundsMeta): + """ + YANG container handler. + + YANG name: path-metric-bounds + """ + + _yang_name: Final[str] = 'path-metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric-bound': ( + path_metric_bound := ( # YANGListMember( + PathMetricBoundsMeta. + PathMetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/path_metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/path_metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2a97d5e3e1d7066756b051d139f997d9a46b3c6b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/path_metric_bound/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric-bound + """ + + def __init__(self): + super().__init__(PathMetricBound) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetricBound']: + pass + + def __iter__(self, key) -> Iterator['PathMetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetricBound': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + pass + + +class PathMetricBound( + YANGListItem, + metaclass=PathMetricBoundMeta): + """ + YANG list item handler. + + YANG name: path-metric-bound + """ + + _yang_name: Final[str] = 'path-metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'upper-bound': ( + upper_bound := YANGLeafMember( + 'upper-bound', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..76541b227cefa1dca289ff8b4cc6350032acc02f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathPropertiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-properties + """ + from .path_route_objects import PathRouteObjects + from .path_srlgs_names import PathSrlgsNames + from .path_srlgs_lists import PathSrlgsLists + from .path_affinities_values import PathAffinitiesValues + from .path_affinity_names import PathAffinityNames + from .path_metric import PathMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-properties + """ + + def __init__(self): + super().__init__(PathProperties) + + def __get__(self, instance, owner=None) -> ( + 'PathPropertiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathProperties': + pass + + def __enter__(self) -> 'PathProperties': + pass + + +class PathProperties( + YANGContainer, + metaclass=PathPropertiesMeta): + """ + YANG container handler. + + YANG name: path-properties + """ + + _yang_name: Final[str] = 'path-properties' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-route-objects': ( + path_route_objects := ( # YANGContainerMember( + PathPropertiesMeta. + PathRouteObjects. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinityNames. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric': ( + path_metric := ( # YANGListMember( + PathPropertiesMeta. + PathMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathProperties': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e4a21b11accc2103aa85169cb46c386658d5cc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d6ae074074e7913854992f9bd32a8f51f6b9d7b7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_metric/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric + """ + + def __init__(self): + super().__init__(PathMetric) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetric']: + pass + + def __iter__(self, key) -> Iterator['PathMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetric': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricMeta.yang_list_descriptor'): + pass + + +class PathMetric( + YANGListItem, + metaclass=PathMetricMeta): + """ + YANG list item handler. + + YANG name: path-metric + """ + + _yang_name: Final[str] = 'path-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'accumulative-value': ( + accumulative_value := YANGLeafMember( + 'accumulative-value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2af8eb3f47d7b0ceb2d21f9f5b1ee44b432ab35f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-route-objects + """ + from .path_route_object import PathRouteObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-route-objects + """ + + def __init__(self): + super().__init__(PathRouteObjects) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathRouteObjects': + pass + + def __enter__(self) -> 'PathRouteObjects': + pass + + +class PathRouteObjects( + YANGContainer, + metaclass=PathRouteObjectsMeta): + """ + YANG container handler. + + YANG name: path-route-objects + """ + + _yang_name: Final[str] = 'path-route-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-route-object': ( + path_route_object := ( # YANGListMember( + PathRouteObjectsMeta. + PathRouteObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74b9e21c769902d7a2bb1f362d2e95cbf5d862cd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-route-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-route-object + """ + + def __init__(self): + super().__init__(PathRouteObject) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathRouteObject']: + pass + + def __iter__(self, key) -> Iterator['PathRouteObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathRouteObject': + return super()[key] + + def __enter__(self) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + pass + + +class PathRouteObject( + YANGListItem, + metaclass=PathRouteObjectMeta): + """ + YANG list item handler. + + YANG name: path-route-object + """ + + _yang_name: Final[str] = 'path-route-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathRouteObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathRouteObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8bc2d82e13718733c4ed76acde67b8508071d571 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d9d3d58559fab79fa12a634fb4aecbef61780f1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3a6876e61b9d99b8ed5b00bc13f60857e8fb3d76 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d03118f5c94e3726341c4332447847c61623d616 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ToMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: to + """ + from .label_restrictions import LabelRestrictions + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: to + """ + + def __init__(self): + super().__init__(To) + + def __get__(self, instance, owner=None) -> ( + 'ToMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'To': + pass + + def __enter__(self) -> 'To': + pass + + +class To( + YANGContainer, + metaclass=ToMeta): + """ + YANG container handler. + + YANG name: to + """ + + _yang_name: Final[str] = 'to' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tp-ref': ( + tp_ref := YANGLeafMember( + 'tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + ToMeta. + LabelRestrictions. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'To': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..61cb67d4bdc9682e1228c9cb9ddfb86817c96f62 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_end import LabelEnd + from .label_start import LabelStart + from .label_step import LabelStep + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2feb9b8f1d3512055ea66c91d1dfc9059e8cf901 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .primary_path import PrimaryPath + from .tunnels import Tunnels + from .tunnel_termination_points import TunnelTerminationPoints + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..eee438314ebe12c55dba835cf5f6839760a31c61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..077e86df002f4bbdf6f8b1a9767746e1493b8fc4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..64a8ec6d5e2fd4a77c59c13b3e37cacb001c91fe --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..00c674167360cd2724dd7263e34c54dbb27dbccb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a2076e54c3ca2f4e75844db6a7ca736e6a1cc6ce --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e568286bdabfa9cd970ff66b3e9b6a807b0f31f3 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c5cccf39482c3497e05c1c7ab8f4fdd3e2d7490b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f854dfd329ce016317b7b9743ace874769f03094 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/connectivity_matrix/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..32c30d13361c09cf5f2a51b8e1e645103a430a6a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_step import LabelStep + from .label_start import LabelStart + from .label_end import LabelEnd + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c8d4f4c8def0e90dabe399cc305dc3b8d3d500 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: optimizations + """ + from .algorithm import Algorithm + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: optimizations + """ + + def __init__(self): + super().__init__(Optimizations) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Optimizations': + pass + + def __enter__(self) -> 'Optimizations': + pass + + +class Optimizations( + YANGContainer, + metaclass=OptimizationsMeta): + """ + YANG container handler. + + YANG name: optimizations + """ + + _yang_name: Final[str] = 'optimizations' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Optimizations': + instance = super().__new__(cls) + instance._yang_choices = { + + 'algorithm': + OptimizationsMeta.Algorithm( + instance), + } + return instance + + @property + def algorithm(self) -> ( + OptimizationsMeta.Algorithm): + return self._yang_choices['algorithm'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d82c7bf9c5ec990484589d660738ffe3d2d9f6bf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AlgorithmMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: algorithm + """ + + from .metric import Metric + from .objective_function import ObjectiveFunction + + class metric_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.Metric) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.metric_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + class objective_function_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.objective_function_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + +class Algorithm(YANGChoice, metaclass=AlgorithmMeta): + """ + YANG choice handler. + + YANG name: algorithm + """ + + _yang_name: Final[str] = 'algorithm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'metric': ( + metric := ( # YANGChoiceCase( + AlgorithmMeta. + metric_case_descriptor())), + + 'objective-function': ( + objective_function := ( # YANGChoiceCase( + AlgorithmMeta. + objective_function_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e7d1da8ee3719d0d6a3c401df7340fbd3517e8ed --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric + """ + from .tiebreakers import Tiebreakers + from .optimization_metric import OptimizationMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__(Metric) + + def __get__(self, instance, owner=None) -> ( + 'MetricMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Metric': + pass + + def __enter__(self) -> 'Metric': + pass + + +class Metric( + YANGContainer, + metaclass=MetricMeta): + """ + YANG container handler. + + YANG name: metric + """ + + _yang_name: Final[str] = 'metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tiebreakers': ( + tiebreakers := ( # YANGContainerMember( + MetricMeta. + Tiebreakers. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'optimization-metric': ( + optimization_metric := ( # YANGListMember( + MetricMeta. + OptimizationMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Metric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bad2331fc0f109b98bda93287a822244302b5d1e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: optimization-metric + """ + from .explicit_route_exclude_objects import ExplicitRouteExcludeObjects + from .explicit_route_include_objects import ExplicitRouteIncludeObjects + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: optimization-metric + """ + + def __init__(self): + super().__init__(OptimizationMetric) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['OptimizationMetric']: + pass + + def __iter__(self, key) -> Iterator['OptimizationMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'OptimizationMetric': + return super()[key] + + def __enter__(self) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + pass + + +class OptimizationMetric( + YANGListItem, + metaclass=OptimizationMetricMeta): + """ + YANG list item handler. + + YANG name: optimization-metric + """ + + _yang_name: Final[str] = 'optimization-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'weight': ( + weight := YANGLeafMember( + 'weight', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'explicit-route-exclude-objects': ( + explicit_route_exclude_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteExcludeObjects. + yang_container_descriptor())), + + 'explicit-route-include-objects': ( + explicit_route_include_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteIncludeObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OptimizationMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aea7bdd4cd5ed1743a1764899878a1ac8035348e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteExcludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + from .route_object_exclude_object import RouteObjectExcludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-exclude-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteExcludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteExcludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteExcludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteExcludeObjects': + pass + + +class ExplicitRouteExcludeObjects( + YANGContainer, + metaclass=ExplicitRouteExcludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + + _yang_name: Final[str] = 'explicit-route-exclude-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-exclude-object': ( + route_object_exclude_object := ( # YANGListMember( + ExplicitRouteExcludeObjectsMeta. + RouteObjectExcludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteExcludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..405906d3e6d9dd1eda79aae3a6302c37e0e24988 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectExcludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-exclude-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-exclude-object + """ + + def __init__(self): + super().__init__(RouteObjectExcludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectExcludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectExcludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectExcludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectExcludeObject( + YANGListItem, + metaclass=RouteObjectExcludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-exclude-object + """ + + _yang_name: Final[str] = 'route-object-exclude-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectExcludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectExcludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectExcludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8411b9056a87031a8a5453bd7ef0d46324215a2f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py @@ -0,0 +1,217 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .srlg import Srlg + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class srlg_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__( + TypeMeta.Srlg) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.srlg_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Srlg'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Srlg'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'srlg': ( + srlg := ( # YANGChoiceCase( + TypeMeta. + srlg_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8837ea16f120b8d9f40ee5099f46294b6ab79579 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..420f996a13a20bf122ec87f0fbb109b34246eb61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + from .srlg import Srlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'srlg': ( + srlg := ( # YANGContainerMember( + SrlgMeta. + Srlg. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95a1628e4caf545e0d31823f89ea93178ffb76c7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'srlg': ( + srlg := YANGLeafMember( + 'srlg', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..07c0b7b779289a6ac9a9123fd540526dc6d190fb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3209b99bad73493077e9e91a8053f320b05c11c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteIncludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-include-objects + """ + from .route_object_include_object import RouteObjectIncludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-include-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteIncludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteIncludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteIncludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteIncludeObjects': + pass + + +class ExplicitRouteIncludeObjects( + YANGContainer, + metaclass=ExplicitRouteIncludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-include-objects + """ + + _yang_name: Final[str] = 'explicit-route-include-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-include-object': ( + route_object_include_object := ( # YANGListMember( + ExplicitRouteIncludeObjectsMeta. + RouteObjectIncludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteIncludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c9f24330ff35e20e47be0db730f6ec682dd71d2d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectIncludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-include-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-include-object + """ + + def __init__(self): + super().__init__(RouteObjectIncludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectIncludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectIncludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectIncludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectIncludeObject( + YANGListItem, + metaclass=RouteObjectIncludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-include-object + """ + + _yang_name: Final[str] = 'route-object-include-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectIncludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectIncludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectIncludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..70317d31c9d8ee9d772e58c135569168cf8843f7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .label import Label + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aa5135a1afed60270d2606ad4c7ad19b66f70d7c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d345b57b342afaa50a04c5782794f34b810b795c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakersMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tiebreakers + """ + from .tiebreaker import Tiebreaker + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tiebreakers + """ + + def __init__(self): + super().__init__(Tiebreakers) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakersMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tiebreakers': + pass + + def __enter__(self) -> 'Tiebreakers': + pass + + +class Tiebreakers( + YANGContainer, + metaclass=TiebreakersMeta): + """ + YANG container handler. + + YANG name: tiebreakers + """ + + _yang_name: Final[str] = 'tiebreakers' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tiebreaker': ( + tiebreaker := ( # YANGListMember( + TiebreakersMeta. + Tiebreaker. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreakers': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..500d880ad6ad48b8079aa3bea0b1e644f7008f49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakerMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tiebreaker + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tiebreaker + """ + + def __init__(self): + super().__init__(Tiebreaker) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tiebreaker']: + pass + + def __iter__(self, key) -> Iterator['Tiebreaker']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tiebreaker': + return super()[key] + + def __enter__(self) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + pass + + +class Tiebreaker( + YANGListItem, + metaclass=TiebreakerMeta): + """ + YANG list item handler. + + YANG name: tiebreaker + """ + + _yang_name: Final[str] = 'tiebreaker' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tiebreaker-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tiebreaker-type': ( + tiebreaker_type := YANGLeafMember( + 'tiebreaker-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreaker': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd32a2bb98c6e47f795103fbc122cbf7957e1e6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/objective_function/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + from .objective_function import ObjectiveFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'objective-function': ( + objective_function := ( # YANGContainerMember( + ObjectiveFunctionMeta. + ObjectiveFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/objective_function/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/objective_function/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af72bcf2702ccee1d360bad39000241d1abfdc19 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/optimizations/algorithm/objective_function/objective_function/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'objective-function-type': ( + objective_function_type := YANGLeafMember( + 'objective-function-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b600b1aeaf464f293a697c09c163096f730379f2 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/__init__.py @@ -0,0 +1,151 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + from .te_bandwidth import TeBandwidth + from .path_metric_bounds import PathMetricBounds + from .path_affinities_values import PathAffinitiesValues + from .path_srlgs_lists import PathSrlgsLists + from .path_affinity_names import PathAffinityNames + from .path_srlgs_names import PathSrlgsNames + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hold-priority': ( + hold_priority := YANGLeafMember( + 'hold-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection': ( + link_protection := YANGLeafMember( + 'link-protection', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'setup-priority': ( + setup_priority := YANGLeafMember( + 'setup-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'signaling-type': ( + signaling_type := YANGLeafMember( + 'signaling-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + PathConstraintsMeta. + TeBandwidth. + yang_container_descriptor())), + + 'path-metric-bounds': ( + path_metric_bounds := ( # YANGContainerMember( + PathConstraintsMeta. + PathMetricBounds. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsNames. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..356f7761b99b2e313b0638407dbaaa3996e6c418 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-metric-bounds + """ + from .path_metric_bound import PathMetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-metric-bounds + """ + + def __init__(self): + super().__init__(PathMetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathMetricBounds': + pass + + def __enter__(self) -> 'PathMetricBounds': + pass + + +class PathMetricBounds( + YANGContainer, + metaclass=PathMetricBoundsMeta): + """ + YANG container handler. + + YANG name: path-metric-bounds + """ + + _yang_name: Final[str] = 'path-metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric-bound': ( + path_metric_bound := ( # YANGListMember( + PathMetricBoundsMeta. + PathMetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_metric_bounds/path_metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_metric_bounds/path_metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e6e72a44fd364b7d9238cef98eba888090a23f76 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_metric_bounds/path_metric_bound/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric-bound + """ + + def __init__(self): + super().__init__(PathMetricBound) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetricBound']: + pass + + def __iter__(self, key) -> Iterator['PathMetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetricBound': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + pass + + +class PathMetricBound( + YANGListItem, + metaclass=PathMetricBoundMeta): + """ + YANG list item handler. + + YANG name: path-metric-bound + """ + + _yang_name: Final[str] = 'path-metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'upper-bound': ( + upper_bound := YANGLeafMember( + 'upper-bound', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_constraints/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..149786798cff216d2d5c3159b457969263950a72 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathPropertiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-properties + """ + from .path_affinities_values import PathAffinitiesValues + from .path_route_objects import PathRouteObjects + from .path_srlgs_lists import PathSrlgsLists + from .path_affinity_names import PathAffinityNames + from .path_srlgs_names import PathSrlgsNames + from .path_metric import PathMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-properties + """ + + def __init__(self): + super().__init__(PathProperties) + + def __get__(self, instance, owner=None) -> ( + 'PathPropertiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathProperties': + pass + + def __enter__(self) -> 'PathProperties': + pass + + +class PathProperties( + YANGContainer, + metaclass=PathPropertiesMeta): + """ + YANG container handler. + + YANG name: path-properties + """ + + _yang_name: Final[str] = 'path-properties' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-route-objects': ( + path_route_objects := ( # YANGContainerMember( + PathPropertiesMeta. + PathRouteObjects. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsNames. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric': ( + path_metric := ( # YANGListMember( + PathPropertiesMeta. + PathMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathProperties': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7645abedd4d25aeb9c77aa579c2972a450d00a6e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_metric/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric + """ + + def __init__(self): + super().__init__(PathMetric) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetric']: + pass + + def __iter__(self, key) -> Iterator['PathMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetric': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricMeta.yang_list_descriptor'): + pass + + +class PathMetric( + YANGListItem, + metaclass=PathMetricMeta): + """ + YANG list item handler. + + YANG name: path-metric + """ + + _yang_name: Final[str] = 'path-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'accumulative-value': ( + accumulative_value := YANGLeafMember( + 'accumulative-value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2af8eb3f47d7b0ceb2d21f9f5b1ee44b432ab35f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-route-objects + """ + from .path_route_object import PathRouteObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-route-objects + """ + + def __init__(self): + super().__init__(PathRouteObjects) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathRouteObjects': + pass + + def __enter__(self) -> 'PathRouteObjects': + pass + + +class PathRouteObjects( + YANGContainer, + metaclass=PathRouteObjectsMeta): + """ + YANG container handler. + + YANG name: path-route-objects + """ + + _yang_name: Final[str] = 'path-route-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-route-object': ( + path_route_object := ( # YANGListMember( + PathRouteObjectsMeta. + PathRouteObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74b9e21c769902d7a2bb1f362d2e95cbf5d862cd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-route-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-route-object + """ + + def __init__(self): + super().__init__(PathRouteObject) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathRouteObject']: + pass + + def __iter__(self, key) -> Iterator['PathRouteObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathRouteObject': + return super()[key] + + def __enter__(self) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + pass + + +class PathRouteObject( + YANGListItem, + metaclass=PathRouteObjectMeta): + """ + YANG list item handler. + + YANG name: path-route-object + """ + + _yang_name: Final[str] = 'path-route-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathRouteObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathRouteObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..535505eea9d601de2d3ee70ab7061cbcf2e35bc8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0f8e113b567402f37aecdf644dae003b86cc8bb4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/path_properties/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ac722c47add5d381fef94d2c3a2f5750b49a2688 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .tunnels import Tunnels + from .tunnel_termination_points import TunnelTerminationPoints + from .primary_path import PrimaryPath + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..eee438314ebe12c55dba835cf5f6839760a31c61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3762dccee93d6c5fc548fea761a80e03cd0398d6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..00c674167360cd2724dd7263e34c54dbb27dbccb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d1ab68ff674ea58adde5a644c74609928fe6f874 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .label import Label + from .numbered_link_hop import NumberedLinkHop + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d9d3d58559fab79fa12a634fb4aecbef61780f1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c909481cb8745c1895e9d6bcb7fb53fa10296f40 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8ae8cc268f3c4fc331cd1e1018be41d113da9183 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d36aa35acd17db473e177b143afdec573f0b4927 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/connectivity_matrices/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/information_source_state/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/information_source_state/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..26d315f6a43287274e5b410c83c64a950c07014d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/information_source_state/__init__.py @@ -0,0 +1,104 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InformationSourceStateMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: information-source-state + """ + from .topology import Topology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: information-source-state + """ + + def __init__(self): + super().__init__(InformationSourceState) + + def __get__(self, instance, owner=None) -> ( + 'InformationSourceStateMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'InformationSourceState': + pass + + def __enter__(self) -> 'InformationSourceState': + pass + + +class InformationSourceState( + YANGContainer, + metaclass=InformationSourceStateMeta): + """ + YANG container handler. + + YANG name: information-source-state + """ + + _yang_name: Final[str] = 'information-source-state' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-instance': ( + network_instance := YANGLeafMember( + 'network-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'credibility-preference': ( + credibility_preference := YANGLeafMember( + 'credibility-preference', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'logical-network-element': ( + logical_network_element := YANGLeafMember( + 'logical-network-element', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'topology': ( + topology := ( # YANGContainerMember( + InformationSourceStateMeta. + Topology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InformationSourceState': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/information_source_state/topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/information_source_state/topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9e09ccdff8c5f951521b350308c3922079bad836 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/information_source_state/topology/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: topology + """ + + def __init__(self): + super().__init__(Topology) + + def __get__(self, instance, owner=None) -> ( + 'TopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Topology': + pass + + def __enter__(self) -> 'Topology': + pass + + +class Topology( + YANGContainer, + metaclass=TopologyMeta): + """ + YANG container handler. + + YANG name: topology + """ + + _yang_name: Final[str] = 'topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-ref': ( + node_ref := YANGLeafMember( + 'node-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Topology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/underlay_topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/underlay_topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42dee7a72fe4a5d79128cf6ad278af68094e6692 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_entry/underlay_topology/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayTopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay-topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay-topology + """ + + def __init__(self): + super().__init__(UnderlayTopology) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayTopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnderlayTopology': + pass + + def __enter__(self) -> 'UnderlayTopology': + pass + + +class UnderlayTopology( + YANGContainer, + metaclass=UnderlayTopologyMeta): + """ + YANG container handler. + + YANG name: underlay-topology + """ + + _yang_name: Final[str] = 'underlay-topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnderlayTopology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_state/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_state/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6d2edeb71cbf031bc1516862b7175c9ed004e9a0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_state/__init__.py @@ -0,0 +1,104 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InformationSourceStateMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: information-source-state + """ + from .topology import Topology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: information-source-state + """ + + def __init__(self): + super().__init__(InformationSourceState) + + def __get__(self, instance, owner=None) -> ( + 'InformationSourceStateMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'InformationSourceState': + pass + + def __enter__(self) -> 'InformationSourceState': + pass + + +class InformationSourceState( + YANGContainer, + metaclass=InformationSourceStateMeta): + """ + YANG container handler. + + YANG name: information-source-state + """ + + _yang_name: Final[str] = 'information-source-state' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'logical-network-element': ( + logical_network_element := YANGLeafMember( + 'logical-network-element', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'credibility-preference': ( + credibility_preference := YANGLeafMember( + 'credibility-preference', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-instance': ( + network_instance := YANGLeafMember( + 'network-instance', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'topology': ( + topology := ( # YANGContainerMember( + InformationSourceStateMeta. + Topology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InformationSourceState': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_state/topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_state/topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9e09ccdff8c5f951521b350308c3922079bad836 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/information_source_state/topology/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: topology + """ + + def __init__(self): + super().__init__(Topology) + + def __get__(self, instance, owner=None) -> ( + 'TopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Topology': + pass + + def __enter__(self) -> 'Topology': + pass + + +class Topology( + YANGContainer, + metaclass=TopologyMeta): + """ + YANG container handler. + + YANG name: topology + """ + + _yang_name: Final[str] = 'topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-ref': ( + node_ref := YANGLeafMember( + 'node-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Topology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5c42b5a651c746140109908a98c5d411f7b354b4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/__init__.py @@ -0,0 +1,99 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StatisticsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: statistics + """ + from .node import Node + from .connectivity_matrix_entry import ConnectivityMatrixEntry + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: statistics + """ + + def __init__(self): + super().__init__(Statistics) + + def __get__(self, instance, owner=None) -> ( + 'StatisticsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Statistics': + pass + + def __enter__(self) -> 'Statistics': + pass + + +class Statistics( + YANGContainer, + metaclass=StatisticsMeta): + """ + YANG container handler. + + YANG name: statistics + """ + + _yang_name: Final[str] = 'statistics' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'discontinuity-time': ( + discontinuity_time := YANGLeafMember( + 'discontinuity-time', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'node': ( + node := ( # YANGContainerMember( + StatisticsMeta. + Node. + yang_container_descriptor())), + + 'connectivity-matrix-entry': ( + connectivity_matrix_entry := ( # YANGContainerMember( + StatisticsMeta. + ConnectivityMatrixEntry. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Statistics': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/connectivity_matrix_entry/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/connectivity_matrix_entry/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7ae31f705e9a8fa0e6bb6614787e440ad5d86410 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/connectivity_matrix_entry/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityMatrixEntryMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: connectivity-matrix-entry + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: connectivity-matrix-entry + """ + + def __init__(self): + super().__init__(ConnectivityMatrixEntry) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityMatrixEntryMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ConnectivityMatrixEntry': + pass + + def __enter__(self) -> 'ConnectivityMatrixEntry': + pass + + +class ConnectivityMatrixEntry( + YANGContainer, + metaclass=ConnectivityMatrixEntryMeta): + """ + YANG container handler. + + YANG name: connectivity-matrix-entry + """ + + _yang_name: Final[str] = 'connectivity-matrix-entry' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enables': ( + enables := YANGLeafMember( + 'enables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'modifies': ( + modifies := YANGLeafMember( + 'modifies', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'creates': ( + creates := YANGLeafMember( + 'creates', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disables': ( + disables := YANGLeafMember( + 'disables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'deletes': ( + deletes := YANGLeafMember( + 'deletes', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityMatrixEntry': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/node/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/node/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c56ab2444397767e1a021bf9158d0f3ccad1a088 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/statistics/node/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NodeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: node + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: node + """ + + def __init__(self): + super().__init__(Node) + + def __get__(self, instance, owner=None) -> ( + 'NodeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Node': + pass + + def __enter__(self) -> 'Node': + pass + + +class Node( + YANGContainer, + metaclass=NodeMeta): + """ + YANG container handler. + + YANG name: node + """ + + _yang_name: Final[str] = 'node' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enables': ( + enables := YANGLeafMember( + 'enables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'maintenance-clears': ( + maintenance_clears := YANGLeafMember( + 'maintenance-clears', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disables': ( + disables := YANGLeafMember( + 'disables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'maintenance-sets': ( + maintenance_sets := YANGLeafMember( + 'maintenance-sets', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'modifies': ( + modifies := YANGLeafMember( + 'modifies', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Node': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d34072811b1c72f6894141790ae68180723d5b09 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeNodeAttributesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-node-attributes + """ + from .connectivity_matrices import ConnectivityMatrices + from .underlay_topology import UnderlayTopology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-node-attributes + """ + + def __init__(self): + super().__init__(TeNodeAttributes) + + def __get__(self, instance, owner=None) -> ( + 'TeNodeAttributesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeNodeAttributes': + pass + + def __enter__(self) -> 'TeNodeAttributes': + pass + + +class TeNodeAttributes( + YANGContainer, + metaclass=TeNodeAttributesMeta): + """ + YANG container handler. + + YANG name: te-node-attributes + """ + + _yang_name: Final[str] = 'te-node-attributes' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'domain-id': ( + domain_id := YANGLeafMember( + 'domain-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-abstract': ( + is_abstract := YANGLeafMember( + 'is-abstract', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'admin-status': ( + admin_status := YANGLeafMember( + 'admin-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'connectivity-matrices': ( + connectivity_matrices := ( # YANGContainerMember( + TeNodeAttributesMeta. + ConnectivityMatrices. + yang_container_descriptor())), + + 'underlay-topology': ( + underlay_topology := ( # YANGContainerMember( + TeNodeAttributesMeta. + UnderlayTopology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeNodeAttributes': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b6cae8709d65455d297c24861f6fd52badff4745 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/__init__.py @@ -0,0 +1,133 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityMatricesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: connectivity-matrices + """ + from .label_restrictions import LabelRestrictions + from .optimizations import Optimizations + from .underlay import Underlay + from .path_properties import PathProperties + from .path_constraints import PathConstraints + from .connectivity_matrix import ConnectivityMatrix + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: connectivity-matrices + """ + + def __init__(self): + super().__init__(ConnectivityMatrices) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityMatricesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ConnectivityMatrices': + pass + + def __enter__(self) -> 'ConnectivityMatrices': + pass + + +class ConnectivityMatrices( + YANGContainer, + metaclass=ConnectivityMatricesMeta): + """ + YANG container handler. + + YANG name: connectivity-matrices + """ + + _yang_name: Final[str] = 'connectivity-matrices' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'number-of-entries': ( + number_of_entries := YANGLeafMember( + 'number-of-entries', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-allowed': ( + is_allowed := YANGLeafMember( + 'is-allowed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + ConnectivityMatricesMeta. + LabelRestrictions. + yang_container_descriptor())), + + 'optimizations': ( + optimizations := ( # YANGContainerMember( + ConnectivityMatricesMeta. + Optimizations. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + ConnectivityMatricesMeta. + Underlay. + yang_container_descriptor())), + + 'path-properties': ( + path_properties := ( # YANGContainerMember( + ConnectivityMatricesMeta. + PathProperties. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + ConnectivityMatricesMeta. + PathConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'connectivity-matrix': ( + connectivity_matrix := ( # YANGListMember( + ConnectivityMatricesMeta. + ConnectivityMatrix. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityMatrices': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..caf8d26a9e2be21ed0d3b862f36049fb6a191df9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/__init__.py @@ -0,0 +1,144 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ConnectivityMatrixMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: connectivity-matrix + """ + from .to import To + from .path_properties import PathProperties + from .underlay import Underlay + from .path_constraints import PathConstraints + from .from import From + from .optimizations import Optimizations + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: connectivity-matrix + """ + + def __init__(self): + super().__init__(ConnectivityMatrix) + + def __get__(self, instance, owner=None) -> ( + 'ConnectivityMatrixMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['ConnectivityMatrix']: + pass + + def __iter__(self, key) -> Iterator['ConnectivityMatrix']: + return super().__iter__() + + def __getitem__(self, key) -> 'ConnectivityMatrix': + return super()[key] + + def __enter__(self) -> ( + 'ConnectivityMatrixMeta.yang_list_descriptor'): + pass + + +class ConnectivityMatrix( + YANGListItem, + metaclass=ConnectivityMatrixMeta): + """ + YANG list item handler. + + YANG name: connectivity-matrix + """ + + _yang_name: Final[str] = 'connectivity-matrix' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'id': ( + id := YANGLeafMember( + 'id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-allowed': ( + is_allowed := YANGLeafMember( + 'is-allowed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'to': ( + to := ( # YANGContainerMember( + ConnectivityMatrixMeta. + To. + yang_container_descriptor())), + + 'path-properties': ( + path_properties := ( # YANGContainerMember( + ConnectivityMatrixMeta. + PathProperties. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + ConnectivityMatrixMeta. + Underlay. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + ConnectivityMatrixMeta. + PathConstraints. + yang_container_descriptor())), + + 'from': ( + from := ( # YANGContainerMember( + ConnectivityMatrixMeta. + From. + yang_container_descriptor())), + + 'optimizations': ( + optimizations := ( # YANGContainerMember( + ConnectivityMatrixMeta. + Optimizations. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ConnectivityMatrix': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..14cbae7304f9e1b80e18a1547974269f00b66621 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class FromMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: from + """ + from .label_restrictions import LabelRestrictions + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: from + """ + + def __init__(self): + super().__init__(From) + + def __get__(self, instance, owner=None) -> ( + 'FromMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'From': + pass + + def __enter__(self) -> 'From': + pass + + +class From( + YANGContainer, + metaclass=FromMeta): + """ + YANG container handler. + + YANG name: from + """ + + _yang_name: Final[str] = 'from' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tp-ref': ( + tp_ref := YANGLeafMember( + 'tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + FromMeta. + LabelRestrictions. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'From': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..90d6fbfa8ef329a23ca16908801c5dfc1c509b01 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_end import LabelEnd + from .label_step import LabelStep + from .label_start import LabelStart + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/from/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c8d4f4c8def0e90dabe399cc305dc3b8d3d500 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: optimizations + """ + from .algorithm import Algorithm + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: optimizations + """ + + def __init__(self): + super().__init__(Optimizations) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Optimizations': + pass + + def __enter__(self) -> 'Optimizations': + pass + + +class Optimizations( + YANGContainer, + metaclass=OptimizationsMeta): + """ + YANG container handler. + + YANG name: optimizations + """ + + _yang_name: Final[str] = 'optimizations' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Optimizations': + instance = super().__new__(cls) + instance._yang_choices = { + + 'algorithm': + OptimizationsMeta.Algorithm( + instance), + } + return instance + + @property + def algorithm(self) -> ( + OptimizationsMeta.Algorithm): + return self._yang_choices['algorithm'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d82c7bf9c5ec990484589d660738ffe3d2d9f6bf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AlgorithmMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: algorithm + """ + + from .metric import Metric + from .objective_function import ObjectiveFunction + + class metric_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.Metric) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.metric_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + class objective_function_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.objective_function_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + +class Algorithm(YANGChoice, metaclass=AlgorithmMeta): + """ + YANG choice handler. + + YANG name: algorithm + """ + + _yang_name: Final[str] = 'algorithm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'metric': ( + metric := ( # YANGChoiceCase( + AlgorithmMeta. + metric_case_descriptor())), + + 'objective-function': ( + objective_function := ( # YANGChoiceCase( + AlgorithmMeta. + objective_function_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e7d1da8ee3719d0d6a3c401df7340fbd3517e8ed --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric + """ + from .tiebreakers import Tiebreakers + from .optimization_metric import OptimizationMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__(Metric) + + def __get__(self, instance, owner=None) -> ( + 'MetricMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Metric': + pass + + def __enter__(self) -> 'Metric': + pass + + +class Metric( + YANGContainer, + metaclass=MetricMeta): + """ + YANG container handler. + + YANG name: metric + """ + + _yang_name: Final[str] = 'metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tiebreakers': ( + tiebreakers := ( # YANGContainerMember( + MetricMeta. + Tiebreakers. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'optimization-metric': ( + optimization_metric := ( # YANGListMember( + MetricMeta. + OptimizationMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Metric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bad2331fc0f109b98bda93287a822244302b5d1e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: optimization-metric + """ + from .explicit_route_exclude_objects import ExplicitRouteExcludeObjects + from .explicit_route_include_objects import ExplicitRouteIncludeObjects + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: optimization-metric + """ + + def __init__(self): + super().__init__(OptimizationMetric) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['OptimizationMetric']: + pass + + def __iter__(self, key) -> Iterator['OptimizationMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'OptimizationMetric': + return super()[key] + + def __enter__(self) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + pass + + +class OptimizationMetric( + YANGListItem, + metaclass=OptimizationMetricMeta): + """ + YANG list item handler. + + YANG name: optimization-metric + """ + + _yang_name: Final[str] = 'optimization-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'weight': ( + weight := YANGLeafMember( + 'weight', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'explicit-route-exclude-objects': ( + explicit_route_exclude_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteExcludeObjects. + yang_container_descriptor())), + + 'explicit-route-include-objects': ( + explicit_route_include_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteIncludeObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OptimizationMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aea7bdd4cd5ed1743a1764899878a1ac8035348e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteExcludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + from .route_object_exclude_object import RouteObjectExcludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-exclude-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteExcludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteExcludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteExcludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteExcludeObjects': + pass + + +class ExplicitRouteExcludeObjects( + YANGContainer, + metaclass=ExplicitRouteExcludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + + _yang_name: Final[str] = 'explicit-route-exclude-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-exclude-object': ( + route_object_exclude_object := ( # YANGListMember( + ExplicitRouteExcludeObjectsMeta. + RouteObjectExcludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteExcludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..405906d3e6d9dd1eda79aae3a6302c37e0e24988 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectExcludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-exclude-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-exclude-object + """ + + def __init__(self): + super().__init__(RouteObjectExcludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectExcludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectExcludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectExcludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectExcludeObject( + YANGListItem, + metaclass=RouteObjectExcludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-exclude-object + """ + + _yang_name: Final[str] = 'route-object-exclude-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectExcludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectExcludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectExcludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8100bae93730074ddc472dfb8328dc9ec9b34a21 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py @@ -0,0 +1,217 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .srlg import Srlg + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class srlg_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__( + TypeMeta.Srlg) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.srlg_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Srlg'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Srlg'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'srlg': ( + srlg := ( # YANGChoiceCase( + TypeMeta. + srlg_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d9d3d58559fab79fa12a634fb4aecbef61780f1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..420f996a13a20bf122ec87f0fbb109b34246eb61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + from .srlg import Srlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'srlg': ( + srlg := ( # YANGContainerMember( + SrlgMeta. + Srlg. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95a1628e4caf545e0d31823f89ea93178ffb76c7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'srlg': ( + srlg := YANGLeafMember( + 'srlg', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7de25b7bbfed705b63d9c681cad27d7bd9b9584d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3209b99bad73493077e9e91a8053f320b05c11c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteIncludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-include-objects + """ + from .route_object_include_object import RouteObjectIncludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-include-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteIncludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteIncludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteIncludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteIncludeObjects': + pass + + +class ExplicitRouteIncludeObjects( + YANGContainer, + metaclass=ExplicitRouteIncludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-include-objects + """ + + _yang_name: Final[str] = 'explicit-route-include-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-include-object': ( + route_object_include_object := ( # YANGListMember( + ExplicitRouteIncludeObjectsMeta. + RouteObjectIncludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteIncludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c9f24330ff35e20e47be0db730f6ec682dd71d2d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectIncludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-include-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-include-object + """ + + def __init__(self): + super().__init__(RouteObjectIncludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectIncludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectIncludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectIncludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectIncludeObject( + YANGListItem, + metaclass=RouteObjectIncludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-include-object + """ + + _yang_name: Final[str] = 'route-object-include-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectIncludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectIncludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectIncludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5f251c42ed301ea688e4e921968867ed262acfa2 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .label import Label + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..64a8ec6d5e2fd4a77c59c13b3e37cacb001c91fe --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7de25b7bbfed705b63d9c681cad27d7bd9b9584d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d345b57b342afaa50a04c5782794f34b810b795c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakersMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tiebreakers + """ + from .tiebreaker import Tiebreaker + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tiebreakers + """ + + def __init__(self): + super().__init__(Tiebreakers) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakersMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tiebreakers': + pass + + def __enter__(self) -> 'Tiebreakers': + pass + + +class Tiebreakers( + YANGContainer, + metaclass=TiebreakersMeta): + """ + YANG container handler. + + YANG name: tiebreakers + """ + + _yang_name: Final[str] = 'tiebreakers' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tiebreaker': ( + tiebreaker := ( # YANGListMember( + TiebreakersMeta. + Tiebreaker. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreakers': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..500d880ad6ad48b8079aa3bea0b1e644f7008f49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakerMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tiebreaker + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tiebreaker + """ + + def __init__(self): + super().__init__(Tiebreaker) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tiebreaker']: + pass + + def __iter__(self, key) -> Iterator['Tiebreaker']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tiebreaker': + return super()[key] + + def __enter__(self) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + pass + + +class Tiebreaker( + YANGListItem, + metaclass=TiebreakerMeta): + """ + YANG list item handler. + + YANG name: tiebreaker + """ + + _yang_name: Final[str] = 'tiebreaker' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tiebreaker-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tiebreaker-type': ( + tiebreaker_type := YANGLeafMember( + 'tiebreaker-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreaker': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd32a2bb98c6e47f795103fbc122cbf7957e1e6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + from .objective_function import ObjectiveFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'objective-function': ( + objective_function := ( # YANGContainerMember( + ObjectiveFunctionMeta. + ObjectiveFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af72bcf2702ccee1d360bad39000241d1abfdc19 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/optimizations/algorithm/objective_function/objective_function/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'objective-function-type': ( + objective_function_type := YANGLeafMember( + 'objective-function-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6f5aceab23841faec8396e85e86e21692641125f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/__init__.py @@ -0,0 +1,151 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + from .path_metric_bounds import PathMetricBounds + from .path_affinities_values import PathAffinitiesValues + from .path_srlgs_lists import PathSrlgsLists + from .path_srlgs_names import PathSrlgsNames + from .path_affinity_names import PathAffinityNames + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection': ( + link_protection := YANGLeafMember( + 'link-protection', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'signaling-type': ( + signaling_type := YANGLeafMember( + 'signaling-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hold-priority': ( + hold_priority := YANGLeafMember( + 'hold-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'setup-priority': ( + setup_priority := YANGLeafMember( + 'setup-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-metric-bounds': ( + path_metric_bounds := ( # YANGContainerMember( + PathConstraintsMeta. + PathMetricBounds. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + PathConstraintsMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..356f7761b99b2e313b0638407dbaaa3996e6c418 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-metric-bounds + """ + from .path_metric_bound import PathMetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-metric-bounds + """ + + def __init__(self): + super().__init__(PathMetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathMetricBounds': + pass + + def __enter__(self) -> 'PathMetricBounds': + pass + + +class PathMetricBounds( + YANGContainer, + metaclass=PathMetricBoundsMeta): + """ + YANG container handler. + + YANG name: path-metric-bounds + """ + + _yang_name: Final[str] = 'path-metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric-bound': ( + path_metric_bound := ( # YANGListMember( + PathMetricBoundsMeta. + PathMetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/path_metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/path_metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2a97d5e3e1d7066756b051d139f997d9a46b3c6b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_metric_bounds/path_metric_bound/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric-bound + """ + + def __init__(self): + super().__init__(PathMetricBound) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetricBound']: + pass + + def __iter__(self, key) -> Iterator['PathMetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetricBound': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + pass + + +class PathMetricBound( + YANGListItem, + metaclass=PathMetricBoundMeta): + """ + YANG list item handler. + + YANG name: path-metric-bound + """ + + _yang_name: Final[str] = 'path-metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'upper-bound': ( + upper_bound := YANGLeafMember( + 'upper-bound', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_constraints/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..df295258db86b4261becc2471833afaabe8421be --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathPropertiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-properties + """ + from .path_affinities_values import PathAffinitiesValues + from .path_srlgs_names import PathSrlgsNames + from .path_route_objects import PathRouteObjects + from .path_srlgs_lists import PathSrlgsLists + from .path_affinity_names import PathAffinityNames + from .path_metric import PathMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-properties + """ + + def __init__(self): + super().__init__(PathProperties) + + def __get__(self, instance, owner=None) -> ( + 'PathPropertiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathProperties': + pass + + def __enter__(self) -> 'PathProperties': + pass + + +class PathProperties( + YANGContainer, + metaclass=PathPropertiesMeta): + """ + YANG container handler. + + YANG name: path-properties + """ + + _yang_name: Final[str] = 'path-properties' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-route-objects': ( + path_route_objects := ( # YANGContainerMember( + PathPropertiesMeta. + PathRouteObjects. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinityNames. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric': ( + path_metric := ( # YANGListMember( + PathPropertiesMeta. + PathMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathProperties': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e4a21b11accc2103aa85169cb46c386658d5cc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d6ae074074e7913854992f9bd32a8f51f6b9d7b7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_metric/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric + """ + + def __init__(self): + super().__init__(PathMetric) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetric']: + pass + + def __iter__(self, key) -> Iterator['PathMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetric': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricMeta.yang_list_descriptor'): + pass + + +class PathMetric( + YANGListItem, + metaclass=PathMetricMeta): + """ + YANG list item handler. + + YANG name: path-metric + """ + + _yang_name: Final[str] = 'path-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'accumulative-value': ( + accumulative_value := YANGLeafMember( + 'accumulative-value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2af8eb3f47d7b0ceb2d21f9f5b1ee44b432ab35f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-route-objects + """ + from .path_route_object import PathRouteObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-route-objects + """ + + def __init__(self): + super().__init__(PathRouteObjects) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathRouteObjects': + pass + + def __enter__(self) -> 'PathRouteObjects': + pass + + +class PathRouteObjects( + YANGContainer, + metaclass=PathRouteObjectsMeta): + """ + YANG container handler. + + YANG name: path-route-objects + """ + + _yang_name: Final[str] = 'path-route-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-route-object': ( + path_route_object := ( # YANGListMember( + PathRouteObjectsMeta. + PathRouteObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74b9e21c769902d7a2bb1f362d2e95cbf5d862cd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-route-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-route-object + """ + + def __init__(self): + super().__init__(PathRouteObject) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathRouteObject']: + pass + + def __iter__(self, key) -> Iterator['PathRouteObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathRouteObject': + return super()[key] + + def __enter__(self) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + pass + + +class PathRouteObject( + YANGListItem, + metaclass=PathRouteObjectMeta): + """ + YANG list item handler. + + YANG name: path-route-object + """ + + _yang_name: Final[str] = 'path-route-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathRouteObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathRouteObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..28ea603a0e4ee2c731661a01ab1dbbee36529de5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..652da89e61bd32067e97591a11a2970e965bed4a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/path_properties/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d03118f5c94e3726341c4332447847c61623d616 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ToMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: to + """ + from .label_restrictions import LabelRestrictions + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: to + """ + + def __init__(self): + super().__init__(To) + + def __get__(self, instance, owner=None) -> ( + 'ToMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'To': + pass + + def __enter__(self) -> 'To': + pass + + +class To( + YANGContainer, + metaclass=ToMeta): + """ + YANG container handler. + + YANG name: to + """ + + _yang_name: Final[str] = 'to' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tp-ref': ( + tp_ref := YANGLeafMember( + 'tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + ToMeta. + LabelRestrictions. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'To': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d6963852ba0c84a4b78122f6ad1185f29748eb5f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_start import LabelStart + from .label_step import LabelStep + from .label_end import LabelEnd + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/to/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ac722c47add5d381fef94d2c3a2f5750b49a2688 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .tunnels import Tunnels + from .tunnel_termination_points import TunnelTerminationPoints + from .primary_path import PrimaryPath + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6b6e1ff5cb9da5f8c265df0f8c0854de089ff9ef --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..39f656215584aa2bcf14b3ba1a003b8347ff4977 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + from .label import Label + from .numbered_node_hop import NumberedNodeHop + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..17a8ab32f6e4e90649c07d42b9433c6639fb2934 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e01f01986b3d51fd6143967c4f05b169aff11129 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..652da89e61bd32067e97591a11a2970e965bed4a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8ae8cc268f3c4fc331cd1e1018be41d113da9183 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f854dfd329ce016317b7b9743ace874769f03094 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/connectivity_matrix/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..832dd2f7ef2d442bd2e0efe6ad680c3d4fd15402 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_end import LabelEnd + from .label_start import LabelStart + from .label_step import LabelStep + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c8d4f4c8def0e90dabe399cc305dc3b8d3d500 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: optimizations + """ + from .algorithm import Algorithm + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: optimizations + """ + + def __init__(self): + super().__init__(Optimizations) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Optimizations': + pass + + def __enter__(self) -> 'Optimizations': + pass + + +class Optimizations( + YANGContainer, + metaclass=OptimizationsMeta): + """ + YANG container handler. + + YANG name: optimizations + """ + + _yang_name: Final[str] = 'optimizations' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Optimizations': + instance = super().__new__(cls) + instance._yang_choices = { + + 'algorithm': + OptimizationsMeta.Algorithm( + instance), + } + return instance + + @property + def algorithm(self) -> ( + OptimizationsMeta.Algorithm): + return self._yang_choices['algorithm'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d82c7bf9c5ec990484589d660738ffe3d2d9f6bf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AlgorithmMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: algorithm + """ + + from .metric import Metric + from .objective_function import ObjectiveFunction + + class metric_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.Metric) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.metric_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + class objective_function_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.objective_function_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + +class Algorithm(YANGChoice, metaclass=AlgorithmMeta): + """ + YANG choice handler. + + YANG name: algorithm + """ + + _yang_name: Final[str] = 'algorithm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'metric': ( + metric := ( # YANGChoiceCase( + AlgorithmMeta. + metric_case_descriptor())), + + 'objective-function': ( + objective_function := ( # YANGChoiceCase( + AlgorithmMeta. + objective_function_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e7d1da8ee3719d0d6a3c401df7340fbd3517e8ed --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric + """ + from .tiebreakers import Tiebreakers + from .optimization_metric import OptimizationMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__(Metric) + + def __get__(self, instance, owner=None) -> ( + 'MetricMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Metric': + pass + + def __enter__(self) -> 'Metric': + pass + + +class Metric( + YANGContainer, + metaclass=MetricMeta): + """ + YANG container handler. + + YANG name: metric + """ + + _yang_name: Final[str] = 'metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tiebreakers': ( + tiebreakers := ( # YANGContainerMember( + MetricMeta. + Tiebreakers. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'optimization-metric': ( + optimization_metric := ( # YANGListMember( + MetricMeta. + OptimizationMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Metric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e5e69ea24d5d4bc36b6bf78a13fb98a25a1e5916 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: optimization-metric + """ + from .explicit_route_exclude_objects import ExplicitRouteExcludeObjects + from .explicit_route_include_objects import ExplicitRouteIncludeObjects + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: optimization-metric + """ + + def __init__(self): + super().__init__(OptimizationMetric) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['OptimizationMetric']: + pass + + def __iter__(self, key) -> Iterator['OptimizationMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'OptimizationMetric': + return super()[key] + + def __enter__(self) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + pass + + +class OptimizationMetric( + YANGListItem, + metaclass=OptimizationMetricMeta): + """ + YANG list item handler. + + YANG name: optimization-metric + """ + + _yang_name: Final[str] = 'optimization-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'weight': ( + weight := YANGLeafMember( + 'weight', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'explicit-route-exclude-objects': ( + explicit_route_exclude_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteExcludeObjects. + yang_container_descriptor())), + + 'explicit-route-include-objects': ( + explicit_route_include_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteIncludeObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OptimizationMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aea7bdd4cd5ed1743a1764899878a1ac8035348e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteExcludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + from .route_object_exclude_object import RouteObjectExcludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-exclude-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteExcludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteExcludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteExcludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteExcludeObjects': + pass + + +class ExplicitRouteExcludeObjects( + YANGContainer, + metaclass=ExplicitRouteExcludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + + _yang_name: Final[str] = 'explicit-route-exclude-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-exclude-object': ( + route_object_exclude_object := ( # YANGListMember( + ExplicitRouteExcludeObjectsMeta. + RouteObjectExcludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteExcludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..405906d3e6d9dd1eda79aae3a6302c37e0e24988 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectExcludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-exclude-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-exclude-object + """ + + def __init__(self): + super().__init__(RouteObjectExcludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectExcludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectExcludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectExcludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectExcludeObject( + YANGListItem, + metaclass=RouteObjectExcludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-exclude-object + """ + + _yang_name: Final[str] = 'route-object-exclude-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectExcludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectExcludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectExcludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..519535f45f22cf80d11d26ecfff5511b21632ae4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py @@ -0,0 +1,217 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .srlg import Srlg + from .label import Label + from .unnumbered_link_hop import UnnumberedLinkHop + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class srlg_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__( + TypeMeta.Srlg) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.srlg_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Srlg'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Srlg'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'srlg': ( + srlg := ( # YANGChoiceCase( + TypeMeta. + srlg_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..420f996a13a20bf122ec87f0fbb109b34246eb61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + from .srlg import Srlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'srlg': ( + srlg := ( # YANGContainerMember( + SrlgMeta. + Srlg. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95a1628e4caf545e0d31823f89ea93178ffb76c7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'srlg': ( + srlg := YANGLeafMember( + 'srlg', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cdc24c09f1b3ccadebb91f2dbb9442bbfbd3595d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3209b99bad73493077e9e91a8053f320b05c11c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteIncludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-include-objects + """ + from .route_object_include_object import RouteObjectIncludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-include-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteIncludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteIncludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteIncludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteIncludeObjects': + pass + + +class ExplicitRouteIncludeObjects( + YANGContainer, + metaclass=ExplicitRouteIncludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-include-objects + """ + + _yang_name: Final[str] = 'explicit-route-include-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-include-object': ( + route_object_include_object := ( # YANGListMember( + ExplicitRouteIncludeObjectsMeta. + RouteObjectIncludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteIncludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c9f24330ff35e20e47be0db730f6ec682dd71d2d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectIncludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-include-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-include-object + """ + + def __init__(self): + super().__init__(RouteObjectIncludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectIncludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectIncludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectIncludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectIncludeObject( + YANGListItem, + metaclass=RouteObjectIncludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-include-object + """ + + _yang_name: Final[str] = 'route-object-include-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectIncludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectIncludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectIncludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0fc658253392d53b5678ebb702dd6ecb3cee4165 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + from .label import Label + from .unnumbered_link_hop import UnnumberedLinkHop + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5baa996de0fff24876e40ec73f87a7a90da1f2ea --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d345b57b342afaa50a04c5782794f34b810b795c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakersMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tiebreakers + """ + from .tiebreaker import Tiebreaker + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tiebreakers + """ + + def __init__(self): + super().__init__(Tiebreakers) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakersMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tiebreakers': + pass + + def __enter__(self) -> 'Tiebreakers': + pass + + +class Tiebreakers( + YANGContainer, + metaclass=TiebreakersMeta): + """ + YANG container handler. + + YANG name: tiebreakers + """ + + _yang_name: Final[str] = 'tiebreakers' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tiebreaker': ( + tiebreaker := ( # YANGListMember( + TiebreakersMeta. + Tiebreaker. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreakers': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..500d880ad6ad48b8079aa3bea0b1e644f7008f49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakerMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tiebreaker + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tiebreaker + """ + + def __init__(self): + super().__init__(Tiebreaker) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tiebreaker']: + pass + + def __iter__(self, key) -> Iterator['Tiebreaker']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tiebreaker': + return super()[key] + + def __enter__(self) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + pass + + +class Tiebreaker( + YANGListItem, + metaclass=TiebreakerMeta): + """ + YANG list item handler. + + YANG name: tiebreaker + """ + + _yang_name: Final[str] = 'tiebreaker' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tiebreaker-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tiebreaker-type': ( + tiebreaker_type := YANGLeafMember( + 'tiebreaker-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreaker': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd32a2bb98c6e47f795103fbc122cbf7957e1e6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/objective_function/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + from .objective_function import ObjectiveFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'objective-function': ( + objective_function := ( # YANGContainerMember( + ObjectiveFunctionMeta. + ObjectiveFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/objective_function/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/objective_function/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af72bcf2702ccee1d360bad39000241d1abfdc19 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/optimizations/algorithm/objective_function/objective_function/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'objective-function-type': ( + objective_function_type := YANGLeafMember( + 'objective-function-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..28191362a8a0f4d9e8af895e993672214dc2b00f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/__init__.py @@ -0,0 +1,151 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + from .path_metric_bounds import PathMetricBounds + from .path_affinity_names import PathAffinityNames + from .path_srlgs_lists import PathSrlgsLists + from .path_srlgs_names import PathSrlgsNames + from .te_bandwidth import TeBandwidth + from .path_affinities_values import PathAffinitiesValues + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'setup-priority': ( + setup_priority := YANGLeafMember( + 'setup-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'signaling-type': ( + signaling_type := YANGLeafMember( + 'signaling-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hold-priority': ( + hold_priority := YANGLeafMember( + 'hold-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection': ( + link_protection := YANGLeafMember( + 'link-protection', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-metric-bounds': ( + path_metric_bounds := ( # YANGContainerMember( + PathConstraintsMeta. + PathMetricBounds. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + PathConstraintsMeta. + TeBandwidth. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinitiesValues. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..356f7761b99b2e313b0638407dbaaa3996e6c418 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-metric-bounds + """ + from .path_metric_bound import PathMetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-metric-bounds + """ + + def __init__(self): + super().__init__(PathMetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathMetricBounds': + pass + + def __enter__(self) -> 'PathMetricBounds': + pass + + +class PathMetricBounds( + YANGContainer, + metaclass=PathMetricBoundsMeta): + """ + YANG container handler. + + YANG name: path-metric-bounds + """ + + _yang_name: Final[str] = 'path-metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric-bound': ( + path_metric_bound := ( # YANGListMember( + PathMetricBoundsMeta. + PathMetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_metric_bounds/path_metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_metric_bounds/path_metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2a97d5e3e1d7066756b051d139f997d9a46b3c6b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_metric_bounds/path_metric_bound/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric-bound + """ + + def __init__(self): + super().__init__(PathMetricBound) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetricBound']: + pass + + def __iter__(self, key) -> Iterator['PathMetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetricBound': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + pass + + +class PathMetricBound( + YANGListItem, + metaclass=PathMetricBoundMeta): + """ + YANG list item handler. + + YANG name: path-metric-bound + """ + + _yang_name: Final[str] = 'path-metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'upper-bound': ( + upper_bound := YANGLeafMember( + 'upper-bound', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_constraints/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..149786798cff216d2d5c3159b457969263950a72 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathPropertiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-properties + """ + from .path_affinities_values import PathAffinitiesValues + from .path_route_objects import PathRouteObjects + from .path_srlgs_lists import PathSrlgsLists + from .path_affinity_names import PathAffinityNames + from .path_srlgs_names import PathSrlgsNames + from .path_metric import PathMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-properties + """ + + def __init__(self): + super().__init__(PathProperties) + + def __get__(self, instance, owner=None) -> ( + 'PathPropertiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathProperties': + pass + + def __enter__(self) -> 'PathProperties': + pass + + +class PathProperties( + YANGContainer, + metaclass=PathPropertiesMeta): + """ + YANG container handler. + + YANG name: path-properties + """ + + _yang_name: Final[str] = 'path-properties' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-route-objects': ( + path_route_objects := ( # YANGContainerMember( + PathPropertiesMeta. + PathRouteObjects. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsNames. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric': ( + path_metric := ( # YANGListMember( + PathPropertiesMeta. + PathMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathProperties': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e4a21b11accc2103aa85169cb46c386658d5cc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7645abedd4d25aeb9c77aa579c2972a450d00a6e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_metric/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric + """ + + def __init__(self): + super().__init__(PathMetric) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetric']: + pass + + def __iter__(self, key) -> Iterator['PathMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetric': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricMeta.yang_list_descriptor'): + pass + + +class PathMetric( + YANGListItem, + metaclass=PathMetricMeta): + """ + YANG list item handler. + + YANG name: path-metric + """ + + _yang_name: Final[str] = 'path-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'accumulative-value': ( + accumulative_value := YANGLeafMember( + 'accumulative-value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2af8eb3f47d7b0ceb2d21f9f5b1ee44b432ab35f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-route-objects + """ + from .path_route_object import PathRouteObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-route-objects + """ + + def __init__(self): + super().__init__(PathRouteObjects) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathRouteObjects': + pass + + def __enter__(self) -> 'PathRouteObjects': + pass + + +class PathRouteObjects( + YANGContainer, + metaclass=PathRouteObjectsMeta): + """ + YANG container handler. + + YANG name: path-route-objects + """ + + _yang_name: Final[str] = 'path-route-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-route-object': ( + path_route_object := ( # YANGListMember( + PathRouteObjectsMeta. + PathRouteObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74b9e21c769902d7a2bb1f362d2e95cbf5d862cd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-route-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-route-object + """ + + def __init__(self): + super().__init__(PathRouteObject) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathRouteObject']: + pass + + def __iter__(self, key) -> Iterator['PathRouteObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathRouteObject': + return super()[key] + + def __enter__(self) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + pass + + +class PathRouteObject( + YANGListItem, + metaclass=PathRouteObjectMeta): + """ + YANG list item handler. + + YANG name: path-route-object + """ + + _yang_name: Final[str] = 'path-route-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathRouteObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathRouteObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5f251c42ed301ea688e4e921968867ed262acfa2 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + from .label import Label + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..07c0b7b779289a6ac9a9123fd540526dc6d190fb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/path_properties/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9ef388cd63aa7c8947fc3391bad703bb01f3d827 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .primary_path import PrimaryPath + from .tunnel_termination_points import TunnelTerminationPoints + from .tunnels import Tunnels + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6b6e1ff5cb9da5f8c265df0f8c0854de089ff9ef --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e16cb666ce1a7bc800b744b15e11b1d4b7279e6d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .as_number import AsNumber + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6c1142926ba50c34d71606b198e801811b621385 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c00e57c237e53df3a2bba30cffe83a15d1149756 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8ee74a2b7c7f647d2a88dfb22f44ed0ec1e80e4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8ae8cc268f3c4fc331cd1e1018be41d113da9183 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d36aa35acd17db473e177b143afdec573f0b4927 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/connectivity_matrices/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/underlay_topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/underlay_topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42dee7a72fe4a5d79128cf6ad278af68094e6692 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/te_node_attributes/underlay_topology/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayTopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay-topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay-topology + """ + + def __init__(self): + super().__init__(UnderlayTopology) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayTopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnderlayTopology': + pass + + def __enter__(self) -> 'UnderlayTopology': + pass + + +class UnderlayTopology( + YANGContainer, + metaclass=UnderlayTopologyMeta): + """ + YANG container handler. + + YANG name: underlay-topology + """ + + _yang_name: Final[str] = 'underlay-topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnderlayTopology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3a2840f2560d9dcbb55f2d1dcd7515046766223b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/__init__.py @@ -0,0 +1,167 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel-termination-point + """ + from .client_layer_adaptation import ClientLayerAdaptation + from .statistics import Statistics + from .local_link_connectivities import LocalLinkConnectivities + from .geolocation import Geolocation + from .supporting_tunnel_termination_point import SupportingTunnelTerminationPoint + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel-termination-point + """ + + def __init__(self): + super().__init__(TunnelTerminationPoint) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['TunnelTerminationPoint']: + pass + + def __iter__(self, key) -> Iterator['TunnelTerminationPoint']: + return super().__iter__() + + def __getitem__(self, key) -> 'TunnelTerminationPoint': + return super()[key] + + def __enter__(self) -> ( + 'TunnelTerminationPointMeta.yang_list_descriptor'): + pass + + +class TunnelTerminationPoint( + YANGListItem, + metaclass=TunnelTerminationPointMeta): + """ + YANG list item handler. + + YANG name: tunnel-termination-point + """ + + _yang_name: Final[str] = 'tunnel-termination-point' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-tp-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'admin-status': ( + admin_status := YANGLeafMember( + 'admin-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tunnel-tp-id': ( + tunnel_tp_id := YANGLeafMember( + 'tunnel-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'encoding': ( + encoding := YANGLeafMember( + 'encoding', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'switching-capability': ( + switching_capability := YANGLeafMember( + 'switching-capability', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'oper-status': ( + oper_status := YANGLeafMember( + 'oper-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'client-layer-adaptation': ( + client_layer_adaptation := ( # YANGContainerMember( + TunnelTerminationPointMeta. + ClientLayerAdaptation. + yang_container_descriptor())), + + 'statistics': ( + statistics := ( # YANGContainerMember( + TunnelTerminationPointMeta. + Statistics. + yang_container_descriptor())), + + 'local-link-connectivities': ( + local_link_connectivities := ( # YANGContainerMember( + TunnelTerminationPointMeta. + LocalLinkConnectivities. + yang_container_descriptor())), + + 'geolocation': ( + geolocation := ( # YANGContainerMember( + TunnelTerminationPointMeta. + Geolocation. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'supporting-tunnel-termination-point': ( + supporting_tunnel_termination_point := ( # YANGListMember( + TunnelTerminationPointMeta. + SupportingTunnelTerminationPoint. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoint': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38f9ec314a9426a5fe03975be29a2e28b422a31e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ClientLayerAdaptationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: client-layer-adaptation + """ + from .switching_capability import SwitchingCapability + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: client-layer-adaptation + """ + + def __init__(self): + super().__init__(ClientLayerAdaptation) + + def __get__(self, instance, owner=None) -> ( + 'ClientLayerAdaptationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ClientLayerAdaptation': + pass + + def __enter__(self) -> 'ClientLayerAdaptation': + pass + + +class ClientLayerAdaptation( + YANGContainer, + metaclass=ClientLayerAdaptationMeta): + """ + YANG container handler. + + YANG name: client-layer-adaptation + """ + + _yang_name: Final[str] = 'client-layer-adaptation' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'switching-capability': ( + switching_capability := ( # YANGListMember( + ClientLayerAdaptationMeta. + SwitchingCapability. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ClientLayerAdaptation': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74c496e9c8505568c18ca8db338e3c313884945d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SwitchingCapabilityMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: switching-capability + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: switching-capability + """ + + def __init__(self): + super().__init__(SwitchingCapability) + + def __get__(self, instance, owner=None) -> ( + 'SwitchingCapabilityMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SwitchingCapability']: + pass + + def __iter__(self, key) -> Iterator['SwitchingCapability']: + return super().__iter__() + + def __getitem__(self, key) -> 'SwitchingCapability': + return super()[key] + + def __enter__(self) -> ( + 'SwitchingCapabilityMeta.yang_list_descriptor'): + pass + + +class SwitchingCapability( + YANGListItem, + metaclass=SwitchingCapabilityMeta): + """ + YANG list item handler. + + YANG name: switching-capability + """ + + _yang_name: Final[str] = 'switching-capability' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'switching-capability', + 'encoding', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'switching-capability': ( + switching_capability := YANGLeafMember( + 'switching-capability', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'encoding': ( + encoding := YANGLeafMember( + 'encoding', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + SwitchingCapabilityMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SwitchingCapability': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/client_layer_adaptation/switching_capability/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/geolocation/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/geolocation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e58eb1516669a36eac9abd5451d7335da8de62a4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/geolocation/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GeolocationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: geolocation + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: geolocation + """ + + def __init__(self): + super().__init__(Geolocation) + + def __get__(self, instance, owner=None) -> ( + 'GeolocationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Geolocation': + pass + + def __enter__(self) -> 'Geolocation': + pass + + +class Geolocation( + YANGContainer, + metaclass=GeolocationMeta): + """ + YANG container handler. + + YANG name: geolocation + """ + + _yang_name: Final[str] = 'geolocation' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'latitude': ( + latitude := YANGLeafMember( + 'latitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'longitude': ( + longitude := YANGLeafMember( + 'longitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'altitude': ( + altitude := YANGLeafMember( + 'altitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Geolocation': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d107aca7146b13039b609d38c023443bfe120a37 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/__init__.py @@ -0,0 +1,133 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LocalLinkConnectivitiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: local-link-connectivities + """ + from .underlay import Underlay + from .path_constraints import PathConstraints + from .path_properties import PathProperties + from .label_restrictions import LabelRestrictions + from .optimizations import Optimizations + from .local_link_connectivity import LocalLinkConnectivity + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: local-link-connectivities + """ + + def __init__(self): + super().__init__(LocalLinkConnectivities) + + def __get__(self, instance, owner=None) -> ( + 'LocalLinkConnectivitiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LocalLinkConnectivities': + pass + + def __enter__(self) -> 'LocalLinkConnectivities': + pass + + +class LocalLinkConnectivities( + YANGContainer, + metaclass=LocalLinkConnectivitiesMeta): + """ + YANG container handler. + + YANG name: local-link-connectivities + """ + + _yang_name: Final[str] = 'local-link-connectivities' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'is-allowed': ( + is_allowed := YANGLeafMember( + 'is-allowed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'number-of-entries': ( + number_of_entries := YANGLeafMember( + 'number-of-entries', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'underlay': ( + underlay := ( # YANGContainerMember( + LocalLinkConnectivitiesMeta. + Underlay. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + LocalLinkConnectivitiesMeta. + PathConstraints. + yang_container_descriptor())), + + 'path-properties': ( + path_properties := ( # YANGContainerMember( + LocalLinkConnectivitiesMeta. + PathProperties. + yang_container_descriptor())), + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + LocalLinkConnectivitiesMeta. + LabelRestrictions. + yang_container_descriptor())), + + 'optimizations': ( + optimizations := ( # YANGContainerMember( + LocalLinkConnectivitiesMeta. + Optimizations. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'local-link-connectivity': ( + local_link_connectivity := ( # YANGListMember( + LocalLinkConnectivitiesMeta. + LocalLinkConnectivity. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LocalLinkConnectivities': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..814ea59a555c0c31d59f79bd58db695d0fb105e8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_end import LabelEnd + from .label_start import LabelStart + from .label_step import LabelStep + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..89dc7a8809c12f5dc8f942f7719322884fea3b49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/__init__.py @@ -0,0 +1,137 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LocalLinkConnectivityMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: local-link-connectivity + """ + from .underlay import Underlay + from .optimizations import Optimizations + from .label_restrictions import LabelRestrictions + from .path_properties import PathProperties + from .path_constraints import PathConstraints + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: local-link-connectivity + """ + + def __init__(self): + super().__init__(LocalLinkConnectivity) + + def __get__(self, instance, owner=None) -> ( + 'LocalLinkConnectivityMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LocalLinkConnectivity']: + pass + + def __iter__(self, key) -> Iterator['LocalLinkConnectivity']: + return super().__iter__() + + def __getitem__(self, key) -> 'LocalLinkConnectivity': + return super()[key] + + def __enter__(self) -> ( + 'LocalLinkConnectivityMeta.yang_list_descriptor'): + pass + + +class LocalLinkConnectivity( + YANGListItem, + metaclass=LocalLinkConnectivityMeta): + """ + YANG list item handler. + + YANG name: local-link-connectivity + """ + + _yang_name: Final[str] = 'local-link-connectivity' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'link-tp-ref', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-ref': ( + link_tp_ref := YANGLeafMember( + 'link-tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-allowed': ( + is_allowed := YANGLeafMember( + 'is-allowed', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'underlay': ( + underlay := ( # YANGContainerMember( + LocalLinkConnectivityMeta. + Underlay. + yang_container_descriptor())), + + 'optimizations': ( + optimizations := ( # YANGContainerMember( + LocalLinkConnectivityMeta. + Optimizations. + yang_container_descriptor())), + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + LocalLinkConnectivityMeta. + LabelRestrictions. + yang_container_descriptor())), + + 'path-properties': ( + path_properties := ( # YANGContainerMember( + LocalLinkConnectivityMeta. + PathProperties. + yang_container_descriptor())), + + 'path-constraints': ( + path_constraints := ( # YANGContainerMember( + LocalLinkConnectivityMeta. + PathConstraints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LocalLinkConnectivity': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1075ea1483389fe2d8a6245c8b19b16007859ffb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_start import LabelStart + from .label_end import LabelEnd + from .label_step import LabelStep + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c8d4f4c8def0e90dabe399cc305dc3b8d3d500 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: optimizations + """ + from .algorithm import Algorithm + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: optimizations + """ + + def __init__(self): + super().__init__(Optimizations) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Optimizations': + pass + + def __enter__(self) -> 'Optimizations': + pass + + +class Optimizations( + YANGContainer, + metaclass=OptimizationsMeta): + """ + YANG container handler. + + YANG name: optimizations + """ + + _yang_name: Final[str] = 'optimizations' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Optimizations': + instance = super().__new__(cls) + instance._yang_choices = { + + 'algorithm': + OptimizationsMeta.Algorithm( + instance), + } + return instance + + @property + def algorithm(self) -> ( + OptimizationsMeta.Algorithm): + return self._yang_choices['algorithm'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9e0ca52a42ed25af1b7e0612d3e9a6b3d43b6ef9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AlgorithmMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: algorithm + """ + + from .objective_function import ObjectiveFunction + from .metric import Metric + + class objective_function_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.objective_function_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + class metric_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.Metric) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.metric_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + +class Algorithm(YANGChoice, metaclass=AlgorithmMeta): + """ + YANG choice handler. + + YANG name: algorithm + """ + + _yang_name: Final[str] = 'algorithm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'objective-function': ( + objective_function := ( # YANGChoiceCase( + AlgorithmMeta. + objective_function_case_descriptor())), + + 'metric': ( + metric := ( # YANGChoiceCase( + AlgorithmMeta. + metric_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e7d1da8ee3719d0d6a3c401df7340fbd3517e8ed --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric + """ + from .tiebreakers import Tiebreakers + from .optimization_metric import OptimizationMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__(Metric) + + def __get__(self, instance, owner=None) -> ( + 'MetricMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Metric': + pass + + def __enter__(self) -> 'Metric': + pass + + +class Metric( + YANGContainer, + metaclass=MetricMeta): + """ + YANG container handler. + + YANG name: metric + """ + + _yang_name: Final[str] = 'metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tiebreakers': ( + tiebreakers := ( # YANGContainerMember( + MetricMeta. + Tiebreakers. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'optimization-metric': ( + optimization_metric := ( # YANGListMember( + MetricMeta. + OptimizationMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Metric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e5e69ea24d5d4bc36b6bf78a13fb98a25a1e5916 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: optimization-metric + """ + from .explicit_route_exclude_objects import ExplicitRouteExcludeObjects + from .explicit_route_include_objects import ExplicitRouteIncludeObjects + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: optimization-metric + """ + + def __init__(self): + super().__init__(OptimizationMetric) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['OptimizationMetric']: + pass + + def __iter__(self, key) -> Iterator['OptimizationMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'OptimizationMetric': + return super()[key] + + def __enter__(self) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + pass + + +class OptimizationMetric( + YANGListItem, + metaclass=OptimizationMetricMeta): + """ + YANG list item handler. + + YANG name: optimization-metric + """ + + _yang_name: Final[str] = 'optimization-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'weight': ( + weight := YANGLeafMember( + 'weight', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'explicit-route-exclude-objects': ( + explicit_route_exclude_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteExcludeObjects. + yang_container_descriptor())), + + 'explicit-route-include-objects': ( + explicit_route_include_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteIncludeObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OptimizationMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aea7bdd4cd5ed1743a1764899878a1ac8035348e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteExcludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + from .route_object_exclude_object import RouteObjectExcludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-exclude-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteExcludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteExcludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteExcludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteExcludeObjects': + pass + + +class ExplicitRouteExcludeObjects( + YANGContainer, + metaclass=ExplicitRouteExcludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + + _yang_name: Final[str] = 'explicit-route-exclude-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-exclude-object': ( + route_object_exclude_object := ( # YANGListMember( + ExplicitRouteExcludeObjectsMeta. + RouteObjectExcludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteExcludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..405906d3e6d9dd1eda79aae3a6302c37e0e24988 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectExcludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-exclude-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-exclude-object + """ + + def __init__(self): + super().__init__(RouteObjectExcludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectExcludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectExcludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectExcludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectExcludeObject( + YANGListItem, + metaclass=RouteObjectExcludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-exclude-object + """ + + _yang_name: Final[str] = 'route-object-exclude-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectExcludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectExcludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectExcludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d71309cbb007ad744071cd2a2bbacb7964114efc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py @@ -0,0 +1,217 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + from .srlg import Srlg + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class srlg_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__( + TypeMeta.Srlg) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.srlg_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Srlg'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Srlg'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'srlg': ( + srlg := ( # YANGChoiceCase( + TypeMeta. + srlg_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..420f996a13a20bf122ec87f0fbb109b34246eb61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + from .srlg import Srlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'srlg': ( + srlg := ( # YANGContainerMember( + SrlgMeta. + Srlg. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95a1628e4caf545e0d31823f89ea93178ffb76c7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'srlg': ( + srlg := YANGLeafMember( + 'srlg', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..07c0b7b779289a6ac9a9123fd540526dc6d190fb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3209b99bad73493077e9e91a8053f320b05c11c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteIncludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-include-objects + """ + from .route_object_include_object import RouteObjectIncludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-include-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteIncludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteIncludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteIncludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteIncludeObjects': + pass + + +class ExplicitRouteIncludeObjects( + YANGContainer, + metaclass=ExplicitRouteIncludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-include-objects + """ + + _yang_name: Final[str] = 'explicit-route-include-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-include-object': ( + route_object_include_object := ( # YANGListMember( + ExplicitRouteIncludeObjectsMeta. + RouteObjectIncludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteIncludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c9f24330ff35e20e47be0db730f6ec682dd71d2d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectIncludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-include-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-include-object + """ + + def __init__(self): + super().__init__(RouteObjectIncludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectIncludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectIncludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectIncludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectIncludeObject( + YANGListItem, + metaclass=RouteObjectIncludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-include-object + """ + + _yang_name: Final[str] = 'route-object-include-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectIncludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectIncludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectIncludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..97c7b52d53563f340bcf3adef447aa2d718ee50b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d9d3d58559fab79fa12a634fb4aecbef61780f1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..07c0b7b779289a6ac9a9123fd540526dc6d190fb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/tiebreakers/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/tiebreakers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d345b57b342afaa50a04c5782794f34b810b795c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/tiebreakers/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakersMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tiebreakers + """ + from .tiebreaker import Tiebreaker + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tiebreakers + """ + + def __init__(self): + super().__init__(Tiebreakers) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakersMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tiebreakers': + pass + + def __enter__(self) -> 'Tiebreakers': + pass + + +class Tiebreakers( + YANGContainer, + metaclass=TiebreakersMeta): + """ + YANG container handler. + + YANG name: tiebreakers + """ + + _yang_name: Final[str] = 'tiebreakers' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tiebreaker': ( + tiebreaker := ( # YANGListMember( + TiebreakersMeta. + Tiebreaker. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreakers': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..500d880ad6ad48b8079aa3bea0b1e644f7008f49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakerMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tiebreaker + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tiebreaker + """ + + def __init__(self): + super().__init__(Tiebreaker) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tiebreaker']: + pass + + def __iter__(self, key) -> Iterator['Tiebreaker']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tiebreaker': + return super()[key] + + def __enter__(self) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + pass + + +class Tiebreaker( + YANGListItem, + metaclass=TiebreakerMeta): + """ + YANG list item handler. + + YANG name: tiebreaker + """ + + _yang_name: Final[str] = 'tiebreaker' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tiebreaker-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tiebreaker-type': ( + tiebreaker_type := YANGLeafMember( + 'tiebreaker-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreaker': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd32a2bb98c6e47f795103fbc122cbf7957e1e6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/objective_function/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + from .objective_function import ObjectiveFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'objective-function': ( + objective_function := ( # YANGContainerMember( + ObjectiveFunctionMeta. + ObjectiveFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/objective_function/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/objective_function/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af72bcf2702ccee1d360bad39000241d1abfdc19 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/optimizations/algorithm/objective_function/objective_function/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'objective-function-type': ( + objective_function_type := YANGLeafMember( + 'objective-function-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4ffa7b66e87daa14eb143c6501aa376cc779aed5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/__init__.py @@ -0,0 +1,151 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + from .path_srlgs_names import PathSrlgsNames + from .path_affinities_values import PathAffinitiesValues + from .path_srlgs_lists import PathSrlgsLists + from .path_metric_bounds import PathMetricBounds + from .te_bandwidth import TeBandwidth + from .path_affinity_names import PathAffinityNames + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'setup-priority': ( + setup_priority := YANGLeafMember( + 'setup-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection': ( + link_protection := YANGLeafMember( + 'link-protection', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'signaling-type': ( + signaling_type := YANGLeafMember( + 'signaling-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hold-priority': ( + hold_priority := YANGLeafMember( + 'hold-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-metric-bounds': ( + path_metric_bounds := ( # YANGContainerMember( + PathConstraintsMeta. + PathMetricBounds. + yang_container_descriptor())), + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + PathConstraintsMeta. + TeBandwidth. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinityNames. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..356f7761b99b2e313b0638407dbaaa3996e6c418 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-metric-bounds + """ + from .path_metric_bound import PathMetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-metric-bounds + """ + + def __init__(self): + super().__init__(PathMetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathMetricBounds': + pass + + def __enter__(self) -> 'PathMetricBounds': + pass + + +class PathMetricBounds( + YANGContainer, + metaclass=PathMetricBoundsMeta): + """ + YANG container handler. + + YANG name: path-metric-bounds + """ + + _yang_name: Final[str] = 'path-metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric-bound': ( + path_metric_bound := ( # YANGListMember( + PathMetricBoundsMeta. + PathMetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_metric_bounds/path_metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_metric_bounds/path_metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e6e72a44fd364b7d9238cef98eba888090a23f76 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_metric_bounds/path_metric_bound/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric-bound + """ + + def __init__(self): + super().__init__(PathMetricBound) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetricBound']: + pass + + def __iter__(self, key) -> Iterator['PathMetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetricBound': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + pass + + +class PathMetricBound( + YANGListItem, + metaclass=PathMetricBoundMeta): + """ + YANG list item handler. + + YANG name: path-metric-bound + """ + + _yang_name: Final[str] = 'path-metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'upper-bound': ( + upper_bound := YANGLeafMember( + 'upper-bound', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_constraints/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bde8f98e58827b2019a01b80cad4ec0198201e72 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathPropertiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-properties + """ + from .path_srlgs_lists import PathSrlgsLists + from .path_srlgs_names import PathSrlgsNames + from .path_affinities_values import PathAffinitiesValues + from .path_affinity_names import PathAffinityNames + from .path_route_objects import PathRouteObjects + from .path_metric import PathMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-properties + """ + + def __init__(self): + super().__init__(PathProperties) + + def __get__(self, instance, owner=None) -> ( + 'PathPropertiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathProperties': + pass + + def __enter__(self) -> 'PathProperties': + pass + + +class PathProperties( + YANGContainer, + metaclass=PathPropertiesMeta): + """ + YANG container handler. + + YANG name: path-properties + """ + + _yang_name: Final[str] = 'path-properties' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-route-objects': ( + path_route_objects := ( # YANGContainerMember( + PathPropertiesMeta. + PathRouteObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric': ( + path_metric := ( # YANGListMember( + PathPropertiesMeta. + PathMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathProperties': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7645abedd4d25aeb9c77aa579c2972a450d00a6e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_metric/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric + """ + + def __init__(self): + super().__init__(PathMetric) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetric']: + pass + + def __iter__(self, key) -> Iterator['PathMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetric': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricMeta.yang_list_descriptor'): + pass + + +class PathMetric( + YANGListItem, + metaclass=PathMetricMeta): + """ + YANG list item handler. + + YANG name: path-metric + """ + + _yang_name: Final[str] = 'path-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'accumulative-value': ( + accumulative_value := YANGLeafMember( + 'accumulative-value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2af8eb3f47d7b0ceb2d21f9f5b1ee44b432ab35f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-route-objects + """ + from .path_route_object import PathRouteObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-route-objects + """ + + def __init__(self): + super().__init__(PathRouteObjects) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathRouteObjects': + pass + + def __enter__(self) -> 'PathRouteObjects': + pass + + +class PathRouteObjects( + YANGContainer, + metaclass=PathRouteObjectsMeta): + """ + YANG container handler. + + YANG name: path-route-objects + """ + + _yang_name: Final[str] = 'path-route-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-route-object': ( + path_route_object := ( # YANGListMember( + PathRouteObjectsMeta. + PathRouteObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74b9e21c769902d7a2bb1f362d2e95cbf5d862cd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-route-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-route-object + """ + + def __init__(self): + super().__init__(PathRouteObject) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathRouteObject']: + pass + + def __iter__(self, key) -> Iterator['PathRouteObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathRouteObject': + return super()[key] + + def __enter__(self) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + pass + + +class PathRouteObject( + YANGListItem, + metaclass=PathRouteObjectMeta): + """ + YANG list item handler. + + YANG name: path-route-object + """ + + _yang_name: Final[str] = 'path-route-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathRouteObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathRouteObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ce99e420e4339dbff19a79559a99828a5632ed52 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7de25b7bbfed705b63d9c681cad27d7bd9b9584d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/path_properties/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..718667143f90b280fcd63585a43ec31bd9555933 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .tunnels import Tunnels + from .primary_path import PrimaryPath + from .tunnel_termination_points import TunnelTerminationPoints + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6b6e1ff5cb9da5f8c265df0f8c0854de089ff9ef --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d1ab68ff674ea58adde5a644c74609928fe6f874 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .label import Label + from .numbered_link_hop import NumberedLinkHop + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..64a8ec6d5e2fd4a77c59c13b3e37cacb001c91fe --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1182654a4bf2eb5a4496796aa2c9752309208f46 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2961e2bf8c581c42005442bebf3b91dd7424a524 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .label import Label + from .numbered_link_hop import NumberedLinkHop + from .as_number import AsNumber + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..088a2a9a5842516b7391cf36f8c90e94028a03d5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8ae8cc268f3c4fc331cd1e1018be41d113da9183 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d36aa35acd17db473e177b143afdec573f0b4927 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/local_link_connectivity/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c8d4f4c8def0e90dabe399cc305dc3b8d3d500 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: optimizations + """ + from .algorithm import Algorithm + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: optimizations + """ + + def __init__(self): + super().__init__(Optimizations) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Optimizations': + pass + + def __enter__(self) -> 'Optimizations': + pass + + +class Optimizations( + YANGContainer, + metaclass=OptimizationsMeta): + """ + YANG container handler. + + YANG name: optimizations + """ + + _yang_name: Final[str] = 'optimizations' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Optimizations': + instance = super().__new__(cls) + instance._yang_choices = { + + 'algorithm': + OptimizationsMeta.Algorithm( + instance), + } + return instance + + @property + def algorithm(self) -> ( + OptimizationsMeta.Algorithm): + return self._yang_choices['algorithm'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9e0ca52a42ed25af1b7e0612d3e9a6b3d43b6ef9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/__init__.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AlgorithmMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: algorithm + """ + + from .objective_function import ObjectiveFunction + from .metric import Metric + + class objective_function_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.objective_function_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.ObjectiveFunction'): + pass + + class metric_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__( + AlgorithmMeta.Metric) + + def __get__(self, instance, owner=None) -> ( + 'AlgorithmMeta.metric_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + def __enter__(self) -> ( + 'AlgorithmMeta.Metric'): + pass + + +class Algorithm(YANGChoice, metaclass=AlgorithmMeta): + """ + YANG choice handler. + + YANG name: algorithm + """ + + _yang_name: Final[str] = 'algorithm' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'objective-function': ( + objective_function := ( # YANGChoiceCase( + AlgorithmMeta. + objective_function_case_descriptor())), + + 'metric': ( + metric := ( # YANGChoiceCase( + AlgorithmMeta. + metric_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e7d1da8ee3719d0d6a3c401df7340fbd3517e8ed --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MetricMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: metric + """ + from .tiebreakers import Tiebreakers + from .optimization_metric import OptimizationMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: metric + """ + + def __init__(self): + super().__init__(Metric) + + def __get__(self, instance, owner=None) -> ( + 'MetricMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Metric': + pass + + def __enter__(self) -> 'Metric': + pass + + +class Metric( + YANGContainer, + metaclass=MetricMeta): + """ + YANG container handler. + + YANG name: metric + """ + + _yang_name: Final[str] = 'metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tiebreakers': ( + tiebreakers := ( # YANGContainerMember( + MetricMeta. + Tiebreakers. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'optimization-metric': ( + optimization_metric := ( # YANGListMember( + MetricMeta. + OptimizationMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Metric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e0b3f85a0993ca8184c4cec6a891f373b0666767 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class OptimizationMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: optimization-metric + """ + from .explicit_route_include_objects import ExplicitRouteIncludeObjects + from .explicit_route_exclude_objects import ExplicitRouteExcludeObjects + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: optimization-metric + """ + + def __init__(self): + super().__init__(OptimizationMetric) + + def __get__(self, instance, owner=None) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['OptimizationMetric']: + pass + + def __iter__(self, key) -> Iterator['OptimizationMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'OptimizationMetric': + return super()[key] + + def __enter__(self) -> ( + 'OptimizationMetricMeta.yang_list_descriptor'): + pass + + +class OptimizationMetric( + YANGListItem, + metaclass=OptimizationMetricMeta): + """ + YANG list item handler. + + YANG name: optimization-metric + """ + + _yang_name: Final[str] = 'optimization-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'weight': ( + weight := YANGLeafMember( + 'weight', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'explicit-route-include-objects': ( + explicit_route_include_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteIncludeObjects. + yang_container_descriptor())), + + 'explicit-route-exclude-objects': ( + explicit_route_exclude_objects := ( # YANGContainerMember( + OptimizationMetricMeta. + ExplicitRouteExcludeObjects. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'OptimizationMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aea7bdd4cd5ed1743a1764899878a1ac8035348e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteExcludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + from .route_object_exclude_object import RouteObjectExcludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-exclude-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteExcludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteExcludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteExcludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteExcludeObjects': + pass + + +class ExplicitRouteExcludeObjects( + YANGContainer, + metaclass=ExplicitRouteExcludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-exclude-objects + """ + + _yang_name: Final[str] = 'explicit-route-exclude-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-exclude-object': ( + route_object_exclude_object := ( # YANGListMember( + ExplicitRouteExcludeObjectsMeta. + RouteObjectExcludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteExcludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..405906d3e6d9dd1eda79aae3a6302c37e0e24988 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectExcludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-exclude-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-exclude-object + """ + + def __init__(self): + super().__init__(RouteObjectExcludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectExcludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectExcludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectExcludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectExcludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectExcludeObject( + YANGListItem, + metaclass=RouteObjectExcludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-exclude-object + """ + + _yang_name: Final[str] = 'route-object-exclude-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectExcludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectExcludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectExcludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ef448f1cfb4766cf527a00e8da8e1a261466c995 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/__init__.py @@ -0,0 +1,217 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .srlg import Srlg + from .numbered_node_hop import NumberedNodeHop + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .label import Label + + class srlg_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__( + TypeMeta.Srlg) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.srlg_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Srlg'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Srlg'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'srlg': ( + srlg := ( # YANGChoiceCase( + TypeMeta. + srlg_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..420f996a13a20bf122ec87f0fbb109b34246eb61 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + from .srlg import Srlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'srlg': ( + srlg := ( # YANGContainerMember( + SrlgMeta. + Srlg. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..95a1628e4caf545e0d31823f89ea93178ffb76c7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/srlg/srlg/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SrlgMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: srlg + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: srlg + """ + + def __init__(self): + super().__init__(Srlg) + + def __get__(self, instance, owner=None) -> ( + 'SrlgMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Srlg': + pass + + def __enter__(self) -> 'Srlg': + pass + + +class Srlg( + YANGContainer, + metaclass=SrlgMeta): + """ + YANG container handler. + + YANG name: srlg + """ + + _yang_name: Final[str] = 'srlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'srlg': ( + srlg := YANGLeafMember( + 'srlg', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Srlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8ee74a2b7c7f647d2a88dfb22f44ed0ec1e80e4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_exclude_objects/route_object_exclude_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3209b99bad73493077e9e91a8053f320b05c11c0 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExplicitRouteIncludeObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: explicit-route-include-objects + """ + from .route_object_include_object import RouteObjectIncludeObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: explicit-route-include-objects + """ + + def __init__(self): + super().__init__(ExplicitRouteIncludeObjects) + + def __get__(self, instance, owner=None) -> ( + 'ExplicitRouteIncludeObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExplicitRouteIncludeObjects': + pass + + def __enter__(self) -> 'ExplicitRouteIncludeObjects': + pass + + +class ExplicitRouteIncludeObjects( + YANGContainer, + metaclass=ExplicitRouteIncludeObjectsMeta): + """ + YANG container handler. + + YANG name: explicit-route-include-objects + """ + + _yang_name: Final[str] = 'explicit-route-include-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'route-object-include-object': ( + route_object_include_object := ( # YANGListMember( + ExplicitRouteIncludeObjectsMeta. + RouteObjectIncludeObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExplicitRouteIncludeObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c9f24330ff35e20e47be0db730f6ec682dd71d2d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class RouteObjectIncludeObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: route-object-include-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: route-object-include-object + """ + + def __init__(self): + super().__init__(RouteObjectIncludeObject) + + def __get__(self, instance, owner=None) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['RouteObjectIncludeObject']: + pass + + def __iter__(self, key) -> Iterator['RouteObjectIncludeObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'RouteObjectIncludeObject': + return super()[key] + + def __enter__(self) -> ( + 'RouteObjectIncludeObjectMeta.yang_list_descriptor'): + pass + + +class RouteObjectIncludeObject( + YANGListItem, + metaclass=RouteObjectIncludeObjectMeta): + """ + YANG list item handler. + + YANG name: route-object-include-object + """ + + _yang_name: Final[str] = 'route-object-include-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'RouteObjectIncludeObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + RouteObjectIncludeObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + RouteObjectIncludeObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..943ba0bd2ef587976729a620de43a51d18612462 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_link_hop import NumberedLinkHop + from .numbered_node_hop import NumberedNodeHop + from .label import Label + from .as_number import AsNumber + from .unnumbered_link_hop import UnnumberedLinkHop + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ad1ed06e7edbba03876800aa1f46233860ec8b0d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/optimization_metric/explicit_route_include_objects/route_object_include_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/tiebreakers/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/tiebreakers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d345b57b342afaa50a04c5782794f34b810b795c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/tiebreakers/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakersMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tiebreakers + """ + from .tiebreaker import Tiebreaker + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tiebreakers + """ + + def __init__(self): + super().__init__(Tiebreakers) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakersMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tiebreakers': + pass + + def __enter__(self) -> 'Tiebreakers': + pass + + +class Tiebreakers( + YANGContainer, + metaclass=TiebreakersMeta): + """ + YANG container handler. + + YANG name: tiebreakers + """ + + _yang_name: Final[str] = 'tiebreakers' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tiebreaker': ( + tiebreaker := ( # YANGListMember( + TiebreakersMeta. + Tiebreaker. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreakers': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..500d880ad6ad48b8079aa3bea0b1e644f7008f49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/metric/tiebreakers/tiebreaker/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TiebreakerMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tiebreaker + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tiebreaker + """ + + def __init__(self): + super().__init__(Tiebreaker) + + def __get__(self, instance, owner=None) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tiebreaker']: + pass + + def __iter__(self, key) -> Iterator['Tiebreaker']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tiebreaker': + return super()[key] + + def __enter__(self) -> ( + 'TiebreakerMeta.yang_list_descriptor'): + pass + + +class Tiebreaker( + YANGListItem, + metaclass=TiebreakerMeta): + """ + YANG list item handler. + + YANG name: tiebreaker + """ + + _yang_name: Final[str] = 'tiebreaker' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tiebreaker-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tiebreaker-type': ( + tiebreaker_type := YANGLeafMember( + 'tiebreaker-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tiebreaker': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd32a2bb98c6e47f795103fbc122cbf7957e1e6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/objective_function/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + from .objective_function import ObjectiveFunction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'objective-function': ( + objective_function := ( # YANGContainerMember( + ObjectiveFunctionMeta. + ObjectiveFunction. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/objective_function/objective_function/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/objective_function/objective_function/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af72bcf2702ccee1d360bad39000241d1abfdc19 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/optimizations/algorithm/objective_function/objective_function/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ObjectiveFunctionMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: objective-function + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: objective-function + """ + + def __init__(self): + super().__init__(ObjectiveFunction) + + def __get__(self, instance, owner=None) -> ( + 'ObjectiveFunctionMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ObjectiveFunction': + pass + + def __enter__(self) -> 'ObjectiveFunction': + pass + + +class ObjectiveFunction( + YANGContainer, + metaclass=ObjectiveFunctionMeta): + """ + YANG container handler. + + YANG name: objective-function + """ + + _yang_name: Final[str] = 'objective-function' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'objective-function-type': ( + objective_function_type := YANGLeafMember( + 'objective-function-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ObjectiveFunction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c83cf0a2d0df81953e96e2a55fde9fd16c751d0a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/__init__.py @@ -0,0 +1,151 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathConstraintsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-constraints + """ + from .path_affinities_values import PathAffinitiesValues + from .path_srlgs_lists import PathSrlgsLists + from .path_metric_bounds import PathMetricBounds + from .path_srlgs_names import PathSrlgsNames + from .path_affinity_names import PathAffinityNames + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-constraints + """ + + def __init__(self): + super().__init__(PathConstraints) + + def __get__(self, instance, owner=None) -> ( + 'PathConstraintsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathConstraints': + pass + + def __enter__(self) -> 'PathConstraints': + pass + + +class PathConstraints( + YANGContainer, + metaclass=PathConstraintsMeta): + """ + YANG container handler. + + YANG name: path-constraints + """ + + _yang_name: Final[str] = 'path-constraints' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hold-priority': ( + hold_priority := YANGLeafMember( + 'hold-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'setup-priority': ( + setup_priority := YANGLeafMember( + 'setup-priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'signaling-type': ( + signaling_type := YANGLeafMember( + 'signaling-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection': ( + link_protection := YANGLeafMember( + 'link-protection', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinitiesValues. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-metric-bounds': ( + path_metric_bounds := ( # YANGContainerMember( + PathConstraintsMeta. + PathMetricBounds. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathConstraintsMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + PathConstraintsMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathConstraints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e4a21b11accc2103aa85169cb46c386658d5cc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_metric_bounds/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_metric_bounds/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..356f7761b99b2e313b0638407dbaaa3996e6c418 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_metric_bounds/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-metric-bounds + """ + from .path_metric_bound import PathMetricBound + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-metric-bounds + """ + + def __init__(self): + super().__init__(PathMetricBounds) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathMetricBounds': + pass + + def __enter__(self) -> 'PathMetricBounds': + pass + + +class PathMetricBounds( + YANGContainer, + metaclass=PathMetricBoundsMeta): + """ + YANG container handler. + + YANG name: path-metric-bounds + """ + + _yang_name: Final[str] = 'path-metric-bounds' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric-bound': ( + path_metric_bound := ( # YANGListMember( + PathMetricBoundsMeta. + PathMetricBound. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBounds': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_metric_bounds/path_metric_bound/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_metric_bounds/path_metric_bound/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2a97d5e3e1d7066756b051d139f997d9a46b3c6b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_metric_bounds/path_metric_bound/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricBoundMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric-bound + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric-bound + """ + + def __init__(self): + super().__init__(PathMetricBound) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetricBound']: + pass + + def __iter__(self, key) -> Iterator['PathMetricBound']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetricBound': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricBoundMeta.yang_list_descriptor'): + pass + + +class PathMetricBound( + YANGListItem, + metaclass=PathMetricBoundMeta): + """ + YANG list item handler. + + YANG name: path-metric-bound + """ + + _yang_name: Final[str] = 'path-metric-bound' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'upper-bound': ( + upper_bound := YANGLeafMember( + 'upper-bound', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetricBound': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_constraints/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..41c96a46e00a42f281a1cdc712517006ccd5fa0b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/__init__.py @@ -0,0 +1,121 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathPropertiesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-properties + """ + from .path_route_objects import PathRouteObjects + from .path_affinity_names import PathAffinityNames + from .path_srlgs_lists import PathSrlgsLists + from .path_srlgs_names import PathSrlgsNames + from .path_affinities_values import PathAffinitiesValues + from .path_metric import PathMetric + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-properties + """ + + def __init__(self): + super().__init__(PathProperties) + + def __get__(self, instance, owner=None) -> ( + 'PathPropertiesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathProperties': + pass + + def __enter__(self) -> 'PathProperties': + pass + + +class PathProperties( + YANGContainer, + metaclass=PathPropertiesMeta): + """ + YANG container handler. + + YANG name: path-properties + """ + + _yang_name: Final[str] = 'path-properties' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'path-route-objects': ( + path_route_objects := ( # YANGContainerMember( + PathPropertiesMeta. + PathRouteObjects. + yang_container_descriptor())), + + 'path-affinity-names': ( + path_affinity_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinityNames. + yang_container_descriptor())), + + 'path-srlgs-lists': ( + path_srlgs_lists := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsLists. + yang_container_descriptor())), + + 'path-srlgs-names': ( + path_srlgs_names := ( # YANGContainerMember( + PathPropertiesMeta. + PathSrlgsNames. + yang_container_descriptor())), + + 'path-affinities-values': ( + path_affinities_values := ( # YANGContainerMember( + PathPropertiesMeta. + PathAffinitiesValues. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-metric': ( + path_metric := ( # YANGListMember( + PathPropertiesMeta. + PathMetric. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathProperties': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinities_values/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinities_values/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c038ff21414923b939355bb6bdda825d64ece5a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinities_values/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValuesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinities-values + """ + from .path_affinities_value import PathAffinitiesValue + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinities-values + """ + + def __init__(self): + super().__init__(PathAffinitiesValues) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValuesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinitiesValues': + pass + + def __enter__(self) -> 'PathAffinitiesValues': + pass + + +class PathAffinitiesValues( + YANGContainer, + metaclass=PathAffinitiesValuesMeta): + """ + YANG container handler. + + YANG name: path-affinities-values + """ + + _yang_name: Final[str] = 'path-affinities-values' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinities-value': ( + path_affinities_value := ( # YANGListMember( + PathAffinitiesValuesMeta. + PathAffinitiesValue. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValues': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinities_values/path_affinities_value/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinities_values/path_affinities_value/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7560d7f51b4174c036b96d1a6599a2a3ada8d674 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinities_values/path_affinities_value/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinitiesValueMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinities-value + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinities-value + """ + + def __init__(self): + super().__init__(PathAffinitiesValue) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinitiesValue']: + pass + + def __iter__(self, key) -> Iterator['PathAffinitiesValue']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinitiesValue': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinitiesValueMeta.yang_list_descriptor'): + pass + + +class PathAffinitiesValue( + YANGListItem, + metaclass=PathAffinitiesValueMeta): + """ + YANG list item handler. + + YANG name: path-affinities-value + """ + + _yang_name: Final[str] = 'path-affinities-value' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'value': ( + value := YANGLeafMember( + 'value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinitiesValue': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a8439d312f2b42a7a09bb2b04e3c9207920fe69c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-affinity-names + """ + from .path_affinity_name import PathAffinityName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-affinity-names + """ + + def __init__(self): + super().__init__(PathAffinityNames) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathAffinityNames': + pass + + def __enter__(self) -> 'PathAffinityNames': + pass + + +class PathAffinityNames( + YANGContainer, + metaclass=PathAffinityNamesMeta): + """ + YANG container handler. + + YANG name: path-affinity-names + """ + + _yang_name: Final[str] = 'path-affinity-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-affinity-name': ( + path_affinity_name := ( # YANGListMember( + PathAffinityNamesMeta. + PathAffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/path_affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/path_affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f56a1940217a7ca828879399878fa57c2402196c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/path_affinity_name/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathAffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-affinity-name + """ + from .affinity_name import AffinityName + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-affinity-name + """ + + def __init__(self): + super().__init__(PathAffinityName) + + def __get__(self, instance, owner=None) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathAffinityName']: + pass + + def __iter__(self, key) -> Iterator['PathAffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathAffinityName': + return super()[key] + + def __enter__(self) -> ( + 'PathAffinityNameMeta.yang_list_descriptor'): + pass + + +class PathAffinityName( + YANGListItem, + metaclass=PathAffinityNameMeta): + """ + YANG list item handler. + + YANG name: path-affinity-name + """ + + _yang_name: Final[str] = 'path-affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'affinity-name': ( + affinity_name := ( # YANGListMember( + PathAffinityNameMeta. + AffinityName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathAffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75d22895c1b8c77e3c13ad584eaac74d23d0e359 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_affinity_names/path_affinity_name/affinity_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AffinityNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: affinity-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: affinity-name + """ + + def __init__(self): + super().__init__(AffinityName) + + def __get__(self, instance, owner=None) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['AffinityName']: + pass + + def __iter__(self, key) -> Iterator['AffinityName']: + return super().__iter__() + + def __getitem__(self, key) -> 'AffinityName': + return super()[key] + + def __enter__(self) -> ( + 'AffinityNameMeta.yang_list_descriptor'): + pass + + +class AffinityName( + YANGListItem, + metaclass=AffinityNameMeta): + """ + YANG list item handler. + + YANG name: affinity-name + """ + + _yang_name: Final[str] = 'affinity-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AffinityName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_metric/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_metric/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d6ae074074e7913854992f9bd32a8f51f6b9d7b7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_metric/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathMetricMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-metric + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-metric + """ + + def __init__(self): + super().__init__(PathMetric) + + def __get__(self, instance, owner=None) -> ( + 'PathMetricMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathMetric']: + pass + + def __iter__(self, key) -> Iterator['PathMetric']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathMetric': + return super()[key] + + def __enter__(self) -> ( + 'PathMetricMeta.yang_list_descriptor'): + pass + + +class PathMetric( + YANGListItem, + metaclass=PathMetricMeta): + """ + YANG list item handler. + + YANG name: path-metric + """ + + _yang_name: Final[str] = 'path-metric' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'metric-type', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'metric-type': ( + metric_type := YANGLeafMember( + 'metric-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'accumulative-value': ( + accumulative_value := YANGLeafMember( + 'accumulative-value', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathMetric': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2af8eb3f47d7b0ceb2d21f9f5b1ee44b432ab35f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-route-objects + """ + from .path_route_object import PathRouteObject + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-route-objects + """ + + def __init__(self): + super().__init__(PathRouteObjects) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathRouteObjects': + pass + + def __enter__(self) -> 'PathRouteObjects': + pass + + +class PathRouteObjects( + YANGContainer, + metaclass=PathRouteObjectsMeta): + """ + YANG container handler. + + YANG name: path-route-objects + """ + + _yang_name: Final[str] = 'path-route-objects' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-route-object': ( + path_route_object := ( # YANGListMember( + PathRouteObjectsMeta. + PathRouteObject. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObjects': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74b9e21c769902d7a2bb1f362d2e95cbf5d862cd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathRouteObjectMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-route-object + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-route-object + """ + + def __init__(self): + super().__init__(PathRouteObject) + + def __get__(self, instance, owner=None) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathRouteObject']: + pass + + def __iter__(self, key) -> Iterator['PathRouteObject']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathRouteObject': + return super()[key] + + def __enter__(self) -> ( + 'PathRouteObjectMeta.yang_list_descriptor'): + pass + + +class PathRouteObject( + YANGListItem, + metaclass=PathRouteObjectMeta): + """ + YANG list item handler. + + YANG name: path-route-object + """ + + _yang_name: Final[str] = 'path-route-object' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathRouteObject': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathRouteObjectMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathRouteObjectMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ba147c0c9510241b8cc6f8aa2235042dd634f850 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + from .numbered_link_hop import NumberedLinkHop + from .label import Label + from .unnumbered_link_hop import UnnumberedLinkHop + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1cb78075b80ccd8887818376324a016daf17b67c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e568286bdabfa9cd970ff66b3e9b6a807b0f31f3 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_route_objects/path_route_object/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_lists/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_lists/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5e807a0b29d665deaaed7620fee6b2b7c697fbb6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_lists/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-lists + """ + from .path_srlgs_list import PathSrlgsList + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-lists + """ + + def __init__(self): + super().__init__(PathSrlgsLists) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsLists': + pass + + def __enter__(self) -> 'PathSrlgsLists': + pass + + +class PathSrlgsLists( + YANGContainer, + metaclass=PathSrlgsListsMeta): + """ + YANG container handler. + + YANG name: path-srlgs-lists + """ + + _yang_name: Final[str] = 'path-srlgs-lists' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-list': ( + path_srlgs_list := ( # YANGListMember( + PathSrlgsListsMeta. + PathSrlgsList. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsLists': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..631911d141fd6e870942bd77f7ad80c33e221091 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_lists/path_srlgs_list/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsListMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-list + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-list + """ + + def __init__(self): + super().__init__(PathSrlgsList) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsList']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsList']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsList': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsListMeta.yang_list_descriptor'): + pass + + +class PathSrlgsList( + YANGListItem, + metaclass=PathSrlgsListMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-list + """ + + _yang_name: Final[str] = 'path-srlgs-list' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsList': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_names/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_names/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..54d85c0e52070f3cffb5a27ea963d0923bdcc379 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_names/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNamesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: path-srlgs-names + """ + from .path_srlgs_name import PathSrlgsName + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: path-srlgs-names + """ + + def __init__(self): + super().__init__(PathSrlgsNames) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNamesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PathSrlgsNames': + pass + + def __enter__(self) -> 'PathSrlgsNames': + pass + + +class PathSrlgsNames( + YANGContainer, + metaclass=PathSrlgsNamesMeta): + """ + YANG container handler. + + YANG name: path-srlgs-names + """ + + _yang_name: Final[str] = 'path-srlgs-names' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-srlgs-name': ( + path_srlgs_name := ( # YANGListMember( + PathSrlgsNamesMeta. + PathSrlgsName. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsNames': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_names/path_srlgs_name/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_names/path_srlgs_name/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d9b66f1860f862ec66429b96c9f73d88815ecfd6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/path_properties/path_srlgs_names/path_srlgs_name/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathSrlgsNameMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-srlgs-name + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-srlgs-name + """ + + def __init__(self): + super().__init__(PathSrlgsName) + + def __get__(self, instance, owner=None) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathSrlgsName']: + pass + + def __iter__(self, key) -> Iterator['PathSrlgsName']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathSrlgsName': + return super()[key] + + def __enter__(self) -> ( + 'PathSrlgsNameMeta.yang_list_descriptor'): + pass + + +class PathSrlgsName( + YANGListItem, + metaclass=PathSrlgsNameMeta): + """ + YANG list item handler. + + YANG name: path-srlgs-name + """ + + _yang_name: Final[str] = 'path-srlgs-name' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'usage', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'usage': ( + usage := YANGLeafMember( + 'usage', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathSrlgsName': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9ef388cd63aa7c8947fc3391bad703bb01f3d827 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .primary_path import PrimaryPath + from .tunnel_termination_points import TunnelTerminationPoints + from .tunnels import Tunnels + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6b6e1ff5cb9da5f8c265df0f8c0854de089ff9ef --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..756916fe5305db0152f03d2c6c3aabec84ab6e89 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .numbered_node_hop import NumberedNodeHop + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b97fc02b90568c1b4e8df5f758ab24f6bcb5be9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3a6876e61b9d99b8ed5b00bc13f60857e8fb3d76 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..dcd3c6917ac3e0b72b371917edbce5bc14d39c40 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .as_number import AsNumber + from .numbered_link_hop import NumberedLinkHop + from .unnumbered_link_hop import UnnumberedLinkHop + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..64a8ec6d5e2fd4a77c59c13b3e37cacb001c91fe --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5baa996de0fff24876e40ec73f87a7a90da1f2ea --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8ae8cc268f3c4fc331cd1e1018be41d113da9183 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f854dfd329ce016317b7b9743ace874769f03094 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/local_link_connectivities/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9ed869cac9cbe0a847a4fd06e39f4e8cb0944cfb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/__init__.py @@ -0,0 +1,99 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class StatisticsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: statistics + """ + from .tunnel_termination_point import TunnelTerminationPoint + from .local_link_connectivity import LocalLinkConnectivity + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: statistics + """ + + def __init__(self): + super().__init__(Statistics) + + def __get__(self, instance, owner=None) -> ( + 'StatisticsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Statistics': + pass + + def __enter__(self) -> 'Statistics': + pass + + +class Statistics( + YANGContainer, + metaclass=StatisticsMeta): + """ + YANG container handler. + + YANG name: statistics + """ + + _yang_name: Final[str] = 'statistics' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'discontinuity-time': ( + discontinuity_time := YANGLeafMember( + 'discontinuity-time', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'tunnel-termination-point': ( + tunnel_termination_point := ( # YANGContainerMember( + StatisticsMeta. + TunnelTerminationPoint. + yang_container_descriptor())), + + 'local-link-connectivity': ( + local_link_connectivity := ( # YANGContainerMember( + StatisticsMeta. + LocalLinkConnectivity. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Statistics': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/local_link_connectivity/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/local_link_connectivity/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..968aa5f224d812d13c53912ca6346f0e872afa9d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/local_link_connectivity/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LocalLinkConnectivityMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: local-link-connectivity + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: local-link-connectivity + """ + + def __init__(self): + super().__init__(LocalLinkConnectivity) + + def __get__(self, instance, owner=None) -> ( + 'LocalLinkConnectivityMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LocalLinkConnectivity': + pass + + def __enter__(self) -> 'LocalLinkConnectivity': + pass + + +class LocalLinkConnectivity( + YANGContainer, + metaclass=LocalLinkConnectivityMeta): + """ + YANG container handler. + + YANG name: local-link-connectivity + """ + + _yang_name: Final[str] = 'local-link-connectivity' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enables': ( + enables := YANGLeafMember( + 'enables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'creates': ( + creates := YANGLeafMember( + 'creates', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'deletes': ( + deletes := YANGLeafMember( + 'deletes', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'modifies': ( + modifies := YANGLeafMember( + 'modifies', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disables': ( + disables := YANGLeafMember( + 'disables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LocalLinkConnectivity': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/tunnel_termination_point/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/tunnel_termination_point/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0226e0183e765f0c6bfc59a10e95220a32c88eb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/statistics/tunnel_termination_point/__init__.py @@ -0,0 +1,133 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-point + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-point + """ + + def __init__(self): + super().__init__(TunnelTerminationPoint) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoint': + pass + + def __enter__(self) -> 'TunnelTerminationPoint': + pass + + +class TunnelTerminationPoint( + YANGContainer, + metaclass=TunnelTerminationPointMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-point + """ + + _yang_name: Final[str] = 'tunnel-termination-point' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'maintenance-sets': ( + maintenance_sets := YANGLeafMember( + 'maintenance-sets', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'downs': ( + downs := YANGLeafMember( + 'downs', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'modifies': ( + modifies := YANGLeafMember( + 'modifies', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disables': ( + disables := YANGLeafMember( + 'disables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'in-service-sets': ( + in_service_sets := YANGLeafMember( + 'in-service-sets', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'enables': ( + enables := YANGLeafMember( + 'enables', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'maintenance-clears': ( + maintenance_clears := YANGLeafMember( + 'maintenance-clears', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'ups': ( + ups := YANGLeafMember( + 'ups', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'in-service-clears': ( + in_service_clears := YANGLeafMember( + 'in-service-clears', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoint': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/supporting_tunnel_termination_point/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/supporting_tunnel_termination_point/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6c49df48431602d92607be89318349d2e837536e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/te/tunnel_termination_point/supporting_tunnel_termination_point/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SupportingTunnelTerminationPointMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: supporting-tunnel-termination-point + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: supporting-tunnel-termination-point + """ + + def __init__(self): + super().__init__(SupportingTunnelTerminationPoint) + + def __get__(self, instance, owner=None) -> ( + 'SupportingTunnelTerminationPointMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SupportingTunnelTerminationPoint']: + pass + + def __iter__(self, key) -> Iterator['SupportingTunnelTerminationPoint']: + return super().__iter__() + + def __getitem__(self, key) -> 'SupportingTunnelTerminationPoint': + return super()[key] + + def __enter__(self) -> ( + 'SupportingTunnelTerminationPointMeta.yang_list_descriptor'): + pass + + +class SupportingTunnelTerminationPoint( + YANGListItem, + metaclass=SupportingTunnelTerminationPointMeta): + """ + YANG list item handler. + + YANG name: supporting-tunnel-termination-point + """ + + _yang_name: Final[str] = 'supporting-tunnel-termination-point' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'node-ref', + 'tunnel-tp-ref', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'tunnel-tp-ref': ( + tunnel_tp_ref := YANGLeafMember( + 'tunnel-tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-ref': ( + node_ref := YANGLeafMember( + 'node-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SupportingTunnelTerminationPoint': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c57b1997c1a86a82962fe2fa49041f529d8c1e0b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/__init__.py @@ -0,0 +1,116 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TerminationPointMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: termination-point + """ + from .te import Te + from .supporting_termination_point import SupportingTerminationPoint + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: termination-point + """ + + def __init__(self): + super().__init__(TerminationPoint) + + def __get__(self, instance, owner=None) -> ( + 'TerminationPointMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['TerminationPoint']: + pass + + def __iter__(self, key) -> Iterator['TerminationPoint']: + return super().__iter__() + + def __getitem__(self, key) -> 'TerminationPoint': + return super()[key] + + def __enter__(self) -> ( + 'TerminationPointMeta.yang_list_descriptor'): + pass + + +class TerminationPoint( + YANGListItem, + metaclass=TerminationPointMeta): + """ + YANG list item handler. + + YANG name: termination-point + """ + + _yang_name: Final[str] = 'termination-point' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-topology' + _yang_module_name: Final[str] = 'ietf-network-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tp-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'te-tp-id': ( + te_tp_id := YANGLeafMember( + 'te-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tp-id': ( + tp_id := YANGLeafMember( + 'tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te': ( + te := ( # YANGContainerMember( + TerminationPointMeta. + Te. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'supporting-termination-point': ( + supporting_termination_point := ( # YANGListMember( + TerminationPointMeta. + SupportingTerminationPoint. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TerminationPoint': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/supporting_termination_point/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/supporting_termination_point/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..677a83f1ad4e37460d2b705a8aae82f716d19ced --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/supporting_termination_point/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SupportingTerminationPointMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: supporting-termination-point + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: supporting-termination-point + """ + + def __init__(self): + super().__init__(SupportingTerminationPoint) + + def __get__(self, instance, owner=None) -> ( + 'SupportingTerminationPointMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SupportingTerminationPoint']: + pass + + def __iter__(self, key) -> Iterator['SupportingTerminationPoint']: + return super().__iter__() + + def __getitem__(self, key) -> 'SupportingTerminationPoint': + return super()[key] + + def __enter__(self) -> ( + 'SupportingTerminationPointMeta.yang_list_descriptor'): + pass + + +class SupportingTerminationPoint( + YANGListItem, + metaclass=SupportingTerminationPointMeta): + """ + YANG list item handler. + + YANG name: supporting-termination-point + """ + + _yang_name: Final[str] = 'supporting-termination-point' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network-topology' + _yang_module_name: Final[str] = 'ietf-network-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'network-ref', + 'node-ref', + 'tp-ref', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-ref': ( + node_ref := YANGLeafMember( + 'node-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + + 'tp-ref': ( + tp_ref := YANGLeafMember( + 'tp-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network-topology', + 'ietf-network-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SupportingTerminationPoint': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..01c6bcdf0dcc0a0e9c3adb4b0c4580182a030510 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/__init__.py @@ -0,0 +1,117 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te + """ + from .geolocation import Geolocation + from .interface_switching_capability import InterfaceSwitchingCapability + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te + """ + + def __init__(self): + super().__init__(Te) + + def __get__(self, instance, owner=None) -> ( + 'TeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Te': + pass + + def __enter__(self) -> 'Te': + pass + + +class Te( + YANGContainer, + metaclass=TeMeta): + """ + YANG container handler. + + YANG name: te + """ + + _yang_name: Final[str] = 'te' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'admin-status': ( + admin_status := YANGLeafMember( + 'admin-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'inter-domain-plug-id': ( + inter_domain_plug_id := YANGLeafMember( + 'inter-domain-plug-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'oper-status': ( + oper_status := YANGLeafMember( + 'oper-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'geolocation': ( + geolocation := ( # YANGContainerMember( + TeMeta. + Geolocation. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'interface-switching-capability': ( + interface_switching_capability := ( # YANGListMember( + TeMeta. + InterfaceSwitchingCapability. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Te': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/geolocation/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/geolocation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e58eb1516669a36eac9abd5451d7335da8de62a4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/geolocation/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GeolocationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: geolocation + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: geolocation + """ + + def __init__(self): + super().__init__(Geolocation) + + def __get__(self, instance, owner=None) -> ( + 'GeolocationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Geolocation': + pass + + def __enter__(self) -> 'Geolocation': + pass + + +class Geolocation( + YANGContainer, + metaclass=GeolocationMeta): + """ + YANG container handler. + + YANG name: geolocation + """ + + _yang_name: Final[str] = 'geolocation' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'latitude': ( + latitude := YANGLeafMember( + 'latitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'longitude': ( + longitude := YANGLeafMember( + 'longitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'altitude': ( + altitude := YANGLeafMember( + 'altitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Geolocation': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aed5f69dcca9f3ba106cbda0db555f0efa7fecd1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InterfaceSwitchingCapabilityMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: interface-switching-capability + """ + from .max_lsp_bandwidth import MaxLspBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: interface-switching-capability + """ + + def __init__(self): + super().__init__(InterfaceSwitchingCapability) + + def __get__(self, instance, owner=None) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['InterfaceSwitchingCapability']: + pass + + def __iter__(self, key) -> Iterator['InterfaceSwitchingCapability']: + return super().__iter__() + + def __getitem__(self, key) -> 'InterfaceSwitchingCapability': + return super()[key] + + def __enter__(self) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + pass + + +class InterfaceSwitchingCapability( + YANGListItem, + metaclass=InterfaceSwitchingCapabilityMeta): + """ + YANG list item handler. + + YANG name: interface-switching-capability + """ + + _yang_name: Final[str] = 'interface-switching-capability' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'switching-capability', + 'encoding', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'encoding': ( + encoding := YANGLeafMember( + 'encoding', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'switching-capability': ( + switching_capability := YANGLeafMember( + 'switching-capability', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'max-lsp-bandwidth': ( + max_lsp_bandwidth := ( # YANGListMember( + InterfaceSwitchingCapabilityMeta. + MaxLspBandwidth. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InterfaceSwitchingCapability': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ddad298bbc0cc7c626bd869965fe6da4630b6fb5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLspBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: max-lsp-bandwidth + """ + + def __init__(self): + super().__init__(MaxLspBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MaxLspBandwidth']: + pass + + def __iter__(self, key) -> Iterator['MaxLspBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'MaxLspBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + pass + + +class MaxLspBandwidth( + YANGListItem, + metaclass=MaxLspBandwidthMeta): + """ + YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + + _yang_name: Final[str] = 'max-lsp-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLspBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLspBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/node/termination_point/te/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/supporting_network/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/supporting_network/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1edaacf9b3aac3691d69f548e6e01772d428b4c6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/supporting_network/__init__.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class SupportingNetworkMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: supporting-network + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: supporting-network + """ + + def __init__(self): + super().__init__(SupportingNetwork) + + def __get__(self, instance, owner=None) -> ( + 'SupportingNetworkMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['SupportingNetwork']: + pass + + def __iter__(self, key) -> Iterator['SupportingNetwork']: + return super().__iter__() + + def __getitem__(self, key) -> 'SupportingNetwork': + return super()[key] + + def __enter__(self) -> ( + 'SupportingNetworkMeta.yang_list_descriptor'): + pass + + +class SupportingNetwork( + YANGListItem, + metaclass=SupportingNetworkMeta): + """ + YANG list item handler. + + YANG name: supporting-network + """ + + _yang_name: Final[str] = 'supporting-network' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-network' + _yang_module_name: Final[str] = 'ietf-network' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'network-ref', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-network', + 'ietf-network')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'SupportingNetwork': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..748195d4bd7b81c2ed3d20720cab2c5bff4750aa --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/__init__.py @@ -0,0 +1,111 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te + """ + from .geolocation import Geolocation + from .nsrlg import Nsrlg + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te + """ + + def __init__(self): + super().__init__(Te) + + def __get__(self, instance, owner=None) -> ( + 'TeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Te': + pass + + def __enter__(self) -> 'Te': + pass + + +class Te( + YANGContainer, + metaclass=TeMeta): + """ + YANG container handler. + + YANG name: te + """ + + _yang_name: Final[str] = 'te' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'preference': ( + preference := YANGLeafMember( + 'preference', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'optimization-criterion': ( + optimization_criterion := YANGLeafMember( + 'optimization-criterion', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'geolocation': ( + geolocation := ( # YANGContainerMember( + TeMeta. + Geolocation. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'nsrlg': ( + nsrlg := ( # YANGListMember( + TeMeta. + Nsrlg. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Te': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/geolocation/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/geolocation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5a631c3553d9ab5ce7b22b799dbf338a0f87fa43 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/geolocation/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GeolocationMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: geolocation + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: geolocation + """ + + def __init__(self): + super().__init__(Geolocation) + + def __get__(self, instance, owner=None) -> ( + 'GeolocationMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Geolocation': + pass + + def __enter__(self) -> 'Geolocation': + pass + + +class Geolocation( + YANGContainer, + metaclass=GeolocationMeta): + """ + YANG container handler. + + YANG name: geolocation + """ + + _yang_name: Final[str] = 'geolocation' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'latitude': ( + latitude := YANGLeafMember( + 'latitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'altitude': ( + altitude := YANGLeafMember( + 'altitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'longitude': ( + longitude := YANGLeafMember( + 'longitude', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Geolocation': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/nsrlg/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/nsrlg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5c7ab09b9180c21eb845684ade6a69b7ca0705 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te/nsrlg/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NsrlgMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: nsrlg + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: nsrlg + """ + + def __init__(self): + super().__init__(Nsrlg) + + def __get__(self, instance, owner=None) -> ( + 'NsrlgMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Nsrlg']: + pass + + def __iter__(self, key) -> Iterator['Nsrlg']: + return super().__iter__() + + def __getitem__(self, key) -> 'Nsrlg': + return super()[key] + + def __enter__(self) -> ( + 'NsrlgMeta.yang_list_descriptor'): + pass + + +class Nsrlg( + YANGListItem, + metaclass=NsrlgMeta): + """ + YANG list item handler. + + YANG name: nsrlg + """ + + _yang_name: Final[str] = 'nsrlg' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'id': ( + id := YANGLeafMember( + 'id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'disjointness': ( + disjointness := YANGLeafMember( + 'disjointness', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Nsrlg': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te_topology_identifier/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te_topology_identifier/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7960995015a5d11e0610babc72827436a32087c1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/network/te_topology_identifier/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeTopologyIdentifierMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-topology-identifier + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-topology-identifier + """ + + def __init__(self): + super().__init__(TeTopologyIdentifier) + + def __get__(self, instance, owner=None) -> ( + 'TeTopologyIdentifierMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeTopologyIdentifier': + pass + + def __enter__(self) -> 'TeTopologyIdentifier': + pass + + +class TeTopologyIdentifier( + YANGContainer, + metaclass=TeTopologyIdentifierMeta): + """ + YANG container handler. + + YANG name: te-topology-identifier + """ + + _yang_name: Final[str] = 'te-topology-identifier' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'topology-id': ( + topology_id := YANGLeafMember( + 'topology-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'provider-id': ( + provider_id := YANGLeafMember( + 'provider-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'client-id': ( + client_id := YANGLeafMember( + 'client-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeTopologyIdentifier': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e44025b207547eea5e7bd79b657543db9c3a4deb --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te + """ + from .templates import Templates + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te + """ + + def __init__(self): + super().__init__(Te) + + def __get__(self, instance, owner=None) -> ( + 'TeMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Te': + pass + + def __enter__(self) -> 'Te': + pass + + +class Te( + YANGContainer, + metaclass=TeMeta): + """ + YANG container handler. + + YANG name: te + """ + + _yang_name: Final[str] = 'te' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'templates': ( + templates := ( # YANGContainerMember( + TeMeta. + Templates. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Te': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7445085d6958e61bbe27aa9366276cfb2d0f2fa4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/__init__.py @@ -0,0 +1,93 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TemplatesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: templates + """ + from .link_template import LinkTemplate + from .node_template import NodeTemplate + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: templates + """ + + def __init__(self): + super().__init__(Templates) + + def __get__(self, instance, owner=None) -> ( + 'TemplatesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Templates': + pass + + def __enter__(self) -> 'Templates': + pass + + +class Templates( + YANGContainer, + metaclass=TemplatesMeta): + """ + YANG container handler. + + YANG name: templates + """ + + _yang_name: Final[str] = 'templates' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'link-template': ( + link_template := ( # YANGListMember( + TemplatesMeta. + LinkTemplate. + yang_list_descriptor())), + + 'node-template': ( + node_template := ( # YANGListMember( + TemplatesMeta. + NodeTemplate. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Templates': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6436895020aa9f268a9cf4b4959e7b3782ab8fdd --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LinkTemplateMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: link-template + """ + from .te_link_attributes import TeLinkAttributes + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: link-template + """ + + def __init__(self): + super().__init__(LinkTemplate) + + def __get__(self, instance, owner=None) -> ( + 'LinkTemplateMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LinkTemplate']: + pass + + def __iter__(self, key) -> Iterator['LinkTemplate']: + return super().__iter__() + + def __getitem__(self, key) -> 'LinkTemplate': + return super()[key] + + def __enter__(self) -> ( + 'LinkTemplateMeta.yang_list_descriptor'): + pass + + +class LinkTemplate( + YANGListItem, + metaclass=LinkTemplateMeta): + """ + YANG list item handler. + + YANG name: link-template + """ + + _yang_name: Final[str] = 'link-template' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'reference-change-policy': ( + reference_change_policy := YANGLeafMember( + 'reference-change-policy', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-link-attributes': ( + te_link_attributes := ( # YANGContainerMember( + LinkTemplateMeta. + TeLinkAttributes. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LinkTemplate': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8165170f1f32e48c8d9e9a8bf33effd915d56ea8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/__init__.py @@ -0,0 +1,202 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLinkAttributesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-link-attributes + """ + from .external_domain import ExternalDomain + from .max_link_bandwidth import MaxLinkBandwidth + from .te_nsrlgs import TeNsrlgs + from .max_resv_link_bandwidth import MaxResvLinkBandwidth + from .label_restrictions import LabelRestrictions + from .underlay import Underlay + from .te_srlgs import TeSrlgs + from .interface_switching_capability import InterfaceSwitchingCapability + from .unreserved_bandwidth import UnreservedBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-link-attributes + """ + + def __init__(self): + super().__init__(TeLinkAttributes) + + def __get__(self, instance, owner=None) -> ( + 'TeLinkAttributesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLinkAttributes': + pass + + def __enter__(self) -> 'TeLinkAttributes': + pass + + +class TeLinkAttributes( + YANGContainer, + metaclass=TeLinkAttributesMeta): + """ + YANG container handler. + + YANG name: te-link-attributes + """ + + _yang_name: Final[str] = 'te-link-attributes' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'te-delay-metric': ( + te_delay_metric := YANGLeafMember( + 'te-delay-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'admin-status': ( + admin_status := YANGLeafMember( + 'admin-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'administrative-group': ( + administrative_group := YANGLeafMember( + 'administrative-group', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-index': ( + link_index := YANGLeafMember( + 'link-index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'access-type': ( + access_type := YANGLeafMember( + 'access-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-igp-metric': ( + te_igp_metric := YANGLeafMember( + 'te-igp-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'te-default-metric': ( + te_default_metric := YANGLeafMember( + 'te-default-metric', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-abstract': ( + is_abstract := YANGLeafMember( + 'is-abstract', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-protection-type': ( + link_protection_type := YANGLeafMember( + 'link-protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'external-domain': ( + external_domain := ( # YANGContainerMember( + TeLinkAttributesMeta. + ExternalDomain. + yang_container_descriptor())), + + 'max-link-bandwidth': ( + max_link_bandwidth := ( # YANGContainerMember( + TeLinkAttributesMeta. + MaxLinkBandwidth. + yang_container_descriptor())), + + 'te-nsrlgs': ( + te_nsrlgs := ( # YANGContainerMember( + TeLinkAttributesMeta. + TeNsrlgs. + yang_container_descriptor())), + + 'max-resv-link-bandwidth': ( + max_resv_link_bandwidth := ( # YANGContainerMember( + TeLinkAttributesMeta. + MaxResvLinkBandwidth. + yang_container_descriptor())), + + 'label-restrictions': ( + label_restrictions := ( # YANGContainerMember( + TeLinkAttributesMeta. + LabelRestrictions. + yang_container_descriptor())), + + 'underlay': ( + underlay := ( # YANGContainerMember( + TeLinkAttributesMeta. + Underlay. + yang_container_descriptor())), + + 'te-srlgs': ( + te_srlgs := ( # YANGContainerMember( + TeLinkAttributesMeta. + TeSrlgs. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'interface-switching-capability': ( + interface_switching_capability := ( # YANGListMember( + TeLinkAttributesMeta. + InterfaceSwitchingCapability. + yang_list_descriptor())), + + 'unreserved-bandwidth': ( + unreserved_bandwidth := ( # YANGListMember( + TeLinkAttributesMeta. + UnreservedBandwidth. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLinkAttributes': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/external_domain/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/external_domain/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..30e28c4c7b69dff7823e0a7aa87672840b5f317b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/external_domain/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class ExternalDomainMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: external-domain + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: external-domain + """ + + def __init__(self): + super().__init__(ExternalDomain) + + def __get__(self, instance, owner=None) -> ( + 'ExternalDomainMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'ExternalDomain': + pass + + def __enter__(self) -> 'ExternalDomain': + pass + + +class ExternalDomain( + YANGContainer, + metaclass=ExternalDomainMeta): + """ + YANG container handler. + + YANG name: external-domain + """ + + _yang_name: Final[str] = 'external-domain' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'remote-te-link-tp-id': ( + remote_te_link_tp_id := YANGLeafMember( + 'remote-te-link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'remote-te-node-id': ( + remote_te_node_id := YANGLeafMember( + 'remote-te-node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'ExternalDomain': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..aed5f69dcca9f3ba106cbda0db555f0efa7fecd1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class InterfaceSwitchingCapabilityMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: interface-switching-capability + """ + from .max_lsp_bandwidth import MaxLspBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: interface-switching-capability + """ + + def __init__(self): + super().__init__(InterfaceSwitchingCapability) + + def __get__(self, instance, owner=None) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['InterfaceSwitchingCapability']: + pass + + def __iter__(self, key) -> Iterator['InterfaceSwitchingCapability']: + return super().__iter__() + + def __getitem__(self, key) -> 'InterfaceSwitchingCapability': + return super()[key] + + def __enter__(self) -> ( + 'InterfaceSwitchingCapabilityMeta.yang_list_descriptor'): + pass + + +class InterfaceSwitchingCapability( + YANGListItem, + metaclass=InterfaceSwitchingCapabilityMeta): + """ + YANG list item handler. + + YANG name: interface-switching-capability + """ + + _yang_name: Final[str] = 'interface-switching-capability' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'switching-capability', + 'encoding', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'encoding': ( + encoding := YANGLeafMember( + 'encoding', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'switching-capability': ( + switching_capability := YANGLeafMember( + 'switching-capability', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'max-lsp-bandwidth': ( + max_lsp_bandwidth := ( # YANGListMember( + InterfaceSwitchingCapabilityMeta. + MaxLspBandwidth. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'InterfaceSwitchingCapability': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ddad298bbc0cc7c626bd869965fe6da4630b6fb5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLspBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: max-lsp-bandwidth + """ + + def __init__(self): + super().__init__(MaxLspBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['MaxLspBandwidth']: + pass + + def __iter__(self, key) -> Iterator['MaxLspBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'MaxLspBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'MaxLspBandwidthMeta.yang_list_descriptor'): + pass + + +class MaxLspBandwidth( + YANGListItem, + metaclass=MaxLspBandwidthMeta): + """ + YANG list item handler. + + YANG name: max-lsp-bandwidth + """ + + _yang_name: Final[str] = 'max-lsp-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLspBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLspBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/interface_switching_capability/max_lsp_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..29f30ca794c567238bb34de6d5de219f72b68cca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-restrictions + """ + from .label_restriction import LabelRestriction + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-restrictions + """ + + def __init__(self): + super().__init__(LabelRestrictions) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelRestrictions': + pass + + def __enter__(self) -> 'LabelRestrictions': + pass + + +class LabelRestrictions( + YANGContainer, + metaclass=LabelRestrictionsMeta): + """ + YANG container handler. + + YANG name: label-restrictions + """ + + _yang_name: Final[str] = 'label-restrictions' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'label-restriction': ( + label_restriction := ( # YANGListMember( + LabelRestrictionsMeta. + LabelRestriction. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestrictions': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..59861169cdfff61daccfdded5e79caf46694f7f1 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/__init__.py @@ -0,0 +1,129 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelRestrictionMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: label-restriction + """ + from .label_end import LabelEnd + from .label_start import LabelStart + from .label_step import LabelStep + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: label-restriction + """ + + def __init__(self): + super().__init__(LabelRestriction) + + def __get__(self, instance, owner=None) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['LabelRestriction']: + pass + + def __iter__(self, key) -> Iterator['LabelRestriction']: + return super().__iter__() + + def __getitem__(self, key) -> 'LabelRestriction': + return super()[key] + + def __enter__(self) -> ( + 'LabelRestrictionMeta.yang_list_descriptor'): + pass + + +class LabelRestriction( + YANGListItem, + metaclass=LabelRestrictionMeta): + """ + YANG list item handler. + + YANG name: label-restriction + """ + + _yang_name: Final[str] = 'label-restriction' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'range-bitmap': ( + range_bitmap := YANGLeafMember( + 'range-bitmap', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'restriction': ( + restriction := YANGLeafMember( + 'restriction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-end': ( + label_end := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelEnd. + yang_container_descriptor())), + + 'label-start': ( + label_start := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStart. + yang_container_descriptor())), + + 'label-step': ( + label_step := ( # YANGContainerMember( + LabelRestrictionMeta. + LabelStep. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelRestriction': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2ad525773e032b7b224f5b661e728ffe8950e98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelEndMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-end + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-end + """ + + def __init__(self): + super().__init__(LabelEnd) + + def __get__(self, instance, owner=None) -> ( + 'LabelEndMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelEnd': + pass + + def __enter__(self) -> 'LabelEnd': + pass + + +class LabelEnd( + YANGContainer, + metaclass=LabelEndMeta): + """ + YANG container handler. + + YANG name: label-end + """ + + _yang_name: Final[str] = 'label-end' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelEndMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelEnd': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_end/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8985523ba0c69fac8fbd1852bd47f2891d92bc6 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStartMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-start + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-start + """ + + def __init__(self): + super().__init__(LabelStart) + + def __get__(self, instance, owner=None) -> ( + 'LabelStartMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStart': + pass + + def __enter__(self) -> 'LabelStart': + pass + + +class LabelStart( + YANGContainer, + metaclass=LabelStartMeta): + """ + YANG container handler. + + YANG name: label-start + """ + + _yang_name: Final[str] = 'label-start' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelStartMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStart': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_start/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3aeed125a790da60e394f9e834fb871ab9c3b9 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelStepMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-step + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-step + """ + + def __init__(self): + super().__init__(LabelStep) + + def __get__(self, instance, owner=None) -> ( + 'LabelStepMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelStep': + pass + + def __enter__(self) -> 'LabelStep': + pass + + +class LabelStep( + YANGContainer, + metaclass=LabelStepMeta): + """ + YANG container handler. + + YANG name: label-step + """ + + _yang_name: Final[str] = 'label-step' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelStep': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + LabelStepMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + LabelStepMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/label_restrictions/label_restriction/label_step/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8dbcffdcef6a5a8e5db53b62fce3a3f123ea450f --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxLinkBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: max-link-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: max-link-bandwidth + """ + + def __init__(self): + super().__init__(MaxLinkBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxLinkBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MaxLinkBandwidth': + pass + + def __enter__(self) -> 'MaxLinkBandwidth': + pass + + +class MaxLinkBandwidth( + YANGContainer, + metaclass=MaxLinkBandwidthMeta): + """ + YANG container handler. + + YANG name: max-link-bandwidth + """ + + _yang_name: Final[str] = 'max-link-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxLinkBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxLinkBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_link_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..92e8cf6bf3d3ec018101b740c97d4721224527f7 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class MaxResvLinkBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: max-resv-link-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: max-resv-link-bandwidth + """ + + def __init__(self): + super().__init__(MaxResvLinkBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'MaxResvLinkBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'MaxResvLinkBandwidth': + pass + + def __enter__(self) -> 'MaxResvLinkBandwidth': + pass + + +class MaxResvLinkBandwidth( + YANGContainer, + metaclass=MaxResvLinkBandwidthMeta): + """ + YANG container handler. + + YANG name: max-resv-link-bandwidth + """ + + _yang_name: Final[str] = 'max-resv-link-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + MaxResvLinkBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'MaxResvLinkBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/max_resv_link_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/te_nsrlgs/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/te_nsrlgs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e5e97fc164047e8b36086ca3700f75d61848220c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/te_nsrlgs/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeNsrlgsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-nsrlgs + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-nsrlgs + """ + + def __init__(self): + super().__init__(TeNsrlgs) + + def __get__(self, instance, owner=None) -> ( + 'TeNsrlgsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeNsrlgs': + pass + + def __enter__(self) -> 'TeNsrlgs': + pass + + +class TeNsrlgs( + YANGContainer, + metaclass=TeNsrlgsMeta): + """ + YANG container handler. + + YANG name: te-nsrlgs + """ + + _yang_name: Final[str] = 'te-nsrlgs' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeNsrlgs': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/te_srlgs/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/te_srlgs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..561b31be827190ecd2cf49c88adb2118e8018b00 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/te_srlgs/__init__.py @@ -0,0 +1,79 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeSrlgsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-srlgs + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-srlgs + """ + + def __init__(self): + super().__init__(TeSrlgs) + + def __get__(self, instance, owner=None) -> ( + 'TeSrlgsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeSrlgs': + pass + + def __enter__(self) -> 'TeSrlgs': + pass + + +class TeSrlgs( + YANGContainer, + metaclass=TeSrlgsMeta): + """ + YANG container handler. + + YANG name: te-srlgs + """ + + _yang_name: Final[str] = 'te-srlgs' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeSrlgs': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9ef388cd63aa7c8947fc3391bad703bb01f3d827 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/__init__.py @@ -0,0 +1,119 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay + """ + from .primary_path import PrimaryPath + from .tunnel_termination_points import TunnelTerminationPoints + from .tunnels import Tunnels + from .backup_path import BackupPath + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay + """ + + def __init__(self): + super().__init__(Underlay) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Underlay': + pass + + def __enter__(self) -> 'Underlay': + pass + + +class Underlay( + YANGContainer, + metaclass=UnderlayMeta): + """ + YANG container handler. + + YANG name: underlay + """ + + _yang_name: Final[str] = 'underlay' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'enabled': ( + enabled := YANGLeafMember( + 'enabled', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'protection-type': ( + protection_type := YANGLeafMember( + 'protection-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'primary-path': ( + primary_path := ( # YANGContainerMember( + UnderlayMeta. + PrimaryPath. + yang_container_descriptor())), + + 'tunnel-termination-points': ( + tunnel_termination_points := ( # YANGContainerMember( + UnderlayMeta. + TunnelTerminationPoints. + yang_container_descriptor())), + + 'tunnels': ( + tunnels := ( # YANGContainerMember( + UnderlayMeta. + Tunnels. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'backup-path': ( + backup_path := ( # YANGListMember( + UnderlayMeta. + BackupPath. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Underlay': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6b6e1ff5cb9da5f8c265df0f8c0854de089ff9ef --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/__init__.py @@ -0,0 +1,109 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class BackupPathMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: backup-path + """ + from .path_element import PathElement + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: backup-path + """ + + def __init__(self): + super().__init__(BackupPath) + + def __get__(self, instance, owner=None) -> ( + 'BackupPathMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['BackupPath']: + pass + + def __iter__(self, key) -> Iterator['BackupPath']: + return super().__iter__() + + def __getitem__(self, key) -> 'BackupPath': + return super()[key] + + def __enter__(self) -> ( + 'BackupPathMeta.yang_list_descriptor'): + pass + + +class BackupPath( + YANGListItem, + metaclass=BackupPathMeta): + """ + YANG list item handler. + + YANG name: backup-path + """ + + _yang_name: Final[str] = 'backup-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'index', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'index': ( + index := YANGLeafMember( + 'index', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + BackupPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'BackupPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e16cb666ce1a7bc800b744b15e11b1d4b7279e6d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .as_number import AsNumber + from .label import Label + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .numbered_link_hop import NumberedLinkHop + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7fbc8696d952dbd4da8674d436ba19f95c93755d --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f2c993df52db1f2e1aa1085a57856c8585fcba58 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..088a2a9a5842516b7391cf36f8c90e94028a03d5 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/backup_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..34a2a729ce6d45e11174065699c428a7ac677a8b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PrimaryPathMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: primary-path + """ + from .path_element import PathElement + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: primary-path + """ + + def __init__(self): + super().__init__(PrimaryPath) + + def __get__(self, instance, owner=None) -> ( + 'PrimaryPathMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'PrimaryPath': + pass + + def __enter__(self) -> 'PrimaryPath': + pass + + +class PrimaryPath( + YANGContainer, + metaclass=PrimaryPathMeta): + """ + YANG container handler. + + YANG name: primary-path + """ + + _yang_name: Final[str] = 'primary-path' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'path-element': ( + path_element := ( # YANGListMember( + PrimaryPathMeta. + PathElement. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PrimaryPath': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a0625d0a7e1ed45c21fef726919e7abb0df --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/__init__.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class PathElementMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: path-element + """ + from .type import Type + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: path-element + """ + + def __init__(self): + super().__init__(PathElement) + + def __get__(self, instance, owner=None) -> ( + 'PathElementMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['PathElement']: + pass + + def __iter__(self, key) -> Iterator['PathElement']: + return super().__iter__() + + def __getitem__(self, key) -> 'PathElement': + return super()[key] + + def __enter__(self) -> ( + 'PathElementMeta.yang_list_descriptor'): + pass + + +class PathElement( + YANGListItem, + metaclass=PathElementMeta): + """ + YANG list item handler. + + YANG name: path-element + """ + + _yang_name: Final[str] = 'path-element' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'path-element-id', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'path-element-id': ( + path_element_id := YANGLeafMember( + 'path-element-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'PathElement': + instance = super().__new__(cls) + instance._yang_choices = { + + 'type': + PathElementMeta.Type( + instance), + } + return instance + + @property + def type(self) -> ( + PathElementMeta.Type): + return self._yang_choices['type'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..82e2d504aaeb513b94637bc327bfe2492f2f2447 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/__init__.py @@ -0,0 +1,188 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TypeMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: type + """ + + from .numbered_node_hop import NumberedNodeHop + from .unnumbered_link_hop import UnnumberedLinkHop + from .as_number import AsNumber + from .numbered_link_hop import NumberedLinkHop + from .label import Label + + class numbered_node_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_node_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedNodeHop'): + pass + + class unnumbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.unnumbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.UnnumberedLinkHop'): + pass + + class as_number_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__( + TypeMeta.AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.as_number_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + def __enter__(self) -> ( + 'TypeMeta.AsNumber'): + pass + + class numbered_link_hop_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__( + TypeMeta.NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.numbered_link_hop_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + def __enter__(self) -> ( + 'TypeMeta.NumberedLinkHop'): + pass + + class label_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__( + TypeMeta.Label) + + def __get__(self, instance, owner=None) -> ( + 'TypeMeta.label_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TypeMeta.Label'): + pass + + def __enter__(self) -> ( + 'TypeMeta.Label'): + pass + + +class Type(YANGChoice, metaclass=TypeMeta): + """ + YANG choice handler. + + YANG name: type + """ + + _yang_name: Final[str] = 'type' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_node_hop_case_descriptor())), + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + unnumbered_link_hop_case_descriptor())), + + 'as-number': ( + as_number := ( # YANGChoiceCase( + TypeMeta. + as_number_case_descriptor())), + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGChoiceCase( + TypeMeta. + numbered_link_hop_case_descriptor())), + + 'label': ( + label := ( # YANGChoiceCase( + TypeMeta. + label_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/as_number/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/as_number/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a9e6397e1378c9d49d0720f95118a7bc09d8d589 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/as_number/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number + """ + from .as_number_hop import AsNumberHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number + """ + + def __init__(self): + super().__init__(AsNumber) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumber': + pass + + def __enter__(self) -> 'AsNumber': + pass + + +class AsNumber( + YANGContainer, + metaclass=AsNumberMeta): + """ + YANG container handler. + + YANG name: as-number + """ + + _yang_name: Final[str] = 'as-number' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'as-number-hop': ( + as_number_hop := ( # YANGContainerMember( + AsNumberMeta. + AsNumberHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumber': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3d4d7cc089c766991270dfdd2f888bff8b38bb49 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/as_number/as_number_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class AsNumberHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: as-number-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: as-number-hop + """ + + def __init__(self): + super().__init__(AsNumberHop) + + def __get__(self, instance, owner=None) -> ( + 'AsNumberHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'AsNumberHop': + pass + + def __enter__(self) -> 'AsNumberHop': + pass + + +class AsNumberHop( + YANGContainer, + metaclass=AsNumberHopMeta): + """ + YANG container handler. + + YANG name: as-number-hop + """ + + _yang_name: Final[str] = 'as-number-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'as-number': ( + as_number := YANGLeafMember( + 'as-number', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'AsNumberHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d584796ce0d9f70bed72da335de382683781da --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label + """ + from .label_hop import LabelHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label + """ + + def __init__(self): + super().__init__(Label) + + def __get__(self, instance, owner=None) -> ( + 'LabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Label': + pass + + def __enter__(self) -> 'Label': + pass + + +class Label( + YANGContainer, + metaclass=LabelMeta): + """ + YANG container handler. + + YANG name: label + """ + + _yang_name: Final[str] = 'label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'label-hop': ( + label_hop := ( # YANGContainerMember( + LabelMeta. + LabelHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Label': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2203b992611860dfd058f330ff7fd5f4d751e43c --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class LabelHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: label-hop + """ + from .te_label import TeLabel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: label-hop + """ + + def __init__(self): + super().__init__(LabelHop) + + def __get__(self, instance, owner=None) -> ( + 'LabelHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'LabelHop': + pass + + def __enter__(self) -> 'LabelHop': + pass + + +class LabelHop( + YANGContainer, + metaclass=LabelHopMeta): + """ + YANG container handler. + + YANG name: label-hop + """ + + _yang_name: Final[str] = 'label-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-label': ( + te_label := ( # YANGContainerMember( + LabelHopMeta. + TeLabel. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'LabelHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf308375db86584b3adcea9d5c6d782f2307e12 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/__init__.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeLabelMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-label + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-label + """ + + def __init__(self): + super().__init__(TeLabel) + + def __get__(self, instance, owner=None) -> ( + 'TeLabelMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeLabel': + pass + + def __enter__(self) -> 'TeLabel': + pass + + +class TeLabel( + YANGContainer, + metaclass=TeLabelMeta): + """ + YANG container handler. + + YANG name: te-label + """ + + _yang_name: Final[str] = 'te-label' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeLabel': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeLabelMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeLabelMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/label/label_hop/te_label/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75b0008fe318c4c34997b7532696828e42b85abf --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + from .numbered_link_hop import NumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-link-hop': ( + numbered_link_hop := ( # YANGContainerMember( + NumberedLinkHopMeta. + NumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1abedb4d3f8145943387f3e66e3e17fed741dcdc --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_link_hop/numbered_link_hop/__init__.py @@ -0,0 +1,97 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-link-hop + """ + + def __init__(self): + super().__init__(NumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedLinkHop': + pass + + def __enter__(self) -> 'NumberedLinkHop': + pass + + +class NumberedLinkHop( + YANGContainer, + metaclass=NumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: numbered-link-hop + """ + + _yang_name: Final[str] = 'numbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f0ceac062e9d2ce79e6681b5f812cb2adae4a9ca --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + from .numbered_node_hop import NumberedNodeHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'numbered-node-hop': ( + numbered_node_hop := ( # YANGContainerMember( + NumberedNodeHopMeta. + NumberedNodeHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8413f9714b640282ccc3b07327104536c117b38 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/numbered_node_hop/numbered_node_hop/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NumberedNodeHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: numbered-node-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: numbered-node-hop + """ + + def __init__(self): + super().__init__(NumberedNodeHop) + + def __get__(self, instance, owner=None) -> ( + 'NumberedNodeHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'NumberedNodeHop': + pass + + def __enter__(self) -> 'NumberedNodeHop': + pass + + +class NumberedNodeHop( + YANGContainer, + metaclass=NumberedNodeHopMeta): + """ + YANG container handler. + + YANG name: numbered-node-hop + """ + + _yang_name: Final[str] = 'numbered-node-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NumberedNodeHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..18213797fc567b08150fc431ac7611ef32d54622 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/__init__.py @@ -0,0 +1,86 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + from .unnumbered_link_hop import UnnumberedLinkHop + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'unnumbered-link-hop': ( + unnumbered_link_hop := ( # YANGContainerMember( + UnnumberedLinkHopMeta. + UnnumberedLinkHop. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8ee74a2b7c7f647d2a88dfb22f44ed0ec1e80e4 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/primary_path/path_element/type/unnumbered_link_hop/unnumbered_link_hop/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnnumberedLinkHopMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: unnumbered-link-hop + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: unnumbered-link-hop + """ + + def __init__(self): + super().__init__(UnnumberedLinkHop) + + def __get__(self, instance, owner=None) -> ( + 'UnnumberedLinkHopMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnnumberedLinkHop': + pass + + def __enter__(self) -> 'UnnumberedLinkHop': + pass + + +class UnnumberedLinkHop( + YANGContainer, + metaclass=UnnumberedLinkHopMeta): + """ + YANG container handler. + + YANG name: unnumbered-link-hop + """ + + _yang_name: Final[str] = 'unnumbered-link-hop' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'direction': ( + direction := YANGLeafMember( + 'direction', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'hop-type': ( + hop_type := YANGLeafMember( + 'hop-type', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'link-tp-id': ( + link_tp_id := YANGLeafMember( + 'link-tp-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'node-id': ( + node_id := YANGLeafMember( + 'node-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnnumberedLinkHop': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnel_termination_points/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnel_termination_points/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c5cccf39482c3497e05c1c7ab8f4fdd3e2d7490b --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnel_termination_points/__init__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelTerminationPointsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnel-termination-points + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnel-termination-points + """ + + def __init__(self): + super().__init__(TunnelTerminationPoints) + + def __get__(self, instance, owner=None) -> ( + 'TunnelTerminationPointsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TunnelTerminationPoints': + pass + + def __enter__(self) -> 'TunnelTerminationPoints': + pass + + +class TunnelTerminationPoints( + YANGContainer, + metaclass=TunnelTerminationPointsMeta): + """ + YANG container handler. + + YANG name: tunnel-termination-points + """ + + _yang_name: Final[str] = 'tunnel-termination-points' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'destination': ( + destination := YANGLeafMember( + 'destination', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'source': ( + source := YANGLeafMember( + 'source', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TunnelTerminationPoints': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnels/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..303858f3e0c28faecf9696d2fbf403d5510cced8 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnels/__init__.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelsMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: tunnels + """ + from .tunnel import Tunnel + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: tunnels + """ + + def __init__(self): + super().__init__(Tunnels) + + def __get__(self, instance, owner=None) -> ( + 'TunnelsMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Tunnels': + pass + + def __enter__(self) -> 'Tunnels': + pass + + +class Tunnels( + YANGContainer, + metaclass=TunnelsMeta): + """ + YANG container handler. + + YANG name: tunnels + """ + + _yang_name: Final[str] = 'tunnels' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + + 'tunnel': ( + tunnel := ( # YANGListMember( + TunnelsMeta. + Tunnel. + yang_list_descriptor())), + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnels': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnels/tunnel/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnels/tunnel/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f854dfd329ce016317b7b9743ace874769f03094 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/underlay/tunnels/tunnel/__init__.py @@ -0,0 +1,102 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TunnelMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: tunnel + """ + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: tunnel + """ + + def __init__(self): + super().__init__(Tunnel) + + def __get__(self, instance, owner=None) -> ( + 'TunnelMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['Tunnel']: + pass + + def __iter__(self, key) -> Iterator['Tunnel']: + return super().__iter__() + + def __getitem__(self, key) -> 'Tunnel': + return super()[key] + + def __enter__(self) -> ( + 'TunnelMeta.yang_list_descriptor'): + pass + + +class Tunnel( + YANGListItem, + metaclass=TunnelMeta): + """ + YANG list item handler. + + YANG name: tunnel + """ + + _yang_name: Final[str] = 'tunnel' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'tunnel-name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'sharing': ( + sharing := YANGLeafMember( + 'sharing', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'tunnel-name': ( + tunnel_name := YANGLeafMember( + 'tunnel-name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Tunnel': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fd4e9d8a913ee8fb4ba711c3d10310583ea16711 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/__init__.py @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnreservedBandwidthMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: unreserved-bandwidth + """ + from .te_bandwidth import TeBandwidth + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: unreserved-bandwidth + """ + + def __init__(self): + super().__init__(UnreservedBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'UnreservedBandwidthMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['UnreservedBandwidth']: + pass + + def __iter__(self, key) -> Iterator['UnreservedBandwidth']: + return super().__iter__() + + def __getitem__(self, key) -> 'UnreservedBandwidth': + return super()[key] + + def __enter__(self) -> ( + 'UnreservedBandwidthMeta.yang_list_descriptor'): + pass + + +class UnreservedBandwidth( + YANGListItem, + metaclass=UnreservedBandwidthMeta): + """ + YANG list item handler. + + YANG name: unreserved-bandwidth + """ + + _yang_name: Final[str] = 'unreserved-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'priority', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-bandwidth': ( + te_bandwidth := ( # YANGContainerMember( + UnreservedBandwidthMeta. + TeBandwidth. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnreservedBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..21c93df9e732a17da394efda2c59b6166de1374a --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/__init__.py @@ -0,0 +1,89 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeBandwidthMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-bandwidth + """ + from .technology import Technology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-bandwidth + """ + + def __init__(self): + super().__init__(TeBandwidth) + + def __get__(self, instance, owner=None) -> ( + 'TeBandwidthMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeBandwidth': + pass + + def __enter__(self) -> 'TeBandwidth': + pass + + +class TeBandwidth( + YANGContainer, + metaclass=TeBandwidthMeta): + """ + YANG container handler. + + YANG name: te-bandwidth + """ + + _yang_name: Final[str] = 'te-bandwidth' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeBandwidth': + instance = super().__new__(cls) + instance._yang_choices = { + + 'technology': + TeBandwidthMeta.Technology( + instance), + } + return instance + + @property + def technology(self) -> ( + TeBandwidthMeta.Technology): + return self._yang_choices['technology'] diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c35cb35140e0059a8596a975e71e1cfa92c717 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/__init__.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TechnologyMeta(type): + """ + Metaclass for YANG choice handler. + + YANG name: technology + """ + + from .generic import Generic + + class generic_case_descriptor(YANGChoiceCase): + """ + YANG choice case descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__( + TechnologyMeta.Generic) + + def __get__(self, instance, owner=None) -> ( + 'TechnologyMeta.generic_case_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + def __enter__(self) -> ( + 'TechnologyMeta.Generic'): + pass + + +class Technology(YANGChoice, metaclass=TechnologyMeta): + """ + YANG choice handler. + + YANG name: technology + """ + + _yang_name: Final[str] = 'technology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_cases: Final[Dict[str, YANGChoiceCase]] = { + + 'generic': ( + generic := ( # YANGChoiceCase( + TechnologyMeta. + generic_case_descriptor())), + } diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..81dce6de335c51cb366c8fa8c6fe4d53dbad586e --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/link_template/te_link_attributes/unreserved_bandwidth/te_bandwidth/technology/generic/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class GenericMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: generic + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: generic + """ + + def __init__(self): + super().__init__(Generic) + + def __get__(self, instance, owner=None) -> ( + 'GenericMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'Generic': + pass + + def __enter__(self) -> 'Generic': + pass + + +class Generic( + YANGContainer, + metaclass=GenericMeta): + """ + YANG container handler. + + YANG name: generic + """ + + _yang_name: Final[str] = 'generic' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'generic': ( + generic := YANGLeafMember( + 'generic', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'Generic': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b2973312bf2c09a332f8dc3751bd797b11115c98 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final, Iterator, List, Tuple + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class NodeTemplateMeta(type): + """ + Metaclass for YANG list item handler. + + YANG name: node-template + """ + from .te_node_attributes import TeNodeAttributes + + class yang_list_descriptor( + YANGListMember): + """ + YANG list descriptor class. + + YANG name: node-template + """ + + def __init__(self): + super().__init__(NodeTemplate) + + def __get__(self, instance, owner=None) -> ( + 'NodeTemplateMeta.yang_list_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> List['NodeTemplate']: + pass + + def __iter__(self, key) -> Iterator['NodeTemplate']: + return super().__iter__() + + def __getitem__(self, key) -> 'NodeTemplate': + return super()[key] + + def __enter__(self) -> ( + 'NodeTemplateMeta.yang_list_descriptor'): + pass + + +class NodeTemplate( + YANGListItem, + metaclass=NodeTemplateMeta): + """ + YANG list item handler. + + YANG name: node-template + """ + + _yang_name: Final[str] = 'node-template' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_list_key_names: Final[Tuple[str]] = ( + 'name', + ) + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'reference-change-policy': ( + reference_change_policy := YANGLeafMember( + 'reference-change-policy', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'priority': ( + priority := YANGLeafMember( + 'priority', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'te-node-attributes': ( + te_node_attributes := ( # YANGContainerMember( + NodeTemplateMeta. + TeNodeAttributes. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'NodeTemplate': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/te_node_attributes/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/te_node_attributes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d33037182fea0bb3aaf9c33036500240c54c6058 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/te_node_attributes/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class TeNodeAttributesMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: te-node-attributes + """ + from .underlay_topology import UnderlayTopology + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: te-node-attributes + """ + + def __init__(self): + super().__init__(TeNodeAttributes) + + def __get__(self, instance, owner=None) -> ( + 'TeNodeAttributesMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'TeNodeAttributes': + pass + + def __enter__(self) -> 'TeNodeAttributes': + pass + + +class TeNodeAttributes( + YANGContainer, + metaclass=TeNodeAttributesMeta): + """ + YANG container handler. + + YANG name: te-node-attributes + """ + + _yang_name: Final[str] = 'te-node-attributes' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'name': ( + name := YANGLeafMember( + 'name', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'is-abstract': ( + is_abstract := YANGLeafMember( + 'is-abstract', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'domain-id': ( + domain_id := YANGLeafMember( + 'domain-id', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + + 'admin-status': ( + admin_status := YANGLeafMember( + 'admin-status', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + + 'underlay-topology': ( + underlay_topology := ( # YANGContainerMember( + TeNodeAttributesMeta. + UnderlayTopology. + yang_container_descriptor())), + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'TeNodeAttributes': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/te_node_attributes/underlay_topology/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/te_node_attributes/underlay_topology/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42dee7a72fe4a5d79128cf6ad278af68094e6692 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/bindings/networks/te/templates/node_template/te_node_attributes/underlay_topology/__init__.py @@ -0,0 +1,85 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Final + +from .. import ( + YANGChoice, YANGChoiceCase, YANGContainer, YANGContainerMember, + YANGLeafMember, YANGListItem, YANGListMember) + + +class UnderlayTopologyMeta(type): + """ + Metaclass for YANG container handler. + + YANG name: underlay-topology + """ + + class yang_container_descriptor( + YANGContainerMember): + """ + YANG container descriptor class. + + YANG name: underlay-topology + """ + + def __init__(self): + super().__init__(UnderlayTopology) + + def __get__(self, instance, owner=None) -> ( + 'UnderlayTopologyMeta.yang_container_descriptor'): + return super().__get__(instance, owner) + + def __call__(self) -> 'UnderlayTopology': + pass + + def __enter__(self) -> 'UnderlayTopology': + pass + + +class UnderlayTopology( + YANGContainer, + metaclass=UnderlayTopologyMeta): + """ + YANG container handler. + + YANG name: underlay-topology + """ + + _yang_name: Final[str] = 'underlay-topology' + _yang_namespace: Final[str] = 'urn:ietf:params:xml:ns:yang:ietf-te-topology' + _yang_module_name: Final[str] = 'ietf-te-topology' + + _yang_leaf_members: Final[Dict[str, YANGLeafMember]] = { + + 'network-ref': ( + network_ref := YANGLeafMember( + 'network-ref', + 'urn:ietf:params:xml:ns:yang:ietf-te-topology', + 'ietf-te-topology')), + } + + _yang_container_members: Final[Dict[str, YANGContainerMember]] = { + } + + _yang_list_members: Final[Dict[str, YANGListMember]] = { + } + + _yang_choices: Final[Dict[str, YANGChoice]] = None + + def __new__(cls, *args, **kwargs) -> 'UnderlayTopology': + instance = super().__new__(cls) + instance._yang_choices = { + } + return instance diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt new file mode 100644 index 0000000000000000000000000000000000000000..b81498dd8aa94457e2658cc29586de66242ae391 --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ietf-network-slice-service.txt @@ -0,0 +1,261 @@ +# IETF draft-ietf-teas-ietf-network-slice-nbi-yang-02 - IETF Network Slice Service YANG Model +# Ref: https://datatracker.ietf.org/doc/draft-ietf-teas-ietf-network-slice-nbi-yang/ + +module: ietf-network-slice-service + +--rw network-slice-services + +--rw slo-sle-templates + | +--rw slo-sle-template* [id] + | +--rw id string + | +--rw template-description? string + +--rw slice-service* [service-id] + +--rw service-id string + +--rw service-description? string + +--rw service-tags + | +--rw tag-type* [tag-type] + | | +--rw tag-type identityref + | | +--rw value* string + | +--rw tag-opaque* [tag-name] + | +--rw tag-name string + | +--rw value* string + +--rw (slo-sle-policy)? + | +--:(standard) + | | +--rw slo-sle-template? leafref + | +--:(custom) + | +--rw service-slo-sle-policy + | +--rw policy-description? string + | +--rw metric-bounds + | | +--rw metric-bound* [metric-type] + | | +--rw metric-type identityref + | | +--rw metric-unit string + | | +--rw value-description? string + | | +--rw bound? uint64 + | +--rw security* identityref + | +--rw isolation? identityref + | +--rw max-occupancy-level? uint8 + | +--rw mtu? uint16 + | +--rw steering-constraints + | +--rw path-constraints + | +--rw service-function + +--rw status + | +--rw admin-status + | | +--rw status? identityref + | | +--rw last-updated? yang:date-and-time + | +--ro oper-status + | +--ro status? identityref + | +--ro last-updated? yang:date-and-time + +--rw sdps + | +--rw sdp* [sdp-id] + | +--rw sdp-id string + | +--rw sdp-description? string + | +--rw location + | | +--rw altitude? int64 + | | +--rw latitude? decimal64 + | | +--rw longitude? decimal64 + | +--rw node-id? string + | +--rw sdp-ip? inet:ip-address + | +--rw service-match-criteria + | | +--rw match-criterion* [index] + | | +--rw index uint32 + | | +--rw match-type + | | | identityref + | | +--rw value* string + | | +--rw target-connection-group-id leafref + | | +--rw connection-group-sdp-role? + | | | identityref + | | +--rw target-connectivity-construct-id? leafref + | +--rw sdp-peering + | | +--rw protocol* [protocol-type] + | | | +--rw protocol-type identityref + | | | +--rw attribute* [attribute-type] + | | | +--rw attribute-type identityref + | | | +--rw value* string + | | +--rw opaque* [attribute-name] + | | +--rw attribute-name string + | | +--rw value* string + | +--rw attachment-circuits + | | +--rw attachment-circuit* [ac-id] + | | +--rw ac-id string + | | +--rw ac-description? string + | | +--rw ac-node-id? string + | | +--rw ac-tp-id? string + | | +--rw ac-ip-address? inet:ip-address + | | +--rw ac-ip-prefix-length? uint8 + | | +--rw ac-qos-policy-name? string + | | +--rw mtu? uint16 + | | +--rw ac-tags + | | | +--rw ac-tags* [ac-tag-type] + | | | | +--rw ac-tag-type identityref + | | | | +--rw value* string + | | | +--rw ac-tag-opaque* [tag-name] + | | | +--rw tag-name string + | | | +--rw value* string + | | +--rw service-match-criteria + | | | +--rw match-criterion* [index] + | | | +--rw index + | | | | uint32 + | | | +--rw match-type + | | | | identityref + | | | +--rw value* + | | | | string + | | | +--rw target-connection-group-id leafref + | | | +--rw connection-group-sdp-role? + | | | | identityref + | | | +--rw target-connectivity-construct-id? leafref + | | +--rw sdp-peering + | | | +--rw protocol* [protocol-type] + | | | | +--rw protocol-type identityref + | | | | +--rw attribute* [attribute-type] + | | | | +--rw attribute-type identityref + | | | | +--rw value* string + | | | +--rw opaque* [attribute-name] + | | | +--rw attribute-name string + | | | +--rw value* string + | | +--rw incoming-rate-limits + | | | +--rw cir? uint64 + | | | +--rw cbs? uint64 + | | | +--rw eir? uint64 + | | | +--rw ebs? uint64 + | | | +--rw pir? uint64 + | | | +--rw pbs? uint64 + | | +--rw outgoing-rate-limits + | | +--rw cir? uint64 + | | +--rw cbs? uint64 + | | +--rw eir? uint64 + | | +--rw ebs? uint64 + | | +--rw pir? uint64 + | | +--rw pbs? uint64 + | +--rw incoming-rate-limits + | | +--rw cir? uint64 + | | +--rw cbs? uint64 + | | +--rw eir? uint64 + | | +--rw ebs? uint64 + | | +--rw pir? uint64 + | | +--rw pbs? uint64 + | +--rw outgoing-rate-limits + | | +--rw cir? uint64 + | | +--rw cbs? uint64 + | | +--rw eir? uint64 + | | +--rw ebs? uint64 + | | +--rw pir? uint64 + | | +--rw pbs? uint64 + | +--rw status + | | +--rw admin-status + | | | +--rw status? identityref + | | | +--rw last-updated? yang:date-and-time + | | +--ro oper-status + | | +--ro status? identityref + | | +--ro last-updated? yang:date-and-time + | +--ro sdp-monitoring + | +--ro incoming-utilized-bandwidth? + | | te-types:te-bandwidth + | +--ro incoming-bw-utilization decimal64 + | +--ro outgoing-utilized-bandwidth? + | | te-types:te-bandwidth + | +--ro outgoing-bw-utilization decimal64 + +--rw connection-groups + +--rw connection-group* [connection-group-id] + +--rw connection-group-id string + +--rw connectivity-type? identityref + +--rw (slo-sle-policy)? + | +--:(standard) + | | +--rw slo-sle-template? leafref + | +--:(custom) + | +--rw service-slo-sle-policy + | +--rw policy-description? string + | +--rw metric-bounds + | | +--rw metric-bound* [metric-type] + | | +--rw metric-type identityref + | | +--rw metric-unit string + | | +--rw value-description? string + | | +--rw bound? uint64 + | +--rw security* identityref + | +--rw isolation? identityref + | +--rw max-occupancy-level? uint8 + | +--rw mtu? uint16 + | +--rw steering-constraints + | +--rw path-constraints + | +--rw service-function + +--rw connectivity-construct* [cc-id] + | +--rw cc-id uint32 + | +--rw (connectivity-construct-type)? + | | +--:(p2p) + | | | +--rw p2p-sender-sdp? + | | | | -> ../../../../sdps/sdp/sdp-id + | | | +--rw p2p-receiver-sdp? + | | | -> ../../../../sdps/sdp/sdp-id + | | +--:(p2mp) + | | | +--rw p2mp-sender-sdp? + | | | | -> ../../../../sdps/sdp/sdp-id + | | | +--rw p2mp-receiver-sdp* + | | | -> ../../../../sdps/sdp/sdp-id + | | +--:(a2a) + | | +--rw a2a-sdp* [sdp-id] + | | +--rw sdp-id + | | | -> ../../../../../sdps/sdp/sdp-id + | | +--rw (slo-sle-policy)? + | | +--:(standard) + | | | +--rw slo-sle-template? leafref + | | +--:(custom) + | | +--rw service-slo-sle-policy + | | +--rw policy-description? + | | | string + | | +--rw metric-bounds + | | | +--rw metric-bound* + | | | [metric-type] + | | | +--rw metric-type + | | | | identityref + | | | +--rw metric-unit + | | | | string + | | | +--rw value-description? + | | | | string + | | | +--rw bound? + | | | uint64 + | | +--rw security* + | | | identityref + | | +--rw isolation? + | | | identityref + | | +--rw max-occupancy-level? + | | | uint8 + | | +--rw mtu? + | | | uint16 + | | +--rw steering-constraints + | | +--rw path-constraints + | | +--rw service-function + | +--rw (slo-sle-policy)? + | | +--:(standard) + | | | +--rw slo-sle-template? leafref + | | +--:(custom) + | | +--rw service-slo-sle-policy + | | +--rw policy-description? string + | | +--rw metric-bounds + | | | +--rw metric-bound* [metric-type] + | | | +--rw metric-type + | | | | identityref + | | | +--rw metric-unit string + | | | +--rw value-description? string + | | | +--rw bound? uint64 + | | +--rw security* identityref + | | +--rw isolation? identityref + | | +--rw max-occupancy-level? uint8 + | | +--rw mtu? uint16 + | | +--rw steering-constraints + | | +--rw path-constraints + | | +--rw service-function + | +--ro connectivity-construct-monitoring + | +--ro one-way-min-delay? uint32 + | +--ro one-way-max-delay? uint32 + | +--ro one-way-delay-variation? uint32 + | +--ro one-way-packet-loss? decimal64 + | +--ro two-way-min-delay? uint32 + | +--ro two-way-max-delay? uint32 + | +--ro two-way-delay-variation? uint32 + | +--ro two-way-packet-loss? decimal64 + +--ro connection-group-monitoring + +--ro one-way-min-delay? uint32 + +--ro one-way-max-delay? uint32 + +--ro one-way-delay-variation? uint32 + +--ro one-way-packet-loss? decimal64 + +--ro two-way-min-delay? uint32 + +--ro two-way-max-delay? uint32 + +--ro two-way-delay-variation? uint32 + +--ro two-way-packet-loss? decimal64 \ No newline at end of file diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ofc23_batch_slices.py b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ofc23_batch_slices.py new file mode 100644 index 0000000000000000000000000000000000000000..c38d75d063374b896ce6767c035175df8774c8ff --- /dev/null +++ b/src/compute/service/rest_server/nbi_plugins/ietf_network_slice/ofc23_batch_slices.py @@ -0,0 +1,158 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json +import random +import uuid +import sys +import time +import requests + +from bindings.network_slice_services import NetworkSliceServices + + +# R1 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R1_UUID = "ed2388eb-5fb9-5888-a4f4-160267d3e19b" +R1_PORT_13_0_UUID_OPTICAL = "20440915-1a6c-5e7b-a80f-b0e0e51f066d" +R1_PORT_13_1_UUID_COPPER = "ff900d5d-2ac0-576c-9628-a2d016681f9d" + +# R2 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R2_UUID = "49ce0312-1274-523b-97b8-24d0eca2d72d" +R2_PORT_13_0_UUID_OPTICAL = "214618cb-b63b-5e66-84c2-45c1c016e5f0" +R2_PORT_13_1_UUID_COPPER = "4e0f7fb4-5d22-56ad-a00e-20bffb4860f9" + +# R3 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R3_UUID = "3bc8e994-a3b9-5f60-9c77-6608b1d08313" +R3_PORT_13_0_UUID_OPTICAL = "da5196f5-d651-5def-ada6-50ed6430279d" +R3_PORT_13_1_UUID_COPPER = "43d221fa-5701-5740-a129-502131f5bda2" + +# R4 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R4_UUID = "b43e6361-2573-509d-9a88-1793e751b10d" +R4_PORT_13_0_UUID_OPTICAL = "241b74a7-8677-595c-ad65-cc9093c1e341" +R4_PORT_13_1_UUID_COPPER = "c57abf46-caaf-5954-90cc-1fec0a69330e" + +node_dict = {R1_PORT_13_1_UUID_COPPER: R1_UUID, + R2_PORT_13_1_UUID_COPPER: R2_UUID, + R3_PORT_13_1_UUID_COPPER: R3_UUID, + R4_PORT_13_1_UUID_COPPER: R4_UUID} +list_endpoints = [R1_PORT_13_1_UUID_COPPER, + R2_PORT_13_1_UUID_COPPER, + R3_PORT_13_1_UUID_COPPER, + R4_PORT_13_1_UUID_COPPER] + +list_availability= [99, 99.9, 99.99, 99.999, 99.9999] +list_bw = [10, 40, 50, 100, 150, 200, 400] +list_owner = ["Telefonica", "CTTC", "Telenor", "ADVA", "Ubitech", "ATOS"] + +URL_POST = "/restconf/data/ietf-network-slice-service:ietf-nss/network-slice-services" +URL_DELETE = "/restconf/data/ietf-network-slice-service:ietf-nss/network-slice-services/slice-service=" + +def generate_request(seed: str) -> (dict, str): + + ns = NetworkSliceServices() + + # Slice 1 + suuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, str(seed))) + slice1 = ns.slice_service[suuid] + slice1.service_description = "Test slice for OFC 2023 demo" + slice1.status().admin_status().status = "Planned" # TODO not yet mapped + + ''' + SDPS: + R1 optical to R3 optical + ''' + sdps1 = slice1.sdps().sdp + while True: + ep1_uuid = random.choice(list_endpoints) + ep2_uuid = random.choice(list_endpoints) + if ep1_uuid != ep2_uuid: + break + + sdps1[ep1_uuid].node_id = node_dict.get(ep1_uuid) + sdps1[ep2_uuid].node_id = node_dict.get(ep2_uuid) + + ''' + Connectivity group + Connection construct and 2 sla constrains: + - Bandwidth + - Availability + ''' + cg_uuid = str(uuid.uuid4()) + cg = slice1.connection_groups().connection_group + cg1 = cg[cg_uuid] + + cc1 = cg1.connectivity_construct[0] + cc1.cc_id = 5 + p2p = cc1.connectivity_construct_type.p2p() + p2p.p2p_sender_sdp = ep1_uuid + p2p.p2p_receiver_sdp = ep2_uuid + + slo_custom = cc1.slo_sle_policy.custom() + metric_bounds = slo_custom.service_slo_sle_policy().metric_bounds().metric_bound + + # SLO Bandwidth + slo_bandwidth = metric_bounds["service-slo-two-way-bandwidth"] + slo_bandwidth.value_description = "Guaranteed bandwidth" + slo_bandwidth.bound = int(random.choice(list_bw)) + slo_bandwidth.metric_unit = "Gbps" + + # SLO Availability + slo_availability = metric_bounds["service-slo-availability"] + slo_availability.value_description = "Guaranteed availability" + slo_availability.metric_unit = "percentage" + slo_availability.bound = random.choice(list_availability) + + json_request = {"data": ns.to_json()} + + #Last, add name and owner manually + list_name_owner = [{"tag-type": "owner", "value": random.choice(list_owner)}] + json_request["data"]["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["service-tags"] = list_name_owner + + return (json_request, suuid) + + +if __name__ == "__main__": + print("Generating requests...") + num = int(sys.argv[2]) + ip = str(sys.argv[1]) + list_requests = [] + + for i in range(num): + request = generate_request(i) + list_requests.append(request) + print(f"HTTP.POST={request[0]}-{request[1]}") + time.sleep(2) + requests.post(f"http://{ip}{URL_POST}", auth=("admin", "admin"), json=request[0]) + + print("Slices sent, please press Enter key to delete them...") + input() + + for request,suuid in list_requests: + requests.delete(f"http://{ip}{URL_DELETE}{suuid}", auth=("admin", "admin")) + print(f"HTTP.DELETE={suuid}") + time.sleep(2) + print("All slices deleted!") + + + + + diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Authentication.py b/src/compute/service/rest_server/nbi_plugins/tools/Authentication.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Authentication.py rename to src/compute/service/rest_server/nbi_plugins/tools/Authentication.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/HttpStatusCodes.py b/src/compute/service/rest_server/nbi_plugins/tools/HttpStatusCodes.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/HttpStatusCodes.py rename to src/compute/service/rest_server/nbi_plugins/tools/HttpStatusCodes.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Validator.py b/src/compute/service/rest_server/nbi_plugins/tools/Validator.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/Validator.py rename to src/compute/service/rest_server/nbi_plugins/tools/Validator.py diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/__init__.py b/src/compute/service/rest_server/nbi_plugins/tools/__init__.py similarity index 100% rename from src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/__init__.py rename to src/compute/service/rest_server/nbi_plugins/tools/__init__.py diff --git a/src/compute/tests/test_slice.py b/src/compute/tests/test_slice.py new file mode 100644 index 0000000000000000000000000000000000000000..61f286eb74a876fa02546fc2bf1dcd8f092e718a --- /dev/null +++ b/src/compute/tests/test_slice.py @@ -0,0 +1,125 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json, random, uuid +from typing import Dict, Tuple +from compute.service.rest_server.nbi_plugins.ietf_network_slice.bindings.network_slice_services import ( + NetworkSliceServices +) + +# R1 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R1_UUID = "ed2388eb-5fb9-5888-a4f4-160267d3e19b" +R1_PORT_13_0_UUID_OPTICAL = "20440915-1a6c-5e7b-a80f-b0e0e51f066d" +R1_PORT_13_1_UUID_COPPER = "ff900d5d-2ac0-576c-9628-a2d016681f9d" + +# R2 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R2_UUID = "49ce0312-1274-523b-97b8-24d0eca2d72d" +R2_PORT_13_0_UUID_OPTICAL = "214618cb-b63b-5e66-84c2-45c1c016e5f0" +R2_PORT_13_1_UUID_COPPER = "4e0f7fb4-5d22-56ad-a00e-20bffb4860f9" + +# R3 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R3_UUID = "3bc8e994-a3b9-5f60-9c77-6608b1d08313" +R3_PORT_13_0_UUID_OPTICAL = "da5196f5-d651-5def-ada6-50ed6430279d" +R3_PORT_13_1_UUID_COPPER = "43d221fa-5701-5740-a129-502131f5bda2" + +# R4 emulated devices +# Port 13-0 is Optical +# Port 13-1 is Copper +R4_UUID = "b43e6361-2573-509d-9a88-1793e751b10d" +R4_PORT_13_0_UUID_OPTICAL = "241b74a7-8677-595c-ad65-cc9093c1e341" +R4_PORT_13_1_UUID_COPPER = "c57abf46-caaf-5954-90cc-1fec0a69330e" + +node_dict = {R1_PORT_13_1_UUID_COPPER: R1_UUID, + R2_PORT_13_1_UUID_COPPER: R2_UUID, + R3_PORT_13_1_UUID_COPPER: R3_UUID, + R4_PORT_13_1_UUID_COPPER: R4_UUID} +list_endpoints = [R1_PORT_13_1_UUID_COPPER, + R2_PORT_13_1_UUID_COPPER, + R3_PORT_13_1_UUID_COPPER, + R4_PORT_13_1_UUID_COPPER] + +list_availability= [99, 99.9, 99.99, 99.999, 99.9999] +list_bw = [10, 40, 50, 100, 150, 200, 400] +list_owner = ["Telefonica", "CTTC", "Telenor", "ADVA", "Ubitech", "ATOS"] + +URL_POST = "/restconf/data/ietf-network-slice-service:ietf-nss/network-slice-services" +URL_DELETE = "/restconf/data/ietf-network-slice-service:ietf-nss/network-slice-services/slice-service=" + +def generate_request(seed: str) -> Tuple[Dict, str]: + + ns = NetworkSliceServices() + + # Slice 1 + suuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, str(seed))) + slice1 = ns.slice_service[suuid] + slice1.service_description = "Test slice for OFC 2023 demo" + slice1.status().admin_status().status = "Planned" # TODO not yet mapped + + # SDPS: R1 optical to R3 optical + sdps1 = slice1.sdps().sdp + while True: + ep1_uuid = random.choice(list_endpoints) + ep2_uuid = random.choice(list_endpoints) + if ep1_uuid != ep2_uuid: + break + + sdps1[ep1_uuid].node_id = node_dict.get(ep1_uuid) + sdps1[ep2_uuid].node_id = node_dict.get(ep2_uuid) + + # Connectivity group: Connection construct and 2 sla constrains: + # - Bandwidth + # - Availability + cg_uuid = str(uuid.uuid4()) + cg = slice1.connection_groups().connection_group + cg1 = cg[cg_uuid] + + cc1 = cg1.connectivity_construct[0] + cc1.cc_id = 5 + p2p = cc1.connectivity_construct_type.p2p() + p2p.p2p_sender_sdp = ep1_uuid + p2p.p2p_receiver_sdp = ep2_uuid + + slo_custom = cc1.slo_sle_policy.custom() + metric_bounds = slo_custom.service_slo_sle_policy().metric_bounds().metric_bound + + # SLO Bandwidth + slo_bandwidth = metric_bounds["service-slo-two-way-bandwidth"] + slo_bandwidth.value_description = "Guaranteed bandwidth" + slo_bandwidth.bound = int(random.choice(list_bw)) + slo_bandwidth.metric_unit = "Gbps" + + # SLO Availability + slo_availability = metric_bounds["service-slo-availability"] + slo_availability.value_description = "Guaranteed availability" + slo_availability.metric_unit = "percentage" + slo_availability.bound = random.choice(list_availability) + + json_request = {"data": ns.to_json()} + + #Last, add name and owner manually + list_name_owner = [{"tag-type": "owner", "value": random.choice(list_owner)}] + json_request["data"]["ietf-network-slice-service:network-slice-services"]["slice-service"][0]["service-tags"] = list_name_owner + + return (json_request, suuid) + + +if __name__ == "__main__": + request = generate_request(123) + print(json.dumps(request[0], sort_keys=True, indent=4)) diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index 7c3832d6b3ea7de0a495faee143b73179e8da5b9..13d9dc0035b45845bf11367e02c8830b5151c1d6 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -21,11 +21,11 @@ from common.tools.grpc.Tools import grpc_message_to_json_string from common.proto.context_pb2 import ( Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId, ContextIdList, ContextList, - Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, + Device, DeviceEvent, DeviceFilter, DeviceId, DeviceIdList, DeviceList, Empty, EndPointIdList, EndPointNameList, Link, LinkEvent, LinkId, LinkIdList, LinkList, - Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, - Slice, SliceEvent, SliceId, SliceIdList, SliceList, + Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, + Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList) from common.proto.context_pb2_grpc import ContextServiceStub from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub @@ -185,6 +185,13 @@ class ContextClient: LOGGER.debug('RemoveDevice result: {:s}'.format(grpc_message_to_json_string(response))) return response + @RETRY_DECORATOR + def SelectDevice(self, request: DeviceFilter) -> DeviceList: + LOGGER.debug('SelectDevice request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SelectDevice(request) + LOGGER.debug('SelectDevice result: {:s}'.format(grpc_message_to_json_string(response))) + return response + @RETRY_DECORATOR def GetDeviceEvents(self, request: Empty) -> Iterator[DeviceEvent]: LOGGER.debug('GetDeviceEvents request: {:s}'.format(grpc_message_to_json_string(request))) @@ -283,6 +290,13 @@ class ContextClient: LOGGER.debug('RemoveService result: {:s}'.format(grpc_message_to_json_string(response))) return response + @RETRY_DECORATOR + def SelectService(self, request: ServiceFilter) -> ServiceList: + LOGGER.debug('SelectService request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SelectService(request) + LOGGER.debug('SelectService result: {:s}'.format(grpc_message_to_json_string(response))) + return response + @RETRY_DECORATOR def GetServiceEvents(self, request: Empty) -> Iterator[ServiceEvent]: LOGGER.debug('GetServiceEvents request: {:s}'.format(grpc_message_to_json_string(request))) @@ -332,6 +346,13 @@ class ContextClient: LOGGER.debug('RemoveSlice result: {:s}'.format(grpc_message_to_json_string(response))) return response + @RETRY_DECORATOR + def SelectSlice(self, request: SliceFilter) -> SliceList: + LOGGER.debug('SelectSlice request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SelectSlice(request) + LOGGER.debug('SelectSlice result: {:s}'.format(grpc_message_to_json_string(response))) + return response + @RETRY_DECORATOR def GetSliceEvents(self, request: Empty) -> Iterator[SliceEvent]: LOGGER.debug('GetSliceEvents request: {:s}'.format(grpc_message_to_json_string(request))) diff --git a/src/context/data/sql_hash_join_full_scan_tests.sql b/src/context/data/sql_hash_join_full_scan_tests.sql new file mode 100644 index 0000000000000000000000000000000000000000..ebead1be6cae62bce06ab9324c0381b9266eee9c --- /dev/null +++ b/src/context/data/sql_hash_join_full_scan_tests.sql @@ -0,0 +1,119 @@ +-- When inserting config rules, for instance related to device +-- If we insert few rules (3~4 rows), does a lookup join with more rows does hash join which is less performant... +-- To be investigated... + +----------------------------------------------------------------------------------------------------- +-- Scenario: tests database with device and device_configrule tables + +CREATE DATABASE tests; +USE tests; + +CREATE TYPE public.orm_deviceoperationalstatusenum AS ENUM ('UNDEFINED', 'DISABLED', 'ENABLED'); +CREATE TYPE public.orm_devicedriverenum AS ENUM ('UNDEFINED', 'OPENCONFIG', 'TRANSPORT_API', 'P4', 'IETF_NETWORK_TOPOLOGY', 'ONF_TR_352', 'XR', 'IETF_L2VPN'); +CREATE TYPE public.configrulekindenum AS ENUM ('CUSTOM', 'ACL'); +CREATE TYPE public.orm_configactionenum AS ENUM ('UNDEFINED', 'SET', 'DELETE'); + +CREATE TABLE public.device ( + device_uuid UUID NOT NULL, + device_name VARCHAR NOT NULL, + device_type VARCHAR NOT NULL, + device_operational_status public.orm_deviceoperationalstatusenum NOT NULL, + device_drivers public.orm_devicedriverenum[] NULL, + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + CONSTRAINT device_pkey PRIMARY KEY (device_uuid ASC) +); + +CREATE TABLE public.device_configrule ( + configrule_uuid UUID NOT NULL, + device_uuid UUID NOT NULL, + "position" INT8 NOT NULL, + kind public.configrulekindenum NOT NULL, + action public.orm_configactionenum NOT NULL, + data VARCHAR NOT NULL, + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL, + CONSTRAINT device_configrule_pkey PRIMARY KEY (configrule_uuid ASC), + CONSTRAINT device_configrule_device_uuid_fkey FOREIGN KEY (device_uuid) REFERENCES public.device(device_uuid) ON DELETE CASCADE, + INDEX device_configrule_device_uuid_rec_idx (device_uuid ASC) STORING ("position", kind, action, data, created_at, updated_at), + CONSTRAINT check_position_value CHECK ("position" >= 0:::INT8) +); + +----------------------------------------------------------------------------------------------------- +-- Populate devices + +INSERT INTO device (device_uuid, device_name, device_type, device_operational_status, device_drivers, created_at, updated_at) VALUES +('a3645f8a-5f1f-4d91-8b11-af4104e57f52'::UUID, 'R1', 'router', 'ENABLED', ARRAY['UNDEFINED'], '2023-04-21 07:51:00.0', '2023-04-21 07:51:00.0'), +('7c1e923c-145c-48c5-8016-0d1f596cb4c1'::UUID, 'R2', 'router', 'ENABLED', ARRAY['UNDEFINED'], '2023-04-21 07:51:00.0', '2023-04-21 07:51:00.0') +ON CONFLICT (device_uuid) DO UPDATE SET +device_name=excluded.device_name, +device_operational_status=excluded.device_operational_status, +updated_at=excluded.updated_at +RETURNING device.created_at, device.updated_at; + +----------------------------------------------------------------------------------------------------- +-- Examine insertion of config rules... + +-- Helpful commands: +-- ANALYZE (VERBOSE, TYPES) +-- EXPLAIN (VERBOSE, TYPES) + +-- Rows with realistic data +EXPLAIN (TYPES, VERBOSE) INSERT INTO device_configrule (configrule_uuid, device_uuid, position, kind, action, data, created_at, updated_at) VALUES +('5491b521-76a2-57c4-b622-829131374b4b', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 0, 'CUSTOM', 'SET', '{"resource_key": "_connect/address", "resource_value": "127.0.0.1"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('1f39fb84-2337-5735-a873-2bc7cd50bdd2', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 1, 'CUSTOM', 'SET', '{"resource_key": "_connect/port", "resource_value": "0"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('5d4c72f9-7acc-5ab2-a41e-0d4bc625943e', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 2, 'CUSTOM', 'SET', '{"resource_key": "_connect/settings", "resource_value": "{\\n\\"endpoints\\": [\\n{\\n\\"sample_types\\": [],\\n\\"type\\": \\"copper\\",\\n\\"uuid\\ ... (573 characters truncated) ... "type\\": \\"copper\\",\\n\\"uuid\\": \\"2/5\\"\\n},\\n{\\n\\"sample_types\\": [],\\n\\"type\\": \\"copper\\",\\n\\"uuid\\": \\"2/6\\"\\n}\\n]\\n}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('d14c3fc7-4998-5707-b1c4-073d553a86ef', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 3, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[1/1]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"1/1\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('e3268fba-e695-59d0-b26e-014930f416fd', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 4, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[1/2]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"1/2\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('043eb444-81c8-5ac9-83df-0c6a74bad534', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 5, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[1/3]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"1/3\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('df79d0ea-bcda-57fc-8926-e9a9257628dd', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 6, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[2/1]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"2/1\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('94f41adc-1041-5a8a-81f5-1224d884ae57', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 7, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[2/2]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"2/2\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('b27c0207-dc43-59db-a856-74aaab4f1a19', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 8, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[2/3]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"2/3\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('5902903f-0be4-5ec6-a133-c3e2f9ae05a6', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 9, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[2/4]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"2/4\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('eb20a698-99f2-5369-a228-610cd289297a', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 10, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[2/5]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"2/5\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('3a73b766-195c-59ec-a66e-d32391bc35a3', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 11, 'CUSTOM', 'SET', '{"resource_key": "/endpoints/endpoint[2/6]", "resource_value": "{\\"sample_types\\": {}, \\"type\\": \\"copper\\", \\"uuid\\": \\"2/6\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('353ba35c-5ec6-5f38-8ca9-e6c024772282', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 12, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:126]", "resource_value": "{\\"name\\": \\"ELAN-AC:126\\", \\"type\\": \\"L2VSI\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('45582643-09a1-5ade-beac-2bf057549d38', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 13, 'CUSTOM', 'SET', '{"resource_key": "/interface[2/4.126]/subinterface[0]", "resource_value": "{\\"index\\": 0, \\"name\\": \\"2/4.126\\", \\"type\\": \\"l2vlan\\", \\"vlan_id\\": 26}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('9484afcd-b010-561e-ba83-6b0654d8816c', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 14, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:126]/interface[2/4.126]", "resource_value": "{\\"id\\": \\"2/4.126\\", \\"interface\\": \\"2/4.126\\", \\"name\\": \\"ELAN-AC:126\\", \\"subinterface\\": 0}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('f1cc8161-eaee-5139-a3e5-207fbe11800d', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 15, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:126]/connection_point[VC-1]", "resource_value": "{\\"VC_ID\\": \\"126\\", \\"connection_point\\": \\"VC-1\\", \\"name\\": \\"ELAN-AC:126\\", \\"remote_system\\": \\"10.0.0.6\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('f1836e1d-74a1-51be-944f-a2cedc297812', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 16, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:128]", "resource_value": "{\\"name\\": \\"ELAN-AC:128\\", \\"type\\": \\"L2VSI\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('86f152ea-6abf-5bd4-b2c8-eddfe2826847', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 17, 'CUSTOM', 'SET', '{"resource_key": "/interface[1/2.128]/subinterface[0]", "resource_value": "{\\"index\\": 0, \\"name\\": \\"1/2.128\\", \\"type\\": \\"l2vlan\\", \\"vlan_id\\": 28}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('c36e9d88-0ee3-5826-9a27-3b25a7520121', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 18, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:128]/interface[1/2.128]", "resource_value": "{\\"id\\": \\"1/2.128\\", \\"interface\\": \\"1/2.128\\", \\"name\\": \\"ELAN-AC:128\\", \\"subinterface\\": 0}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('a9d4c170-ca55-5969-8329-5bbbceec5bd6', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 19, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:128]/connection_point[VC-1]", "resource_value": "{\\"VC_ID\\": \\"128\\", \\"connection_point\\": \\"VC-1\\", \\"name\\": \\"ELAN-AC:128\\", \\"remote_system\\": \\"10.0.0.3\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('d86ceb87-e87a-5b1d-b3d9-15af96233500', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 20, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:136]", "resource_value": "{\\"name\\": \\"ELAN-AC:136\\", \\"type\\": \\"L2VSI\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('cef724a0-3a51-5dd7-b9e5-bde174f4a8d2', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 21, 'CUSTOM', 'SET', '{"resource_key": "/interface[2/6.136]/subinterface[0]", "resource_value": "{\\"index\\": 0, \\"name\\": \\"2/6.136\\", \\"type\\": \\"l2vlan\\", \\"vlan_id\\": 36}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('9a01ca29-4ef6-50f3-84f0-a219e7c1689e', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 22, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:136]/interface[2/6.136]", "resource_value": "{\\"id\\": \\"2/6.136\\", \\"interface\\": \\"2/6.136\\", \\"name\\": \\"ELAN-AC:136\\", \\"subinterface\\": 0}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('9212773d-6a4f-5cce-ae5b-85adfdf6674e', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 23, 'CUSTOM', 'SET', '{"resource_key": "/network_instance[ELAN-AC:136]/connection_point[VC-1]", "resource_value": "{\\"VC_ID\\": \\"136\\", \\"connection_point\\": \\"VC-1\\", \\"name\\": \\"ELAN-AC:136\\", \\"remote_system\\": \\"10.0.0.2\\"}"}', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892') +ON CONFLICT (configrule_uuid) DO UPDATE SET position = excluded.position, action = excluded.action, data = excluded.data, updated_at = excluded.updated_at +RETURNING device_configrule.created_at, device_configrule.updated_at; + + +-- Rows with empty data (still does full scan and hash join) +-- If only 3~4 rows are inserted it does lookup join... +EXPLAIN INSERT INTO device_configrule (configrule_uuid, device_uuid, position, kind, action, data, created_at, updated_at) VALUES +('5491b521-76a2-57c4-b622-829131374b4b', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 0, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('1f39fb84-2337-5735-a873-2bc7cd50bdd2', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 1, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('5d4c72f9-7acc-5ab2-a41e-0d4bc625943e', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 2, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('d14c3fc7-4998-5707-b1c4-073d553a86ef', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 3, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('e3268fba-e695-59d0-b26e-014930f416fd', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 4, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('043eb444-81c8-5ac9-83df-0c6a74bad534', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 5, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('df79d0ea-bcda-57fc-8926-e9a9257628dd', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 6, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('94f41adc-1041-5a8a-81f5-1224d884ae57', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 7, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('b27c0207-dc43-59db-a856-74aaab4f1a19', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 8, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('5902903f-0be4-5ec6-a133-c3e2f9ae05a6', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 9, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('eb20a698-99f2-5369-a228-610cd289297a', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 10, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('3a73b766-195c-59ec-a66e-d32391bc35a3', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 11, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('353ba35c-5ec6-5f38-8ca9-e6c024772282', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 12, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('45582643-09a1-5ade-beac-2bf057549d38', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 13, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('9484afcd-b010-561e-ba83-6b0654d8816c', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 14, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('f1cc8161-eaee-5139-a3e5-207fbe11800d', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 15, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('f1836e1d-74a1-51be-944f-a2cedc297812', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 16, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('86f152ea-6abf-5bd4-b2c8-eddfe2826847', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 17, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('c36e9d88-0ee3-5826-9a27-3b25a7520121', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 18, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('a9d4c170-ca55-5969-8329-5bbbceec5bd6', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 19, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('d86ceb87-e87a-5b1d-b3d9-15af96233500', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 20, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('cef724a0-3a51-5dd7-b9e5-bde174f4a8d2', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 21, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('9a01ca29-4ef6-50f3-84f0-a219e7c1689e', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 22, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892'), +('9212773d-6a4f-5cce-ae5b-85adfdf6674e', 'a3645f8a-5f1f-4d91-8b11-af4104e57f52', 23, 'CUSTOM', 'SET', '', '2023-04-20 17:33:54.044892', '2023-04-20 17:33:54.044892') +ON CONFLICT (configrule_uuid) DO UPDATE SET position = excluded.position, action = excluded.action, data = excluded.data, updated_at = excluded.updated_at +RETURNING device_configrule.created_at, device_configrule.updated_at; diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index 6fe00f917cf8b338f0934e2a268fa757d2055865..6d540b4945df8516697c957316294a452186ddb1 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -18,11 +18,11 @@ from common.message_broker.MessageBroker import MessageBroker from common.proto.context_pb2 import ( Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId, ContextIdList, ContextList, - Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, + Device, DeviceEvent, DeviceFilter, DeviceId, DeviceIdList, DeviceList, Empty, EndPointIdList, EndPointNameList, EventTypeEnum, Link, LinkEvent, LinkId, LinkIdList, LinkList, - Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, - Slice, SliceEvent, SliceId, SliceIdList, SliceList, + Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, + Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList) from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule from common.proto.context_pb2_grpc import ContextServiceServicer @@ -31,13 +31,13 @@ from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_m from .database.Connection import ( connection_delete, connection_get, connection_list_ids, connection_list_objs, connection_set) from .database.Context import context_delete, context_get, context_list_ids, context_list_objs, context_set -from .database.Device import device_delete, device_get, device_list_ids, device_list_objs, device_set +from .database.Device import device_delete, device_get, device_list_ids, device_list_objs, device_select, device_set from .database.EndPoint import endpoint_list_names from .database.Link import link_delete, link_get, link_list_ids, link_list_objs, link_set from .database.PolicyRule import ( policyrule_delete, policyrule_get, policyrule_list_ids, policyrule_list_objs, policyrule_set) -from .database.Service import service_delete, service_get, service_list_ids, service_list_objs, service_set -from .database.Slice import slice_delete, slice_get, slice_list_ids, slice_list_objs, slice_set, slice_unset +from .database.Service import service_delete, service_get, service_list_ids, service_list_objs, service_select, service_set, service_unset +from .database.Slice import slice_delete, slice_get, slice_list_ids, slice_list_objs, slice_select, slice_set, slice_unset from .database.Topology import ( topology_delete, topology_get, topology_get_details, topology_list_ids, topology_list_objs, topology_set) from .Events import ( @@ -161,6 +161,10 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer notify_event(self.messagebroker, TOPIC_DEVICE, event_type, {'device_id': device_id}) return Empty() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SelectDevice(self, request : DeviceFilter, context : grpc.ServicerContext) -> DeviceList: + return DeviceList(devices=device_select(self.db_engine, request)) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetDeviceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[DeviceEvent]: for message in self.messagebroker.consume({TOPIC_DEVICE}, consume_timeout=CONSUME_TIMEOUT): @@ -227,6 +231,14 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id}) return ServiceId(**service_id) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def UnsetService(self, request : Service, context : grpc.ServicerContext) -> ServiceId: + service_id,updated = service_unset(self.db_engine, request) + if updated: + event_type = EventTypeEnum.EVENTTYPE_UPDATE + notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id}) + return ServiceId(**service_id) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty: service_id,deleted = service_delete(self.db_engine, request) @@ -235,6 +247,10 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id}) return Empty() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SelectService(self, request : ServiceFilter, context : grpc.ServicerContext) -> ServiceList: + return ServiceList(services=service_select(self.db_engine, request)) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetServiceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[ServiceEvent]: for message in self.messagebroker.consume({TOPIC_SERVICE}, consume_timeout=CONSUME_TIMEOUT): @@ -278,6 +294,10 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': slice_id}) return Empty() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SelectSlice(self, request : SliceFilter, context : grpc.ServicerContext) -> SliceList: + return SliceList(slices=slice_select(self.db_engine, request)) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetSliceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[SliceEvent]: for message in self.messagebroker.consume({TOPIC_SLICE}, consume_timeout=CONSUME_TIMEOUT): diff --git a/src/context/service/__main__.py b/src/context/service/__main__.py index 92d4c88275e4751602bf735f734df84469c43c17..5ac91f233504a25bb787df5be9b1a36848f4e5c4 100644 --- a/src/context/service/__main__.py +++ b/src/context/service/__main__.py @@ -44,9 +44,17 @@ def main(): start_http_server(metrics_port) # Get Database Engine instance and initialize database, if needed + LOGGER.info('Getting SQLAlchemy DB Engine...') db_engine = Engine.get_engine() - if db_engine is None: return -1 - Engine.create_database(db_engine) + if db_engine is None: + LOGGER.error('Unable to get SQLAlchemy DB Engine...') + return -1 + + try: + Engine.create_database(db_engine) + except: # pylint: disable=bare-except # pragma: no cover + LOGGER.exception('Failed to check/create the database: {:s}'.format(str(db_engine.url))) + rebuild_database(db_engine) # Get message broker instance @@ -57,7 +65,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/context/service/database/ConfigRule.py b/src/context/service/database/ConfigRule.py index 09723cc6f6b31e2496bf5ab475f50d0aa58f95c2..c5b259a2dfc2ba684f6881dfb2a9a79b3a36032a 100644 --- a/src/context/service/database/ConfigRule.py +++ b/src/context/service/database/ConfigRule.py @@ -21,7 +21,8 @@ from typing import Dict, List, Optional, Set from common.proto.context_pb2 import ConfigRule from common.tools.grpc.Tools import grpc_message_to_json_string from .models.enums.ConfigAction import ORM_ConfigActionEnum, grpc_to_enum__config_action -from .models.ConfigRuleModel import ConfigRuleKindEnum, ConfigRuleModel +from .models.ConfigRuleModel import ( + ConfigRuleKindEnum, DeviceConfigRuleModel, ServiceConfigRuleModel, SliceConfigRuleModel) from .uuids._Builder import get_uuid_from_string from .uuids.EndPoint import endpoint_get_uuid @@ -83,6 +84,16 @@ def upsert_config_rules( session : Session, config_rules : List[Dict], is_delete : bool = False, device_uuid : Optional[str] = None, service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None, ) -> bool: + if device_uuid is not None and service_uuid is None and slice_uuid is None: + klass = DeviceConfigRuleModel + elif device_uuid is None and service_uuid is not None and slice_uuid is None: + klass = ServiceConfigRuleModel + elif device_uuid is None and service_uuid is None and slice_uuid is not None: + klass = SliceConfigRuleModel + else: + MSG = 'DataModel cannot be identified (device_uuid={:s}, service_uuid={:s}, slice_uuid={:s})' + raise Exception(MSG.format(str(device_uuid), str(service_uuid), str(slice_uuid))) + uuids_to_delete : Set[str] = set() uuids_to_upsert : Dict[str, int] = dict() rules_to_upsert : List[Dict] = list() @@ -108,11 +119,11 @@ def upsert_config_rules( delete_affected = False if len(uuids_to_delete) > 0: - stmt = delete(ConfigRuleModel) - if device_uuid is not None: stmt = stmt.where(ConfigRuleModel.device_uuid == device_uuid ) - if service_uuid is not None: stmt = stmt.where(ConfigRuleModel.service_uuid == service_uuid) - if slice_uuid is not None: stmt = stmt.where(ConfigRuleModel.slice_uuid == slice_uuid ) - stmt = stmt.where(ConfigRuleModel.configrule_uuid.in_(uuids_to_delete)) + stmt = delete(klass) + if device_uuid is not None: stmt = stmt.where(klass.device_uuid == device_uuid ) + if service_uuid is not None: stmt = stmt.where(klass.service_uuid == service_uuid) + if slice_uuid is not None: stmt = stmt.where(klass.slice_uuid == slice_uuid ) + stmt = stmt.where(klass.configrule_uuid.in_(uuids_to_delete)) #str_stmt = stmt.compile(dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}) #LOGGER.warning('delete stmt={:s}'.format(str(str_stmt))) configrule_deletes = session.execute(stmt) @@ -121,9 +132,9 @@ def upsert_config_rules( upsert_affected = False if len(rules_to_upsert) > 0: - stmt = insert(ConfigRuleModel).values(rules_to_upsert) + stmt = insert(klass).values(rules_to_upsert) stmt = stmt.on_conflict_do_update( - index_elements=[ConfigRuleModel.configrule_uuid], + index_elements=[klass.configrule_uuid], set_=dict( position = stmt.excluded.position, action = stmt.excluded.action, @@ -131,7 +142,7 @@ def upsert_config_rules( updated_at = stmt.excluded.updated_at, ) ) - stmt = stmt.returning(ConfigRuleModel.created_at, ConfigRuleModel.updated_at) + stmt = stmt.returning(klass.created_at, klass.updated_at) #str_stmt = stmt.compile(dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}) #LOGGER.warning('upsert stmt={:s}'.format(str(str_stmt))) configrule_updates = session.execute(stmt).fetchall() diff --git a/src/context/service/database/Connection.py b/src/context/service/database/Connection.py index a3edb8ea2838d9203a810677da495893a2cd6973..80d3b3a6d437986741ee5308205d8a902e897c40 100644 --- a/src/context/service/database/Connection.py +++ b/src/context/service/database/Connection.py @@ -16,7 +16,7 @@ import datetime, logging, re from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Tuple from common.proto.context_pb2 import Connection, ConnectionId, ServiceId @@ -40,7 +40,11 @@ def connection_list_ids(db_engine : Engine, request : ServiceId) -> List[Dict]: def connection_list_objs(db_engine : Engine, request : ServiceId) -> List[Dict]: _,service_uuid = service_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: - obj_list : List[ConnectionModel] = session.query(ConnectionModel).filter_by(service_uuid=service_uuid).all() + obj_list : List[ConnectionModel] = session.query(ConnectionModel)\ + .options(selectinload(ConnectionModel.connection_service))\ + .options(selectinload(ConnectionModel.connection_endpoints))\ + .options(selectinload(ConnectionModel.connection_subservices))\ + .filter_by(service_uuid=service_uuid).all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) @@ -48,6 +52,9 @@ def connection_get(db_engine : Engine, request : ConnectionId) -> Dict: connection_uuid = connection_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: obj : Optional[ConnectionModel] = session.query(ConnectionModel)\ + .options(selectinload(ConnectionModel.connection_service))\ + .options(selectinload(ConnectionModel.connection_endpoints))\ + .options(selectinload(ConnectionModel.connection_subservices))\ .filter_by(connection_uuid=connection_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/Constraint.py b/src/context/service/database/Constraint.py index 3a73f6589f9332aa4c84f8f296f2cb56db3048bf..b33316539e7ab728194bda52e80cbc4896981ca2 100644 --- a/src/context/service/database/Constraint.py +++ b/src/context/service/database/Constraint.py @@ -20,7 +20,7 @@ from sqlalchemy.orm import Session from typing import Dict, List, Optional from common.proto.context_pb2 import Constraint from common.tools.grpc.Tools import grpc_message_to_json_string -from .models.ConstraintModel import ConstraintKindEnum, ConstraintModel +from .models.ConstraintModel import ConstraintKindEnum, ServiceConstraintModel, SliceConstraintModel from .uuids._Builder import get_uuid_from_string from .uuids.EndPoint import endpoint_get_uuid @@ -66,7 +66,7 @@ def compose_constraints_data( constraint_name = '{:s}:{:s}:{:s}'.format(parent_kind, kind.value, endpoint_uuid) elif kind in { ConstraintKindEnum.SCHEDULE, ConstraintKindEnum.SLA_CAPACITY, ConstraintKindEnum.SLA_LATENCY, - ConstraintKindEnum.SLA_AVAILABILITY, ConstraintKindEnum.SLA_ISOLATION + ConstraintKindEnum.SLA_AVAILABILITY, ConstraintKindEnum.SLA_ISOLATION, ConstraintKindEnum.EXCLUSIONS }: constraint_name = '{:s}:{:s}:'.format(parent_kind, kind.value) else: @@ -84,6 +84,14 @@ def upsert_constraints( session : Session, constraints : List[Dict], is_delete : bool = False, service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None ) -> bool: + if service_uuid is not None and slice_uuid is None: + klass = ServiceConstraintModel + elif service_uuid is None and slice_uuid is not None: + klass = SliceConstraintModel + else: + MSG = 'DataModel cannot be identified (service_uuid={:s}, slice_uuid={:s})' + raise Exception(MSG.format(str(service_uuid), str(slice_uuid))) + uuids_to_upsert : Dict[str, int] = dict() rules_to_upsert : List[Dict] = list() for constraint in constraints: @@ -100,10 +108,10 @@ def upsert_constraints( # Delete all constraints not in uuids_to_upsert delete_affected = False if len(uuids_to_upsert) > 0: - stmt = delete(ConstraintModel) - if service_uuid is not None: stmt = stmt.where(ConstraintModel.service_uuid == service_uuid) - if slice_uuid is not None: stmt = stmt.where(ConstraintModel.slice_uuid == slice_uuid ) - stmt = stmt.where(ConstraintModel.constraint_uuid.not_in(set(uuids_to_upsert.keys()))) + stmt = delete(klass) + if service_uuid is not None: stmt = stmt.where(klass.service_uuid == service_uuid) + if slice_uuid is not None: stmt = stmt.where(klass.slice_uuid == slice_uuid ) + stmt = stmt.where(klass.constraint_uuid.not_in(set(uuids_to_upsert.keys()))) #str_stmt = stmt.compile(dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}) #LOGGER.warning('delete stmt={:s}'.format(str(str_stmt))) constraint_deletes = session.execute(stmt) @@ -112,16 +120,16 @@ def upsert_constraints( upsert_affected = False if not is_delete and len(constraints) > 0: - stmt = insert(ConstraintModel).values(constraints) + stmt = insert(klass).values(constraints) stmt = stmt.on_conflict_do_update( - index_elements=[ConstraintModel.constraint_uuid], + index_elements=[klass.constraint_uuid], set_=dict( position = stmt.excluded.position, data = stmt.excluded.data, updated_at = stmt.excluded.updated_at, ) ) - stmt = stmt.returning(ConstraintModel.created_at, ConstraintModel.updated_at) + stmt = stmt.returning(klass.created_at, klass.updated_at) #str_stmt = stmt.compile(dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}) #LOGGER.warning('upsert stmt={:s}'.format(str(str_stmt))) constraint_updates = session.execute(stmt).fetchall() diff --git a/src/context/service/database/Context.py b/src/context/service/database/Context.py index 9e05e54b38d3772ece2d87de0d98fb5a216088de..4654095034749e1de985705b242ba9fa05a82f6a 100644 --- a/src/context/service/database/Context.py +++ b/src/context/service/database/Context.py @@ -15,7 +15,7 @@ import datetime, logging from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Tuple from common.proto.context_pb2 import Context, ContextId @@ -34,14 +34,22 @@ def context_list_ids(db_engine : Engine) -> List[Dict]: def context_list_objs(db_engine : Engine) -> List[Dict]: def callback(session : Session) -> List[Dict]: - obj_list : List[ContextModel] = session.query(ContextModel).all() + obj_list : List[ContextModel] = session.query(ContextModel)\ + .options(selectinload(ContextModel.topologies))\ + .options(selectinload(ContextModel.services))\ + .options(selectinload(ContextModel.slices))\ + .all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) def context_get(db_engine : Engine, request : ContextId) -> Dict: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: - obj : Optional[ContextModel] = session.query(ContextModel).filter_by(context_uuid=context_uuid).one_or_none() + obj : Optional[ContextModel] = session.query(ContextModel)\ + .options(selectinload(ContextModel.topologies))\ + .options(selectinload(ContextModel.services))\ + .options(selectinload(ContextModel.slices))\ + .filter_by(context_uuid=context_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) if obj is None: diff --git a/src/context/service/database/Device.py b/src/context/service/database/Device.py index c5a19c9c4b0bca4f85ffe1211dbefc6b218d518e..7fc202b9077f2e1212d0c81313fcfbd1c05efb43 100644 --- a/src/context/service/database/Device.py +++ b/src/context/service/database/Device.py @@ -15,12 +15,12 @@ import datetime, logging from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set, Tuple from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException -from common.proto.context_pb2 import Device, DeviceId, TopologyId -from common.tools.grpc.Tools import grpc_message_to_json_string +from common.proto.context_pb2 import Device, DeviceFilter, DeviceId, TopologyId +#from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Device import json_device_id from context.service.database.uuids.Topology import topology_get_uuid from .models.DeviceModel import DeviceModel @@ -43,14 +43,22 @@ def device_list_ids(db_engine : Engine) -> List[Dict]: def device_list_objs(db_engine : Engine) -> List[Dict]: def callback(session : Session) -> List[Dict]: - obj_list : List[DeviceModel] = session.query(DeviceModel).all() + obj_list : List[DeviceModel] = session.query(DeviceModel)\ + .options(selectinload(DeviceModel.endpoints))\ + .options(selectinload(DeviceModel.config_rules))\ + .all() + #.options(selectinload(DeviceModel.components))\ return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) def device_get(db_engine : Engine, request : DeviceId) -> Dict: device_uuid = device_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: - obj : Optional[DeviceModel] = session.query(DeviceModel).filter_by(device_uuid=device_uuid).one_or_none() + obj : Optional[DeviceModel] = session.query(DeviceModel)\ + .options(selectinload(DeviceModel.endpoints))\ + .options(selectinload(DeviceModel.config_rules))\ + .filter_by(device_uuid=device_uuid).one_or_none() + #.options(selectinload(DeviceModel.components))\ return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) if obj is None: @@ -66,6 +74,11 @@ def device_set(db_engine : Engine, request : Device) -> Tuple[Dict, bool]: device_name = raw_device_uuid if len(raw_device_name) == 0 else raw_device_name device_uuid = device_get_uuid(request.device_id, device_name=device_name, allow_random=True) + if len(request.controller_id.device_uuid.uuid) > 0: + controller_uuid = device_get_uuid(request.controller_id, allow_random=False) + else: + controller_uuid = None + device_type = request.device_type oper_status = grpc_to_enum__device_operational_status(request.device_operational_status) device_drivers = [grpc_to_enum__device_driver(d) for d in request.device_drivers] @@ -131,6 +144,9 @@ def device_set(db_engine : Engine, request : Device) -> Tuple[Dict, bool]: 'updated_at' : now, }] + if controller_uuid is not None: + device_data[0]['controller_uuid'] = controller_uuid + def callback(session : Session) -> bool: stmt = insert(DeviceModel).values(device_data) stmt = stmt.on_conflict_do_update( @@ -163,7 +179,9 @@ def device_set(db_engine : Engine, request : Device) -> Tuple[Dict, bool]: endpoint_updates = session.execute(stmt).fetchall() updated_endpoints = any([(updated_at > created_at) for created_at,updated_at in endpoint_updates]) - if len(related_topologies) > 0: + if not updated or len(related_topologies) > 1: + # Only update topology-device relations when device is created (not updated) or when endpoints are + # modified (len(related_topologies) > 1). session.execute(insert(TopologyDeviceModel).values(related_topologies).on_conflict_do_nothing( index_elements=[TopologyDeviceModel.topology_uuid, TopologyDeviceModel.device_uuid] )) @@ -182,3 +200,22 @@ def device_delete(db_engine : Engine, request : DeviceId) -> Tuple[Dict, bool]: return num_deleted > 0 deleted = run_transaction(sessionmaker(bind=db_engine), callback) return json_device_id(device_uuid),deleted + +def device_select(db_engine : Engine, request : DeviceFilter) -> List[Dict]: + device_uuids = [ + device_get_uuid(device_id, allow_random=False) + for device_id in request.device_ids.device_ids + ] + dump_params = dict( + include_endpoints =request.include_endpoints, + include_config_rules=request.include_config_rules, + include_components =request.include_components, + ) + def callback(session : Session) -> List[Dict]: + query = session.query(DeviceModel) + if request.include_endpoints : query = query.options(selectinload(DeviceModel.endpoints)) + if request.include_config_rules: query = query.options(selectinload(DeviceModel.config_rules)) + #if request.include_components : query = query.options(selectinload(DeviceModel.components)) + obj_list : List[DeviceModel] = query.filter(DeviceModel.device_uuid.in_(device_uuids)).all() + return [obj.dump(**dump_params) for obj in obj_list] + return run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/EndPoint.py b/src/context/service/database/EndPoint.py index e2f86893abdf62c9675a83b2a80ceed1227b85d4..b0df3bb8101a7b64a148e916178b1c9a77d511af 100644 --- a/src/context/service/database/EndPoint.py +++ b/src/context/service/database/EndPoint.py @@ -14,7 +14,7 @@ import logging from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List from common.proto.context_pb2 import EndPointIdList @@ -29,7 +29,8 @@ def endpoint_list_names(db_engine : Engine, request : EndPointIdList) -> List[Di for endpoint_id in request.endpoint_ids } def callback(session : Session) -> List[Dict]: - obj_list : List[EndPointModel] = \ - session.query(EndPointModel).filter(EndPointModel.endpoint_uuid.in_(endpoint_uuids)).all() + obj_list : List[EndPointModel] = session.query(EndPointModel)\ + .options(selectinload(EndPointModel.device))\ + .filter(EndPointModel.endpoint_uuid.in_(endpoint_uuids)).all() return [obj.dump_name() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/Engine.py b/src/context/service/database/Engine.py index 5cfe7cd4be6fefb4fe2e0921e2cd0e2b4e23c60a..5924329900dda78d7a15ce7eebc6cbc69e954f8f 100644 --- a/src/context/service/database/Engine.py +++ b/src/context/service/database/Engine.py @@ -42,12 +42,6 @@ class Engine: LOGGER.exception('Failed to connect to database: {:s}'.format(str(crdb_uri))) return None - try: - Engine.create_database(engine) - except: # pylint: disable=bare-except # pragma: no cover - LOGGER.exception('Failed to check/create to database: {:s}'.format(str(crdb_uri))) - return None - return engine @staticmethod diff --git a/src/context/service/database/Link.py b/src/context/service/database/Link.py index 8d195cb1d548368c4b1d55f70a3d728ee6fd052e..76db07a9e30b4f62c4b51574ad95c222a1490f79 100644 --- a/src/context/service/database/Link.py +++ b/src/context/service/database/Link.py @@ -15,12 +15,13 @@ import datetime, logging from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set, Tuple -from common.proto.context_pb2 import Link, LinkId +from common.proto.context_pb2 import Link, LinkId, TopologyId from common.method_wrappers.ServiceExceptions import NotFoundException from common.tools.object_factory.Link import json_link_id +from context.service.database.uuids.Topology import topology_get_uuid from .models.LinkModel import LinkModel, LinkEndPointModel from .models.TopologyModel import TopologyLinkModel from .uuids.EndPoint import endpoint_get_uuid @@ -36,14 +37,18 @@ def link_list_ids(db_engine : Engine) -> List[Dict]: def link_list_objs(db_engine : Engine) -> List[Dict]: def callback(session : Session) -> List[Dict]: - obj_list : List[LinkModel] = session.query(LinkModel).all() + obj_list : List[LinkModel] = session.query(LinkModel)\ + .options(selectinload(LinkModel.link_endpoints))\ + .all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) def link_get(db_engine : Engine, request : LinkId) -> Dict: link_uuid = link_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: - obj : Optional[LinkModel] = session.query(LinkModel).filter_by(link_uuid=link_uuid).one_or_none() + obj : Optional[LinkModel] = session.query(LinkModel)\ + .options(selectinload(LinkModel.link_endpoints))\ + .filter_by(link_uuid=link_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) if obj is None: @@ -63,14 +68,24 @@ def link_set(db_engine : Engine, request : Link) -> Tuple[Dict, bool]: topology_uuids : Set[str] = set() related_topologies : List[Dict] = list() + + # By default, always add link to default Context/Topology + _,topology_uuid = topology_get_uuid(TopologyId(), allow_random=False, allow_default=True) + related_topologies.append({ + 'topology_uuid': topology_uuid, + 'link_uuid' : link_uuid, + }) + topology_uuids.add(topology_uuid) + link_endpoints_data : List[Dict] = list() - for endpoint_id in request.link_endpoint_ids: + for i,endpoint_id in enumerate(request.link_endpoint_ids): endpoint_topology_uuid, _, endpoint_uuid = endpoint_get_uuid( endpoint_id, allow_random=False) link_endpoints_data.append({ 'link_uuid' : link_uuid, 'endpoint_uuid': endpoint_uuid, + 'position' : i, }) if endpoint_topology_uuid not in topology_uuids: diff --git a/src/context/service/database/PolicyRule.py b/src/context/service/database/PolicyRule.py index e95cec4ae533795b23b8fd4e2f26ac9000c1bcce..13f0a2698c17874e1e15f4d6a1d527d366141f56 100644 --- a/src/context/service/database/PolicyRule.py +++ b/src/context/service/database/PolicyRule.py @@ -15,7 +15,7 @@ import datetime, json from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set, Tuple from common.proto.policy_pb2 import PolicyRule, PolicyRuleId, PolicyRuleIdList, PolicyRuleList @@ -31,14 +31,15 @@ from .uuids.Service import service_get_uuid def policyrule_list_ids(db_engine : Engine) -> List[Dict]: def callback(session : Session) -> List[Dict]: obj_list : List[PolicyRuleModel] = session.query(PolicyRuleModel).all() - #.options(selectinload(PolicyRuleModel.topology)).filter_by(context_uuid=context_uuid).one_or_none() return [obj.dump_id() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) def policyrule_list_objs(db_engine : Engine) -> List[Dict]: def callback(session : Session) -> List[Dict]: - obj_list : List[PolicyRuleModel] = session.query(PolicyRuleModel).all() - #.options(selectinload(PolicyRuleModel.topology)).filter_by(context_uuid=context_uuid).one_or_none() + obj_list : List[PolicyRuleModel] = session.query(PolicyRuleModel)\ + .options(selectinload(PolicyRuleModel.policyrule_service))\ + .options(selectinload(PolicyRuleModel.policyrule_devices))\ + .all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) @@ -46,6 +47,8 @@ def policyrule_get(db_engine : Engine, request : PolicyRuleId) -> PolicyRule: policyrule_uuid = policyrule_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: obj : Optional[PolicyRuleModel] = session.query(PolicyRuleModel)\ + .options(selectinload(PolicyRuleModel.policyrule_service))\ + .options(selectinload(PolicyRuleModel.policyrule_devices))\ .filter_by(policyrule_uuid=policyrule_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/Service.py b/src/context/service/database/Service.py index a81a80c3c2398fed16842bcc3d8aa16342edb72b..b6916dc3a19fef4bde3aff93300e63f360b362c0 100644 --- a/src/context/service/database/Service.py +++ b/src/context/service/database/Service.py @@ -13,12 +13,13 @@ # limitations under the License. import datetime, logging +from sqlalchemy import and_ from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction -from typing import Dict, List, Optional, Tuple -from common.proto.context_pb2 import ContextId, Service, ServiceId +from typing import Dict, List, Optional, Set, Tuple +from common.proto.context_pb2 import ContextId, Service, ServiceFilter, ServiceId from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Service import json_service_id @@ -43,14 +44,22 @@ def service_list_ids(db_engine : Engine, request : ContextId) -> List[Dict]: def service_list_objs(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: - obj_list : List[ServiceModel] = session.query(ServiceModel).filter_by(context_uuid=context_uuid).all() + obj_list : List[ServiceModel] = session.query(ServiceModel)\ + .options(selectinload(ServiceModel.service_endpoints))\ + .options(selectinload(ServiceModel.constraints))\ + .options(selectinload(ServiceModel.config_rules))\ + .filter_by(context_uuid=context_uuid).all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) def service_get(db_engine : Engine, request : ServiceId) -> Dict: _,service_uuid = service_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: - obj : Optional[ServiceModel] = session.query(ServiceModel).filter_by(service_uuid=service_uuid).one_or_none() + obj : Optional[ServiceModel] = session.query(ServiceModel)\ + .options(selectinload(ServiceModel.service_endpoints))\ + .options(selectinload(ServiceModel.constraints))\ + .options(selectinload(ServiceModel.config_rules))\ + .filter_by(service_uuid=service_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) if obj is None: @@ -91,6 +100,7 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[Dict, bool]: service_endpoints_data.append({ 'service_uuid' : service_uuid, 'endpoint_uuid': endpoint_uuid, + 'position' : i, }) constraints = compose_constraints_data(request.service_constraints, now, service_uuid=service_uuid) @@ -137,6 +147,45 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[Dict, bool]: updated = run_transaction(sessionmaker(bind=db_engine), callback) return json_service_id(service_uuid, json_context_id(context_uuid)),updated +def service_unset(db_engine : Engine, request : Service) -> Tuple[Dict, bool]: + raw_context_uuid = request.service_id.context_id.context_uuid.uuid + raw_service_uuid = request.service_id.service_uuid.uuid + raw_service_name = request.name + service_name = raw_service_uuid if len(raw_service_name) == 0 else raw_service_name + context_uuid,service_uuid = service_get_uuid(request.service_id, service_name=service_name, allow_random=False) + + service_endpoint_uuids : Set[str] = set() + for i,endpoint_id in enumerate(request.service_endpoint_ids): + endpoint_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid + if len(endpoint_context_uuid) == 0: endpoint_context_uuid = context_uuid + if endpoint_context_uuid not in {raw_context_uuid, context_uuid}: + raise InvalidArgumentException( + 'request.service_endpoint_ids[{:d}].topology_id.context_id.context_uuid.uuid'.format(i), + endpoint_context_uuid, + ['should be == request.service_id.context_id.context_uuid.uuid({:s})'.format(raw_context_uuid)]) + service_endpoint_uuids.add(endpoint_get_uuid(endpoint_id, allow_random=False)[2]) + + now = datetime.datetime.utcnow() + constraints = compose_constraints_data(request.service_constraints, now, service_uuid=service_uuid) + config_rules = compose_config_rules_data(request.service_config.config_rules, now, service_uuid=service_uuid) + + def callback(session : Session) -> bool: + num_deletes = 0 + if len(service_endpoint_uuids) > 0: + num_deletes += session.query(ServiceEndPointModel)\ + .filter(and_( + ServiceEndPointModel.service_uuid == service_uuid, + ServiceEndPointModel.endpoint_uuid.in_(service_endpoint_uuids) + )).delete() + + changed_constraints = upsert_constraints(session, constraints, is_delete=True, service_uuid=service_uuid) + changed_config_rules = upsert_config_rules(session, config_rules, is_delete=True, service_uuid=service_uuid) + + return num_deletes > 0 or changed_constraints or changed_config_rules + + updated = run_transaction(sessionmaker(bind=db_engine), callback) + return json_service_id(service_uuid, json_context_id(context_uuid)),updated + def service_delete(db_engine : Engine, request : ServiceId) -> Tuple[Dict, bool]: context_uuid,service_uuid = service_get_uuid(request, allow_random=False) def callback(session : Session) -> bool: @@ -144,3 +193,22 @@ def service_delete(db_engine : Engine, request : ServiceId) -> Tuple[Dict, bool] return num_deleted > 0 deleted = run_transaction(sessionmaker(bind=db_engine), callback) return json_service_id(service_uuid, json_context_id(context_uuid)),deleted + +def service_select(db_engine : Engine, request : ServiceFilter) -> List[Dict]: + service_uuids = [ + service_get_uuid(service_id, allow_random=False)[1] + for service_id in request.service_ids.service_ids + ] + dump_params = dict( + include_endpoint_ids=request.include_endpoint_ids, + include_constraints =request.include_constraints, + include_config_rules=request.include_config_rules, + ) + def callback(session : Session) -> List[Dict]: + query = session.query(ServiceModel) + if request.include_endpoint_ids: query = query.options(selectinload(ServiceModel.service_endpoints)) + if request.include_constraints : query = query.options(selectinload(ServiceModel.constraints)) + if request.include_config_rules: query = query.options(selectinload(ServiceModel.config_rules)) + obj_list : List[ServiceModel] = query.filter(ServiceModel.service_uuid.in_(service_uuids)).all() + return [obj.dump(**dump_params) for obj in obj_list] + return run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/Slice.py b/src/context/service/database/Slice.py index 1d6781d53f7c85d8cb878b1b38b0de65b4ef5726..abd140024f2a13289c7af6a3bafe363a8247e053 100644 --- a/src/context/service/database/Slice.py +++ b/src/context/service/database/Slice.py @@ -16,10 +16,10 @@ import datetime, logging from sqlalchemy import and_ from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set, Tuple -from common.proto.context_pb2 import ContextId, Slice, SliceId +from common.proto.context_pb2 import ContextId, Slice, SliceFilter, SliceId from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Slice import json_slice_id @@ -44,14 +44,26 @@ def slice_list_ids(db_engine : Engine, request : ContextId) -> List[Dict]: def slice_list_objs(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: - obj_list : List[SliceModel] = session.query(SliceModel).filter_by(context_uuid=context_uuid).all() + obj_list : List[SliceModel] = session.query(SliceModel)\ + .options(selectinload(SliceModel.slice_endpoints))\ + .options(selectinload(SliceModel.slice_services))\ + .options(selectinload(SliceModel.slice_subslices))\ + .options(selectinload(SliceModel.constraints))\ + .options(selectinload(SliceModel.config_rules))\ + .filter_by(context_uuid=context_uuid).all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) def slice_get(db_engine : Engine, request : SliceId) -> Dict: _,slice_uuid = slice_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: - obj : Optional[SliceModel] = session.query(SliceModel).filter_by(slice_uuid=slice_uuid).one_or_none() + obj : Optional[SliceModel] = session.query(SliceModel)\ + .options(selectinload(SliceModel.slice_endpoints))\ + .options(selectinload(SliceModel.slice_services))\ + .options(selectinload(SliceModel.slice_subslices))\ + .options(selectinload(SliceModel.constraints))\ + .options(selectinload(SliceModel.config_rules))\ + .filter_by(slice_uuid=slice_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) if obj is None: @@ -91,6 +103,7 @@ def slice_set(db_engine : Engine, request : Slice) -> Tuple[Dict, bool]: slice_endpoints_data.append({ 'slice_uuid' : slice_uuid, 'endpoint_uuid': endpoint_uuid, + 'position' : i, }) slice_services_data : List[Dict] = list() @@ -239,3 +252,26 @@ def slice_delete(db_engine : Engine, request : SliceId) -> Tuple[Dict, bool]: return num_deleted > 0 deleted = run_transaction(sessionmaker(bind=db_engine), callback) return json_slice_id(slice_uuid, json_context_id(context_uuid)),deleted + +def slice_select(db_engine : Engine, request : SliceFilter) -> List[Dict]: + slice_uuids = [ + slice_get_uuid(slice_id, allow_random=False)[1] + for slice_id in request.slice_ids.slice_ids + ] + dump_params = dict( + include_endpoint_ids=request.include_endpoint_ids, + include_constraints =request.include_constraints, + include_service_ids =request.include_service_ids, + include_subslice_ids=request.include_subslice_ids, + include_config_rules=request.include_config_rules, + ) + def callback(session : Session) -> List[Dict]: + query = session.query(SliceModel) + if request.include_endpoint_ids: query = query.options(selectinload(SliceModel.slice_endpoints)) + if request.include_service_ids : query = query.options(selectinload(SliceModel.slice_services)) + if request.include_subslice_ids: query = query.options(selectinload(SliceModel.slice_subslices)) + if request.include_constraints : query = query.options(selectinload(SliceModel.constraints)) + if request.include_config_rules: query = query.options(selectinload(SliceModel.config_rules)) + obj_list : List[SliceModel] = query.filter(SliceModel.slice_uuid.in_(slice_uuids)).all() + return [obj.dump(**dump_params) for obj in obj_list] + return run_transaction(sessionmaker(bind=db_engine), callback) diff --git a/src/context/service/database/Topology.py b/src/context/service/database/Topology.py index e2c6e2e996ac9321d0d8b9ae2ecea018b650632f..4440299b63f68613854e79998270872389d385cb 100644 --- a/src/context/service/database/Topology.py +++ b/src/context/service/database/Topology.py @@ -15,14 +15,16 @@ import datetime, logging from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session, sessionmaker +from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Tuple from common.proto.context_pb2 import ContextId, Topology, TopologyId from common.method_wrappers.ServiceExceptions import NotFoundException from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Topology import json_topology_id -from .models.TopologyModel import TopologyModel +from .models.DeviceModel import DeviceModel +from .models.LinkModel import LinkModel +from .models.TopologyModel import TopologyDeviceModel, TopologyLinkModel, TopologyModel from .uuids.Context import context_get_uuid from .uuids.Topology import topology_get_uuid @@ -38,7 +40,10 @@ def topology_list_ids(db_engine : Engine, request : ContextId) -> List[Dict]: def topology_list_objs(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: - obj_list : List[TopologyModel] = session.query(TopologyModel).filter_by(context_uuid=context_uuid).all() + obj_list : List[TopologyModel] = session.query(TopologyModel)\ + .options(selectinload(TopologyModel.topology_devices))\ + .options(selectinload(TopologyModel.topology_links))\ + .filter_by(context_uuid=context_uuid).all() return [obj.dump() for obj in obj_list] return run_transaction(sessionmaker(bind=db_engine), callback) @@ -46,6 +51,8 @@ def topology_get(db_engine : Engine, request : TopologyId) -> Dict: _,topology_uuid = topology_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: obj : Optional[TopologyModel] = session.query(TopologyModel)\ + .options(selectinload(TopologyModel.topology_devices))\ + .options(selectinload(TopologyModel.topology_links))\ .filter_by(topology_uuid=topology_uuid).one_or_none() return None if obj is None else obj.dump() obj = run_transaction(sessionmaker(bind=db_engine), callback) @@ -62,7 +69,10 @@ def topology_get_details(db_engine : Engine, request : TopologyId) -> Dict: _,topology_uuid = topology_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: obj : Optional[TopologyModel] = session.query(TopologyModel)\ + .options(selectinload(TopologyModel.topology_devices, TopologyDeviceModel.device, DeviceModel.endpoints))\ + .options(selectinload(TopologyModel.topology_links, TopologyLinkModel.link, LinkModel.link_endpoints))\ .filter_by(topology_uuid=topology_uuid).one_or_none() + #.options(selectinload(DeviceModel.components))\ return None if obj is None else obj.dump_details() obj = run_transaction(sessionmaker(bind=db_engine), callback) if obj is None: diff --git a/src/context/service/database/models/ConfigRuleModel.py b/src/context/service/database/models/ConfigRuleModel.py index d7bb97cd0fec1037e98c8713b885b2d5141cae63..5d14b62a83b71d7a146f74e649435ed941dad6d3 100644 --- a/src/context/service/database/models/ConfigRuleModel.py +++ b/src/context/service/database/models/ConfigRuleModel.py @@ -24,13 +24,11 @@ class ConfigRuleKindEnum(enum.Enum): CUSTOM = 'custom' ACL = 'acl' -class ConfigRuleModel(_Base): - __tablename__ = 'configrule' +class DeviceConfigRuleModel(_Base): + __tablename__ = 'device_configrule' configrule_uuid = Column(UUID(as_uuid=False), primary_key=True) - device_uuid = Column(ForeignKey('device.device_uuid', ondelete='CASCADE'), nullable=True, index=True) - service_uuid = Column(ForeignKey('service.service_uuid', ondelete='CASCADE'), nullable=True, index=True) - slice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE'), nullable=True, index=True) + device_uuid = Column(ForeignKey('device.device_uuid', ondelete='CASCADE'), nullable=False) #, index=True position = Column(Integer, nullable=False) kind = Column(Enum(ConfigRuleKindEnum), nullable=False) action = Column(Enum(ORM_ConfigActionEnum), nullable=False) @@ -41,7 +39,51 @@ class ConfigRuleModel(_Base): __table_args__ = ( CheckConstraint(position >= 0, name='check_position_value'), #UniqueConstraint('device_uuid', 'position', name='unique_per_device' ), + ) + + def dump(self) -> Dict: + return { + 'action': self.action.value, + self.kind.value: json.loads(self.data), + } + +class ServiceConfigRuleModel(_Base): + __tablename__ = 'service_configrule' + + configrule_uuid = Column(UUID(as_uuid=False), primary_key=True) + service_uuid = Column(ForeignKey('service.service_uuid', ondelete='CASCADE'), nullable=False) #, index=True + position = Column(Integer, nullable=False) + kind = Column(Enum(ConfigRuleKindEnum), nullable=False) + action = Column(Enum(ORM_ConfigActionEnum), nullable=False) + data = Column(String, nullable=False) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) + + __table_args__ = ( + CheckConstraint(position >= 0, name='check_position_value'), #UniqueConstraint('service_uuid', 'position', name='unique_per_service'), + ) + + def dump(self) -> Dict: + return { + 'action': self.action.value, + self.kind.value: json.loads(self.data), + } + +class SliceConfigRuleModel(_Base): + __tablename__ = 'slice_configrule' + + configrule_uuid = Column(UUID(as_uuid=False), primary_key=True) + slice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE'), nullable=False) #, index=True + position = Column(Integer, nullable=False) + kind = Column(Enum(ConfigRuleKindEnum), nullable=False) + action = Column(Enum(ORM_ConfigActionEnum), nullable=False) + data = Column(String, nullable=False) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) + + __table_args__ = ( + CheckConstraint(position >= 0, name='check_position_value'), #UniqueConstraint('slice_uuid', 'position', name='unique_per_slice' ), ) diff --git a/src/context/service/database/models/ConnectionModel.py b/src/context/service/database/models/ConnectionModel.py index 156e33c6bb32e237af241035f1d9672b0b419222..f71d4177893d146af2f413781b51930c9909d827 100644 --- a/src/context/service/database/models/ConnectionModel.py +++ b/src/context/service/database/models/ConnectionModel.py @@ -59,8 +59,8 @@ class ConnectionEndPointModel(_Base): endpoint_uuid = Column(ForeignKey('endpoint.endpoint_uuid', ondelete='RESTRICT'), primary_key=True, index=True) position = Column(Integer, nullable=False) - connection = relationship('ConnectionModel', back_populates='connection_endpoints', lazy='joined') - endpoint = relationship('EndPointModel', lazy='joined') # back_populates='connection_endpoints' + connection = relationship('ConnectionModel', back_populates='connection_endpoints') #, lazy='joined' + endpoint = relationship('EndPointModel', lazy='selectin') # back_populates='connection_endpoints' __table_args__ = ( CheckConstraint(position >= 0, name='check_position_value'), @@ -72,5 +72,5 @@ class ConnectionSubServiceModel(_Base): connection_uuid = Column(ForeignKey('connection.connection_uuid', ondelete='CASCADE' ), primary_key=True) subservice_uuid = Column(ForeignKey('service.service_uuid', ondelete='RESTRICT'), primary_key=True, index=True) - connection = relationship('ConnectionModel', back_populates='connection_subservices', lazy='joined') - subservice = relationship('ServiceModel', lazy='joined') # back_populates='connection_subservices' + connection = relationship('ConnectionModel', back_populates='connection_subservices') #, lazy='joined' + subservice = relationship('ServiceModel', lazy='selectin') # back_populates='connection_subservices' diff --git a/src/context/service/database/models/ConstraintModel.py b/src/context/service/database/models/ConstraintModel.py index 2412080c1a2883e7bed85e6e22f389270b3f73bc..d093e782adde23092d9c9d3949f9153c8ee9d4f3 100644 --- a/src/context/service/database/models/ConstraintModel.py +++ b/src/context/service/database/models/ConstraintModel.py @@ -30,13 +30,13 @@ class ConstraintKindEnum(enum.Enum): SLA_LATENCY = 'sla_latency' SLA_AVAILABILITY = 'sla_availability' SLA_ISOLATION = 'sla_isolation' + EXCLUSIONS = 'exclusions' -class ConstraintModel(_Base): - __tablename__ = 'constraint' +class ServiceConstraintModel(_Base): + __tablename__ = 'service_constraint' constraint_uuid = Column(UUID(as_uuid=False), primary_key=True) - service_uuid = Column(ForeignKey('service.service_uuid', ondelete='CASCADE'), nullable=True, index=True) - slice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE'), nullable=True, index=True) + service_uuid = Column(ForeignKey('service.service_uuid', ondelete='CASCADE'), nullable=False) #, index=True position = Column(Integer, nullable=False) kind = Column(Enum(ConstraintKindEnum), nullable=False) data = Column(String, nullable=False) @@ -46,6 +46,24 @@ class ConstraintModel(_Base): __table_args__ = ( CheckConstraint(position >= 0, name='check_position_value'), #UniqueConstraint('service_uuid', 'position', name='unique_per_service'), + ) + + def dump(self) -> Dict: + return {self.kind.value: json.loads(self.data)} + +class SliceConstraintModel(_Base): + __tablename__ = 'slice_constraint' + + constraint_uuid = Column(UUID(as_uuid=False), primary_key=True) + slice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE'), nullable=False) #, index=True + position = Column(Integer, nullable=False) + kind = Column(Enum(ConstraintKindEnum), nullable=False) + data = Column(String, nullable=False) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) + + __table_args__ = ( + CheckConstraint(position >= 0, name='check_position_value'), #UniqueConstraint('slice_uuid', 'position', name='unique_per_slice' ), ) diff --git a/src/context/service/database/models/DeviceModel.py b/src/context/service/database/models/DeviceModel.py index 2124386d16e2e33aec58f5b39bf0f89e3c6589f1..1097d0b9ab47a86c47ce2ad8394d067ae9f9953e 100644 --- a/src/context/service/database/models/DeviceModel.py +++ b/src/context/service/database/models/DeviceModel.py @@ -13,10 +13,10 @@ # limitations under the License. import operator -from sqlalchemy import Column, DateTime, Enum, String +from sqlalchemy import Column, DateTime, Enum, ForeignKey, String from sqlalchemy.dialects.postgresql import ARRAY, UUID from sqlalchemy.orm import relationship -from typing import Dict +from typing import Dict, List from .enums.DeviceDriver import ORM_DeviceDriverEnum from .enums.DeviceOperationalStatus import ORM_DeviceOperationalStatusEnum from ._Base import _Base @@ -29,29 +29,46 @@ class DeviceModel(_Base): device_type = Column(String, nullable=False) device_operational_status = Column(Enum(ORM_DeviceOperationalStatusEnum), nullable=False) device_drivers = Column(ARRAY(Enum(ORM_DeviceDriverEnum), dimensions=1)) + controller_uuid = Column(UUID(as_uuid=False), ForeignKey('device.device_uuid'), nullable=True) created_at = Column(DateTime, nullable=False) updated_at = Column(DateTime, nullable=False) #topology_devices = relationship('TopologyDeviceModel', back_populates='device') - config_rules = relationship('ConfigRuleModel', passive_deletes=True) # lazy='joined', back_populates='device' + config_rules = relationship('DeviceConfigRuleModel', passive_deletes=True) # lazy='joined', back_populates='device' endpoints = relationship('EndPointModel', passive_deletes=True) # lazy='joined', back_populates='device' + controller = relationship('DeviceModel', remote_side=[device_uuid], passive_deletes=True) # lazy='joined', back_populates='device' def dump_id(self) -> Dict: return {'device_uuid': {'uuid': self.device_uuid}} - def dump(self) -> Dict: - return { + def dump_controller(self) -> Dict: + if self.controller is None: return {} + return self.controller.dump_id() + + def dump_endpoints(self) -> List[Dict]: + return [endpoint.dump() for endpoint in self.endpoints] + + def dump_config_rules(self) -> Dict: + return {'config_rules': [ + config_rule.dump() + for config_rule in sorted(self.config_rules, key=operator.attrgetter('position')) + ]} + + def dump_components(self) -> List[Dict]: + return [] + + def dump(self, + include_endpoints : bool = True, include_config_rules : bool = True, include_components : bool = True, + ) -> Dict: + result = { 'device_id' : self.dump_id(), 'name' : self.device_name, 'device_type' : self.device_type, 'device_operational_status': self.device_operational_status.value, 'device_drivers' : [driver.value for driver in self.device_drivers], - 'device_config' : {'config_rules': [ - config_rule.dump() - for config_rule in sorted(self.config_rules, key=operator.attrgetter('position')) - ]}, - 'device_endpoints' : [ - endpoint.dump() - for endpoint in self.endpoints - ], + 'controller_id' : self.dump_controller(), } + if include_endpoints: result['device_endpoints'] = self.dump_endpoints() + if include_config_rules: result['device_config'] = self.dump_config_rules() + if include_components: result['component'] = self.dump_components() + return result diff --git a/src/context/service/database/models/EndPointModel.py b/src/context/service/database/models/EndPointModel.py index 12ba7e10e7c3d5789f9bf16ad7b4f50c35a36bf5..a079f9900e39fdf3a4329e604f4e596e7f5d1f89 100644 --- a/src/context/service/database/models/EndPointModel.py +++ b/src/context/service/database/models/EndPointModel.py @@ -31,8 +31,8 @@ class EndPointModel(_Base): created_at = Column(DateTime, nullable=False) updated_at = Column(DateTime, nullable=False) - device = relationship('DeviceModel', back_populates='endpoints') - topology = relationship('TopologyModel') + device = relationship('DeviceModel', back_populates='endpoints') # lazy='selectin' + topology = relationship('TopologyModel', lazy='selectin') #link_endpoints = relationship('LinkEndPointModel', back_populates='endpoint' ) #service_endpoints = relationship('ServiceEndPointModel', back_populates='endpoint' ) diff --git a/src/context/service/database/models/LinkModel.py b/src/context/service/database/models/LinkModel.py index ee591f5c8404cd7f0f6c97651b5f731a51c43303..9c16da3c9146f28352e8b4f7a6f9ab85f870c8b7 100644 --- a/src/context/service/database/models/LinkModel.py +++ b/src/context/service/database/models/LinkModel.py @@ -12,7 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -from sqlalchemy import Column, DateTime, ForeignKey, String +import operator +from sqlalchemy import CheckConstraint, Column, DateTime, ForeignKey, Integer, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from typing import Dict @@ -38,7 +39,7 @@ class LinkModel(_Base): 'name' : self.link_name, 'link_endpoint_ids': [ link_endpoint.endpoint.dump_id() - for link_endpoint in self.link_endpoints + for link_endpoint in sorted(self.link_endpoints, key=operator.attrgetter('position')) ], } @@ -47,6 +48,11 @@ class LinkEndPointModel(_Base): link_uuid = Column(ForeignKey('link.link_uuid', ondelete='CASCADE' ), primary_key=True) endpoint_uuid = Column(ForeignKey('endpoint.endpoint_uuid', ondelete='RESTRICT'), primary_key=True, index=True) + position = Column(Integer, nullable=False) - link = relationship('LinkModel', back_populates='link_endpoints', lazy='joined') - endpoint = relationship('EndPointModel', lazy='joined') # back_populates='link_endpoints' + link = relationship('LinkModel', back_populates='link_endpoints') #, lazy='selectin' + endpoint = relationship('EndPointModel', lazy='selectin') # back_populates='link_endpoints' + + __table_args__ = ( + CheckConstraint(position >= 0, name='check_position_value'), + ) diff --git a/src/context/service/database/models/PolicyRuleModel.py b/src/context/service/database/models/PolicyRuleModel.py index 2f0c8a326a57a05ab1fd623a968dea0bc39d9e76..32364e289cf68fe760c60eb27cde933f7cf448a4 100644 --- a/src/context/service/database/models/PolicyRuleModel.py +++ b/src/context/service/database/models/PolicyRuleModel.py @@ -64,7 +64,7 @@ class PolicyRuleModel(_Base): 'deviceList': [{'device_uuid': {'uuid': pr_d.device_uuid}} for pr_d in self.policyrule_devices], } if self.policyrule_kind == PolicyRuleKindEnum.SERVICE: - result['serviceId'] = self.policyrule_service.dump_id(), + result['serviceId'] = self.policyrule_service.dump_id() return {self.policyrule_kind.value: result} class PolicyRuleDeviceModel(_Base): @@ -74,4 +74,4 @@ class PolicyRuleDeviceModel(_Base): device_uuid = Column(ForeignKey('device.device_uuid', ondelete='RESTRICT'), primary_key=True, index=True) #policyrule = relationship('PolicyRuleModel', lazy='joined') # back_populates='policyrule_devices' - device = relationship('DeviceModel', lazy='joined') # back_populates='policyrule_devices' + device = relationship('DeviceModel', lazy='selectin') # back_populates='policyrule_devices' diff --git a/src/context/service/database/models/ServiceModel.py b/src/context/service/database/models/ServiceModel.py index 09ff381b5eb374ea752590bba5403fe816319036..2895a7ce9ddfeefd025a9397040a01423c9682a4 100644 --- a/src/context/service/database/models/ServiceModel.py +++ b/src/context/service/database/models/ServiceModel.py @@ -13,10 +13,10 @@ # limitations under the License. import operator -from sqlalchemy import Column, DateTime, Enum, ForeignKey, String +from sqlalchemy import CheckConstraint, Column, DateTime, Enum, ForeignKey, Integer, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship -from typing import Dict +from typing import Dict, List from .enums.ServiceStatus import ORM_ServiceStatusEnum from .enums.ServiceType import ORM_ServiceTypeEnum from ._Base import _Base @@ -32,10 +32,10 @@ class ServiceModel(_Base): created_at = Column(DateTime, nullable=False) updated_at = Column(DateTime, nullable=False) - context = relationship('ContextModel', back_populates='services') - service_endpoints = relationship('ServiceEndPointModel') # lazy='joined', back_populates='service' - constraints = relationship('ConstraintModel', passive_deletes=True) # lazy='joined', back_populates='service' - config_rules = relationship('ConfigRuleModel', passive_deletes=True) # lazy='joined', back_populates='service' + context = relationship('ContextModel', back_populates='services', lazy='selectin') + service_endpoints = relationship('ServiceEndPointModel') # lazy='selectin', back_populates='service' + constraints = relationship('ServiceConstraintModel', passive_deletes=True) # lazy='selectin', back_populates='service' + config_rules = relationship('ServiceConfigRuleModel', passive_deletes=True) # lazy='selectin', back_populates='service' def dump_id(self) -> Dict: return { @@ -43,31 +43,48 @@ class ServiceModel(_Base): 'service_uuid': {'uuid': self.service_uuid}, } - def dump(self) -> Dict: - return { - 'service_id' : self.dump_id(), - 'name' : self.service_name, - 'service_type' : self.service_type.value, - 'service_status' : {'service_status': self.service_status.value}, - 'service_endpoint_ids': [ - service_endpoint.endpoint.dump_id() - for service_endpoint in self.service_endpoints - ], - 'service_constraints' : [ - constraint.dump() - for constraint in sorted(self.constraints, key=operator.attrgetter('position')) - ], - 'service_config' : {'config_rules': [ - config_rule.dump() - for config_rule in sorted(self.config_rules, key=operator.attrgetter('position')) - ]}, + def dump_endpoint_ids(self) -> List[Dict]: + return [ + service_endpoint.endpoint.dump_id() + for service_endpoint in sorted(self.service_endpoints, key=operator.attrgetter('position')) + ] + + def dump_constraints(self) -> List[Dict]: + return [ + constraint.dump() + for constraint in sorted(self.constraints, key=operator.attrgetter('position')) + ] + + def dump_config_rules(self) -> Dict: + return {'config_rules': [ + config_rule.dump() + for config_rule in sorted(self.config_rules, key=operator.attrgetter('position')) + ]} + + def dump( + self, include_endpoint_ids : bool = True, include_constraints : bool = True, include_config_rules : bool = True + ) -> Dict: + result = { + 'service_id' : self.dump_id(), + 'name' : self.service_name, + 'service_type' : self.service_type.value, + 'service_status': {'service_status': self.service_status.value}, } + if include_endpoint_ids: result['service_endpoint_ids'] = self.dump_endpoint_ids() + if include_constraints: result['service_constraints'] = self.dump_constraints() + if include_config_rules: result['service_config'] = self.dump_config_rules() + return result class ServiceEndPointModel(_Base): __tablename__ = 'service_endpoint' service_uuid = Column(ForeignKey('service.service_uuid', ondelete='CASCADE' ), primary_key=True) endpoint_uuid = Column(ForeignKey('endpoint.endpoint_uuid', ondelete='RESTRICT'), primary_key=True, index=True) + position = Column(Integer, nullable=False) + + service = relationship('ServiceModel', back_populates='service_endpoints') # lazy='selectin' + endpoint = relationship('EndPointModel', lazy='selectin') # back_populates='service_endpoints' - service = relationship('ServiceModel', back_populates='service_endpoints', lazy='joined') - endpoint = relationship('EndPointModel', lazy='joined') # back_populates='service_endpoints' + __table_args__ = ( + CheckConstraint(position >= 0, name='check_position_value'), + ) diff --git a/src/context/service/database/models/SliceModel.py b/src/context/service/database/models/SliceModel.py index 2d6c884169154fee8d44c26464416c6708c650b1..d3befa66b4c7ecba4a28fefa745a7c2214f37caf 100644 --- a/src/context/service/database/models/SliceModel.py +++ b/src/context/service/database/models/SliceModel.py @@ -13,10 +13,10 @@ # limitations under the License. import operator -from sqlalchemy import Column, DateTime, Enum, ForeignKey, String +from sqlalchemy import CheckConstraint, Column, DateTime, Enum, ForeignKey, Integer, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship -from typing import Dict +from typing import Dict, List from .enums.SliceStatus import ORM_SliceStatusEnum from ._Base import _Base @@ -32,13 +32,13 @@ class SliceModel(_Base): created_at = Column(DateTime, nullable=False) updated_at = Column(DateTime, nullable=False) - context = relationship('ContextModel', back_populates='slices') - slice_endpoints = relationship('SliceEndPointModel') # lazy='joined', back_populates='slice' - slice_services = relationship('SliceServiceModel') # lazy='joined', back_populates='slice' + context = relationship('ContextModel', back_populates='slices', lazy='selectin') + slice_endpoints = relationship('SliceEndPointModel') # lazy='selectin', back_populates='slice' + slice_services = relationship('SliceServiceModel') # lazy='selectin', back_populates='slice' slice_subslices = relationship( 'SliceSubSliceModel', primaryjoin='slice.c.slice_uuid == slice_subslice.c.slice_uuid') - constraints = relationship('ConstraintModel', passive_deletes=True) # lazy='joined', back_populates='slice' - config_rules = relationship('ConfigRuleModel', passive_deletes=True) # lazy='joined', back_populates='slice' + constraints = relationship('SliceConstraintModel', passive_deletes=True) # lazy='selectin', back_populates='slice' + config_rules = relationship('SliceConfigRuleModel', passive_deletes=True) # lazy='selectin', back_populates='slice' def dump_id(self) -> Dict: return { @@ -46,45 +46,72 @@ class SliceModel(_Base): 'slice_uuid': {'uuid': self.slice_uuid}, } - def dump(self) -> Dict: + def dump_endpoint_ids(self) -> List[Dict]: + return [ + slice_endpoint.endpoint.dump_id() + for slice_endpoint in sorted(self.slice_endpoints, key=operator.attrgetter('position')) + ] + + def dump_constraints(self) -> List[Dict]: + return [ + constraint.dump() + for constraint in sorted(self.constraints, key=operator.attrgetter('position')) + ] + + def dump_config_rules(self) -> Dict: + return {'config_rules': [ + config_rule.dump() + for config_rule in sorted(self.config_rules, key=operator.attrgetter('position')) + ]} + + def dump_service_ids(self) -> List[Dict]: + return [ + slice_service.service.dump_id() + for slice_service in self.slice_services + ] + + def dump_subslice_ids(self) -> List[Dict]: + return [ + slice_subslice.subslice.dump_id() + for slice_subslice in self.slice_subslices + ] + + def dump_owner_id(self) -> Dict: return { - 'slice_id' : self.dump_id(), - 'name' : self.slice_name, - 'slice_status' : {'slice_status': self.slice_status.value}, - 'slice_endpoint_ids': [ - slice_endpoint.endpoint.dump_id() - for slice_endpoint in self.slice_endpoints - ], - 'slice_constraints' : [ - constraint.dump() - for constraint in sorted(self.constraints, key=operator.attrgetter('position')) - ], - 'slice_config' : {'config_rules': [ - config_rule.dump() - for config_rule in sorted(self.config_rules, key=operator.attrgetter('position')) - ]}, - 'slice_service_ids': [ - slice_service.service.dump_id() - for slice_service in self.slice_services - ], - 'slice_subslice_ids': [ - slice_subslice.subslice.dump_id() - for slice_subslice in self.slice_subslices - ], - 'slice_owner': { - 'owner_uuid': {'uuid': self.slice_owner_uuid}, - 'owner_string': self.slice_owner_string - } + 'owner_uuid': {'uuid': self.slice_owner_uuid}, + 'owner_string': self.slice_owner_string + } + + def dump( + self, include_endpoint_ids : bool = True, include_constraints : bool = True, include_service_ids : bool = True, + include_subslice_ids : bool = True, include_config_rules : bool = True + ) -> Dict: + result = { + 'slice_id' : self.dump_id(), + 'name' : self.slice_name, + 'slice_status': {'slice_status': self.slice_status.value}, + 'slice_owner' : self.dump_owner_id() } + if include_endpoint_ids: result['slice_endpoint_ids'] = self.dump_endpoint_ids() + if include_constraints : result['slice_constraints' ] = self.dump_constraints() + if include_service_ids : result['slice_service_ids' ] = self.dump_service_ids() + if include_subslice_ids: result['slice_subslice_ids'] = self.dump_subslice_ids() + if include_config_rules: result['slice_config' ] = self.dump_config_rules() + return result class SliceEndPointModel(_Base): __tablename__ = 'slice_endpoint' slice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE' ), primary_key=True) endpoint_uuid = Column(ForeignKey('endpoint.endpoint_uuid', ondelete='RESTRICT'), primary_key=True, index=True) + position = Column(Integer, nullable=False) + + slice = relationship('SliceModel', back_populates='slice_endpoints') #, lazy='selectin' + endpoint = relationship('EndPointModel', lazy='selectin') # back_populates='slice_endpoints' - slice = relationship('SliceModel', back_populates='slice_endpoints', lazy='joined') - endpoint = relationship('EndPointModel', lazy='joined') # back_populates='slice_endpoints' + __table_args__ = ( + CheckConstraint(position >= 0, name='check_position_value'), + ) class SliceServiceModel(_Base): __tablename__ = 'slice_service' @@ -92,8 +119,8 @@ class SliceServiceModel(_Base): slice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE' ), primary_key=True) service_uuid = Column(ForeignKey('service.service_uuid', ondelete='RESTRICT'), primary_key=True, index=True) - slice = relationship('SliceModel', back_populates='slice_services', lazy='joined') - service = relationship('ServiceModel', lazy='joined') # back_populates='slice_services' + slice = relationship('SliceModel', back_populates='slice_services') # , lazy='selectin' + service = relationship('ServiceModel', lazy='selectin') # back_populates='slice_services' class SliceSubSliceModel(_Base): __tablename__ = 'slice_subslice' @@ -102,5 +129,5 @@ class SliceSubSliceModel(_Base): subslice_uuid = Column(ForeignKey('slice.slice_uuid', ondelete='CASCADE'), primary_key=True, index=True) slice = relationship( - 'SliceModel', foreign_keys='SliceSubSliceModel.slice_uuid', back_populates='slice_subslices', lazy='joined') - subslice = relationship('SliceModel', foreign_keys='SliceSubSliceModel.subslice_uuid', lazy='joined') + 'SliceModel', foreign_keys='SliceSubSliceModel.slice_uuid', back_populates='slice_subslices') #, lazy='selectin' + subslice = relationship('SliceModel', foreign_keys='SliceSubSliceModel.subslice_uuid', lazy='selectin') diff --git a/src/context/service/database/models/TopologyModel.py b/src/context/service/database/models/TopologyModel.py index 7dc2333f0a9b979f251c173d850a235dcb822d91..0ed4a038bcf4426f4cf112bd03c5cb36cb42c822 100644 --- a/src/context/service/database/models/TopologyModel.py +++ b/src/context/service/database/models/TopologyModel.py @@ -27,7 +27,7 @@ class TopologyModel(_Base): created_at = Column(DateTime, nullable=False) updated_at = Column(DateTime, nullable=False) - context = relationship('ContextModel', back_populates='topologies') + context = relationship('ContextModel', back_populates='topologies', lazy='selectin') topology_devices = relationship('TopologyDeviceModel') # back_populates='topology' topology_links = relationship('TopologyLinkModel' ) # back_populates='topology' @@ -46,11 +46,19 @@ class TopologyModel(_Base): } def dump_details(self) -> Dict: + devices = [ + td.device.dump(include_config_rules=False, include_components=False) + for td in self.topology_devices + ] + links = [ + tl.link.dump() + for tl in self.topology_links + ] return { 'topology_id': self.dump_id(), 'name' : self.topology_name, - 'devices' : [td.device.dump() for td in self.topology_devices], - 'links' : [tl.link.dump() for tl in self.topology_links ], + 'devices' : devices, + 'links' : links, } class TopologyDeviceModel(_Base): @@ -59,8 +67,8 @@ class TopologyDeviceModel(_Base): topology_uuid = Column(ForeignKey('topology.topology_uuid', ondelete='RESTRICT'), primary_key=True, index=True) device_uuid = Column(ForeignKey('device.device_uuid', ondelete='CASCADE' ), primary_key=True, index=True) - #topology = relationship('TopologyModel', lazy='joined') # back_populates='topology_devices' - device = relationship('DeviceModel', lazy='joined') # back_populates='topology_devices' + #topology = relationship('TopologyModel', lazy='selectin') # back_populates='topology_devices' + device = relationship('DeviceModel', lazy='selectin') # back_populates='topology_devices' class TopologyLinkModel(_Base): __tablename__ = 'topology_link' @@ -68,5 +76,5 @@ class TopologyLinkModel(_Base): topology_uuid = Column(ForeignKey('topology.topology_uuid', ondelete='RESTRICT'), primary_key=True, index=True) link_uuid = Column(ForeignKey('link.link_uuid', ondelete='CASCADE' ), primary_key=True, index=True) - #topology = relationship('TopologyModel', lazy='joined') # back_populates='topology_links' - link = relationship('LinkModel', lazy='joined') # back_populates='topology_links' + #topology = relationship('TopologyModel', lazy='selectin') # back_populates='topology_links' + link = relationship('LinkModel', lazy='selectin') # back_populates='topology_links' diff --git a/src/context/service/database/models/_Base.py b/src/context/service/database/models/_Base.py index a10de60eb8731132ec815de1ff897c06ac12b665..b87b9b06d6adc5825ab5dd84cf64347eb9c26f66 100644 --- a/src/context/service/database/models/_Base.py +++ b/src/context/service/database/models/_Base.py @@ -30,23 +30,23 @@ def create_performance_enhancers(db_engine : sqlalchemy.engine.Engine) -> None: return text(INDEX_STORING.format(index_name, table_name, str_index_fields, str_storing_fields)) statements = [ - index_storing('configrule_device_uuid_rec_idx', 'configrule', ['device_uuid'], [ - 'service_uuid', 'slice_uuid', 'position', 'kind', 'action', 'data', 'created_at', 'updated_at' + index_storing('device_configrule_device_uuid_rec_idx', 'device_configrule', ['device_uuid'], [ + 'position', 'kind', 'action', 'data', 'created_at', 'updated_at' ]), - index_storing('configrule_service_uuid_rec_idx', 'configrule', ['service_uuid'], [ - 'device_uuid', 'slice_uuid', 'position', 'kind', 'action', 'data', 'created_at', 'updated_at' + index_storing('service_configrule_service_uuid_rec_idx', 'service_configrule', ['service_uuid'], [ + 'position', 'kind', 'action', 'data', 'created_at', 'updated_at' ]), - index_storing('configrule_slice_uuid_rec_idx', 'configrule', ['slice_uuid'], [ - 'device_uuid', 'service_uuid', 'position', 'kind', 'action', 'data', 'created_at', 'updated_at' + index_storing('slice_configrule_slice_uuid_rec_idx', 'slice_configrule', ['slice_uuid'], [ + 'position', 'kind', 'action', 'data', 'created_at', 'updated_at' ]), index_storing('connection_service_uuid_rec_idx', 'connection', ['service_uuid'], [ 'settings', 'created_at', 'updated_at' ]), - index_storing('constraint_service_uuid_rec_idx', 'constraint', ['service_uuid'], [ - 'slice_uuid', 'position', 'kind', 'data', 'created_at', 'updated_at' + index_storing('service_constraint_service_uuid_rec_idx', 'service_constraint', ['service_uuid'], [ + 'position', 'kind', 'data', 'created_at', 'updated_at' ]), - index_storing('constraint_slice_uuid_rec_idx', 'constraint', ['slice_uuid'], [ - 'service_uuid', 'position', 'kind', 'data', 'created_at', 'updated_at' + index_storing('slice_constraint_slice_uuid_rec_idx', 'slice_constraint', ['slice_uuid'], [ + 'position', 'kind', 'data', 'created_at', 'updated_at' ]), index_storing('endpoint_device_uuid_rec_idx', 'endpoint', ['device_uuid'], [ 'topology_uuid', 'name', 'endpoint_type', 'kpi_sample_types', 'created_at', 'updated_at' @@ -57,7 +57,6 @@ def create_performance_enhancers(db_engine : sqlalchemy.engine.Engine) -> None: index_storing('slice_context_uuid_rec_idx', 'slice', ['context_uuid'], [ 'slice_name', 'slice_status', 'slice_owner_uuid', 'slice_owner_string', 'created_at', 'updated_at' ]), - index_storing('topology_context_uuid_rec_idx', 'topology', ['context_uuid'], [ 'topology_name', 'created_at', 'updated_at' ]), diff --git a/src/context/service/database/models/enums/DeviceDriver.py b/src/context/service/database/models/enums/DeviceDriver.py index 6997e7dfbff6bc1d4b6452a28f11cdac9aae412f..a612803e235de2c6d2d8c91052416a675a3a3085 100644 --- a/src/context/service/database/models/enums/DeviceDriver.py +++ b/src/context/service/database/models/enums/DeviceDriver.py @@ -24,6 +24,7 @@ class ORM_DeviceDriverEnum(enum.Enum): IETF_NETWORK_TOPOLOGY = DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY ONF_TR_352 = DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352 XR = DeviceDriverEnum.DEVICEDRIVER_XR + IETF_L2VPN = DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN grpc_to_enum__device_driver = functools.partial( grpc_to_enum, DeviceDriverEnum, ORM_DeviceDriverEnum) diff --git a/src/context/service/database/models/enums/ServiceStatus.py b/src/context/service/database/models/enums/ServiceStatus.py index 00ae71f7460fd76a3b8e0f3a981d2e2d08f89e7b..cd2a183b825eff54a51a844ea6834263bbabbc31 100644 --- a/src/context/service/database/models/enums/ServiceStatus.py +++ b/src/context/service/database/models/enums/ServiceStatus.py @@ -20,7 +20,9 @@ class ORM_ServiceStatusEnum(enum.Enum): UNDEFINED = ServiceStatusEnum.SERVICESTATUS_UNDEFINED PLANNED = ServiceStatusEnum.SERVICESTATUS_PLANNED ACTIVE = ServiceStatusEnum.SERVICESTATUS_ACTIVE + UPDATING = ServiceStatusEnum.SERVICESTATUS_UPDATING PENDING_REMOVAL = ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL + SLA_VIOLATED = ServiceStatusEnum.SERVICESTATUS_SLA_VIOLATED grpc_to_enum__service_status = functools.partial( grpc_to_enum, ServiceStatusEnum, ORM_ServiceStatusEnum) diff --git a/src/dbscanserving/.gitlab-ci.yml b/src/dbscanserving/.gitlab-ci.yml index 0acb3e0a7ffb339e800092020fcb2616b3044b15..5d5204cdd26d56aa8e47f056c8f3b84db1a1ceb3 100644 --- a/src/dbscanserving/.gitlab-ci.yml +++ b/src/dbscanserving/.gitlab-ci.yml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# build, tag and push the Docker image to the gitlab registry +# Build, tag, and push the Docker image to the GitLab Docker registry build dbscanserving: variables: IMAGE_NAME: 'dbscanserving' # name of the microservice @@ -21,24 +21,23 @@ build dbscanserving: before_script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY script: - - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/ + - docker 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"' + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - changes: - 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 -# apply unit test to the dbscanserving component -unit test dbscanserving: +# Apply unit test to the component +unit_test dbscanserving: variables: IMAGE_NAME: 'dbscanserving' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) @@ -48,14 +47,17 @@ unit test dbscanserving: 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 + - if docker container ls | grep $IMAGE_NAME; then docker rm -f $IMAGE_NAME; else echo "$IMAGE_NAME container is not in the system"; fi script: - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" - - docker run --name $IMAGE_NAME -d -p 10006:10006 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge --rm $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG + - docker run --name $IMAGE_NAME -d -p 10008:10008 -v "$PWD/src/$IMAGE_NAME/tests:/home/${IMAGE_NAME}/results" --network=teraflowbridge --rm $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 -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml" + - docker exec ps -a + - sleep 5 + - docker logs $IMAGE_NAME + - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/home/${IMAGE_NAME}/results/${IMAGE_NAME}_report.xml" - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing" coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' after_script: @@ -78,27 +80,27 @@ unit test dbscanserving: # Deployment of the dbscanserving service in Kubernetes Cluster -deploy dbscanserving: - variables: - IMAGE_NAME: 'dbscanserving' # name of the microservice - IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) - stage: deploy - needs: - - unit test dbscanserving - # - 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 \ No newline at end of file +# deploy dbscanserving: +# variables: +# IMAGE_NAME: 'dbscanserving' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test dbscanserving +# # - 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 \ No newline at end of file diff --git a/src/dbscanserving/Config.py b/src/dbscanserving/Config.py index e7f7904b0b12cb58cf82d97d2247e57ed339b247..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dbscanserving/Config.py +++ b/src/dbscanserving/Config.py @@ -11,16 +11,3 @@ # 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 - -# General settings -LOG_LEVEL = logging.DEBUG - -# gRPC settings -GRPC_SERVICE_PORT = 10006 -GRPC_MAX_WORKERS = 10 -GRPC_GRACE_PERIOD = 60 - -# Prometheus settings -METRICS_PORT = 9192 diff --git a/src/dbscanserving/Dockerfile b/src/dbscanserving/Dockerfile index 8328ff4d5ecf8dd373bb5b5e4534c941d6307146..81e3fb28a059faf92f793aa5bd76d1a744e65d9b 100644 --- a/src/dbscanserving/Dockerfile +++ b/src/dbscanserving/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM python:3-slim +FROM python:3.9-slim # Install dependencies RUN apt-get --yes --quiet --quiet update && \ @@ -27,22 +27,56 @@ RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe +# Creating a user for security reasons +RUN groupadd -r teraflow && useradd -u 1001 --no-log-init -r -m -g teraflow teraflow +USER teraflow + +# set working directory +RUN mkdir -p /home/teraflow/controller/common +WORKDIR /home/teraflow/controller + +# Get Python packages per module +ENV VIRTUAL_ENV=/home/teraflow/venv +RUN python3 -m venv ${VIRTUAL_ENV} +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" + # Get generic Python packages -RUN python3 -m pip install --upgrade pip setuptools wheel pip-tools +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 +COPY --chown=teraflow:teraflow 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 /home/teraflow/controller/common +COPY --chown=teraflow:teraflow src/common/. ./ +RUN rm -rf proto -# Set working directory -WORKDIR /var/teraflow +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /home/teraflow/controller/common/proto +WORKDIR /home/teraflow/controller/common/proto +RUN touch __init__.py +COPY --chown=teraflow:teraflow 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 module sub-folders -RUN mkdir -p /var/teraflow/dbscanserving +RUN mkdir -p /home/teraflow/controller/dbscanserving +WORKDIR /home/teraflow/controller # Get Python packages per module -COPY dbscanserving/requirements.in dbscanserving/requirements.in -RUN pip-compile --output-file=dbscanserving/requirements.txt dbscanserving/requirements.in +COPY --chown=teraflow:teraflow ./src/dbscanserving/requirements.in dbscanserving/requirements.in +# consider common and specific requirements to avoid inconsistencies with dependencies +RUN pip-compile --quiet --output-file=dbscanserving/requirements.txt dbscanserving/requirements.in common_requirements.in RUN python3 -m pip install -r dbscanserving/requirements.txt -COPY common/. common -COPY dbscanserving/. dbscanserving +# Add component files into working directory +COPY --chown=teraflow:teraflow ./src/dbscanserving/. dbscanserving -# Start dbscanserving service +# Start the service ENTRYPOINT ["python", "-m", "dbscanserving.service"] diff --git a/src/dbscanserving/__init__.py b/src/dbscanserving/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dbscanserving/__init__.py +++ b/src/dbscanserving/__init__.py @@ -11,4 +11,3 @@ # 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/dbscanserving/client/DbscanServingClient.py b/src/dbscanserving/client/DbscanServingClient.py index ce259d0f25dc2515ed49537f5527443cb552c7c1..d8a74948d8c68b1ffabb1fc12c7d04a4817b90e0 100644 --- a/src/dbscanserving/client/DbscanServingClient.py +++ b/src/dbscanserving/client/DbscanServingClient.py @@ -12,37 +12,62 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging -from common.tools.client.RetryDecorator import retry, delay_exponential -from dbscanserving.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse -from dbscanserving.proto.dbscanserving_pb2_grpc import DetectorStub +import logging +from typing import Counter + +import grpc + +from common.Constants import ServiceNameEnum +from common.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse +from common.proto.dbscanserving_pb2_grpc import DetectorStub +from common.Settings import get_service_host, get_service_port_grpc +from common.tools.client.RetryDecorator import delay_exponential, retry 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') +RETRY_DECORATOR = retry( + max_retries=MAX_RETRIES, + delay_function=DELAY_FUNCTION, + prepare_method_name="connect", +) + class DbscanServingClient: - def __init__(self, address, port): - self.endpoint = '{:s}:{:s}'.format(str(address), str(port)) - LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint))) + def __init__(self, host=None, port=None): + if not host: + host = get_service_host(ServiceNameEnum.DBSCANSERVING) + if not port: + port = get_service_port_grpc(ServiceNameEnum.DBSCANSERVING) + + 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.connect() - LOGGER.debug('Channel created') + LOGGER.debug("Channel created") def connect(self): self.channel = grpc.insecure_channel(self.endpoint) self.stub = DetectorStub(self.channel) def close(self): - if(self.channel is not None): self.channel.close() + if self.channel is not None: + self.channel.close() self.channel = None self.stub = None @RETRY_DECORATOR - def Detect(self, request : DetectionRequest) -> DetectionResponse: - LOGGER.debug('Detect request: {:s}'.format(str(request))) - response = self.stub.Detect(request) - LOGGER.debug('Detect result: {:s}'.format(str(response))) + def Detect(self, request: DetectionRequest) -> DetectionResponse: + LOGGER.debug( + "Detect request with {} samples and {} features".format( + request.num_samples, request.num_features + ) + ) + response: DetectionResponse = self.stub.Detect(request) + LOGGER.debug( + "Detect result with {} cluster indices [{}]".format( + len(response.cluster_indices), Counter(response.cluster_indices) + ) + ) return response diff --git a/src/dbscanserving/client/__init__.py b/src/dbscanserving/client/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dbscanserving/client/__init__.py +++ b/src/dbscanserving/client/__init__.py @@ -11,4 +11,3 @@ # 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/dbscanserving/genproto.sh b/src/dbscanserving/genproto.sh deleted file mode 100755 index 449cffdebc5207dc17868b428504475bfab606d6..0000000000000000000000000000000000000000 --- a/src/dbscanserving/genproto.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -# Make folder containing the script the root folder for its execution -cd $(dirname $0) - -rm -rf proto/*.py -rm -rf proto/__pycache__ -tee proto/__init__.py << EOF > /dev/null -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -EOF - -# building current service protos -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto dbscanserving.proto - -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/dbscanserving_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/dbscanserving_pb2_grpc.py diff --git a/src/dbscanserving/proto/dbscanserving_pb2.py b/src/dbscanserving/proto/dbscanserving_pb2.py deleted file mode 100644 index f2d6c37c7c567394d3b12392a1fa4e0f748f6625..0000000000000000000000000000000000000000 --- a/src/dbscanserving/proto/dbscanserving_pb2.py +++ /dev/null @@ -1,244 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: dbscanserving.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='dbscanserving.proto', - package='dbscanserving', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x13\x64\x62scanserving.proto\x12\rdbscanserving\"\x1a\n\x06Sample\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\x02\"\xc2\x01\n\x10\x44\x65tectionRequest\x12\x0b\n\x03\x65ps\x18\x01 \x01(\x02\x12\x13\n\x0bmin_samples\x18\x02 \x01(\x05\x12%\n\x06metric\x18\x03 \x01(\x0e\x32\x15.dbscanserving.Metric\x12\x13\n\x0bnum_samples\x18\x04 \x01(\x05\x12\x14\n\x0cnum_features\x18\x05 \x01(\x05\x12&\n\x07samples\x18\x06 \x03(\x0b\x32\x15.dbscanserving.Sample\x12\x12\n\nidentifier\x18\x07 \x01(\x05\",\n\x11\x44\x65tectionResponse\x12\x17\n\x0f\x63luster_indices\x18\x01 \x03(\x05*\x17\n\x06Metric\x12\r\n\tEUCLIDEAN\x10\x00\x32W\n\x08\x44\x65tector\x12K\n\x06\x44\x65tect\x12\x1f.dbscanserving.DetectionRequest\x1a .dbscanserving.DetectionResponseb\x06proto3' -) - -_METRIC = _descriptor.EnumDescriptor( - name='Metric', - full_name='dbscanserving.Metric', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='EUCLIDEAN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=309, - serialized_end=332, -) -_sym_db.RegisterEnumDescriptor(_METRIC) - -Metric = enum_type_wrapper.EnumTypeWrapper(_METRIC) -EUCLIDEAN = 0 - - - -_SAMPLE = _descriptor.Descriptor( - name='Sample', - full_name='dbscanserving.Sample', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='features', full_name='dbscanserving.Sample.features', index=0, - number=1, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=38, - serialized_end=64, -) - - -_DETECTIONREQUEST = _descriptor.Descriptor( - name='DetectionRequest', - full_name='dbscanserving.DetectionRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='eps', full_name='dbscanserving.DetectionRequest.eps', index=0, - number=1, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='min_samples', full_name='dbscanserving.DetectionRequest.min_samples', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='metric', full_name='dbscanserving.DetectionRequest.metric', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='num_samples', full_name='dbscanserving.DetectionRequest.num_samples', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='num_features', full_name='dbscanserving.DetectionRequest.num_features', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='samples', full_name='dbscanserving.DetectionRequest.samples', index=5, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='identifier', full_name='dbscanserving.DetectionRequest.identifier', index=6, - number=7, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=67, - serialized_end=261, -) - - -_DETECTIONRESPONSE = _descriptor.Descriptor( - name='DetectionResponse', - full_name='dbscanserving.DetectionResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='cluster_indices', full_name='dbscanserving.DetectionResponse.cluster_indices', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=263, - serialized_end=307, -) - -_DETECTIONREQUEST.fields_by_name['metric'].enum_type = _METRIC -_DETECTIONREQUEST.fields_by_name['samples'].message_type = _SAMPLE -DESCRIPTOR.message_types_by_name['Sample'] = _SAMPLE -DESCRIPTOR.message_types_by_name['DetectionRequest'] = _DETECTIONREQUEST -DESCRIPTOR.message_types_by_name['DetectionResponse'] = _DETECTIONRESPONSE -DESCRIPTOR.enum_types_by_name['Metric'] = _METRIC -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -Sample = _reflection.GeneratedProtocolMessageType('Sample', (_message.Message,), { - 'DESCRIPTOR' : _SAMPLE, - '__module__' : 'dbscanserving_pb2' - # @@protoc_insertion_point(class_scope:dbscanserving.Sample) - }) -_sym_db.RegisterMessage(Sample) - -DetectionRequest = _reflection.GeneratedProtocolMessageType('DetectionRequest', (_message.Message,), { - 'DESCRIPTOR' : _DETECTIONREQUEST, - '__module__' : 'dbscanserving_pb2' - # @@protoc_insertion_point(class_scope:dbscanserving.DetectionRequest) - }) -_sym_db.RegisterMessage(DetectionRequest) - -DetectionResponse = _reflection.GeneratedProtocolMessageType('DetectionResponse', (_message.Message,), { - 'DESCRIPTOR' : _DETECTIONRESPONSE, - '__module__' : 'dbscanserving_pb2' - # @@protoc_insertion_point(class_scope:dbscanserving.DetectionResponse) - }) -_sym_db.RegisterMessage(DetectionResponse) - - - -_DETECTOR = _descriptor.ServiceDescriptor( - name='Detector', - full_name='dbscanserving.Detector', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=334, - serialized_end=421, - methods=[ - _descriptor.MethodDescriptor( - name='Detect', - full_name='dbscanserving.Detector.Detect', - index=0, - containing_service=None, - input_type=_DETECTIONREQUEST, - output_type=_DETECTIONRESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_DETECTOR) - -DESCRIPTOR.services_by_name['Detector'] = _DETECTOR - -# @@protoc_insertion_point(module_scope) diff --git a/src/dbscanserving/proto/dbscanserving_pb2_grpc.py b/src/dbscanserving/proto/dbscanserving_pb2_grpc.py deleted file mode 100644 index 895ced1484df2101bb055f28b6a6d3631e7e68da..0000000000000000000000000000000000000000 --- a/src/dbscanserving/proto/dbscanserving_pb2_grpc.py +++ /dev/null @@ -1,66 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from . import dbscanserving_pb2 as dbscanserving__pb2 - - -class DetectorStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.Detect = channel.unary_unary( - '/dbscanserving.Detector/Detect', - request_serializer=dbscanserving__pb2.DetectionRequest.SerializeToString, - response_deserializer=dbscanserving__pb2.DetectionResponse.FromString, - ) - - -class DetectorServicer(object): - """Missing associated documentation comment in .proto file.""" - - def Detect(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_DetectorServicer_to_server(servicer, server): - rpc_method_handlers = { - 'Detect': grpc.unary_unary_rpc_method_handler( - servicer.Detect, - request_deserializer=dbscanserving__pb2.DetectionRequest.FromString, - response_serializer=dbscanserving__pb2.DetectionResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'dbscanserving.Detector', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class Detector(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def Detect(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/dbscanserving.Detector/Detect', - dbscanserving__pb2.DetectionRequest.SerializeToString, - dbscanserving__pb2.DetectionResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/dbscanserving/requirements.in b/src/dbscanserving/requirements.in index 4499fc694c408b17bba4278a509e23ff6e8cf101..83af2a77d2b7dc65f40695f49f6caddb15b1991c 100644 --- a/src/dbscanserving/requirements.in +++ b/src/dbscanserving/requirements.in @@ -12,11 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. - -grpcio-health-checking -prometheus-client -pytest -pytest-benchmark -grpcio scikit-learn -coverage \ No newline at end of file diff --git a/src/dbscanserving/requirements.txt b/src/dbscanserving/requirements.txt deleted file mode 100644 index 067cdbc2620fabe5805f26055690212a0648d5d8..0000000000000000000000000000000000000000 --- a/src/dbscanserving/requirements.txt +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - - -# -# This file is autogenerated by pip-compile with python 3.9 -# To update, run: -# -# pip-compile --output-file=requirements.txt requirements.in -# -attrs==21.2.0 - # via pytest -grpcio==1.42.0 - # via - # -r requirements.in - # grpcio-health-checking -grpcio-health-checking==1.42.0 - # via -r requirements.in -iniconfig==1.1.1 - # via pytest -joblib==1.1.0 - # via scikit-learn -numpy==1.21.4 - # via - # scikit-learn - # scipy -packaging==21.3 - # via pytest -pluggy==1.0.0 - # via pytest -prometheus-client==0.12.0 - # via -r requirements.in -protobuf==3.19.1 - # via grpcio-health-checking -py==1.11.0 - # via pytest -py-cpuinfo==8.0.0 - # via pytest-benchmark -pyparsing==3.0.6 - # via packaging -pytest==6.2.5 - # via - # -r requirements.in - # pytest-benchmark -pytest-benchmark==3.4.1 - # via -r requirements.in -scikit-learn==1.0.1 - # via -r requirements.in -scipy==1.7.3 - # via scikit-learn -six==1.16.0 - # via grpcio -threadpoolctl==3.0.0 - # via scikit-learn -toml==0.10.2 - # via pytest diff --git a/src/dbscanserving/service/DbscanService.py b/src/dbscanserving/service/DbscanService.py index 632e4056050bfc44da069d7b706eb7b70a16bb34..834baa8c224cbb695f91941a02d57d5a591feb07 100644 --- a/src/dbscanserving/service/DbscanService.py +++ b/src/dbscanserving/service/DbscanService.py @@ -12,59 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc import logging -from concurrent import futures -from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH -from grpc_health.v1.health_pb2 import HealthCheckResponse -from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server -from dbscanserving.proto.dbscanserving_pb2_grpc import add_DetectorServicer_to_server -from dbscanserving.service.DbscanServiceServicerImpl import DbscanServiceServicerImpl -from dbscanserving.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD -BIND_ADDRESS = '0.0.0.0' -LOGGER = logging.getLogger(__name__) +from common.Constants import ServiceNameEnum +from common.proto.dbscanserving_pb2_grpc import add_DetectorServicer_to_server +from common.Settings import get_service_port_grpc +from common.tools.service.GenericGrpcService import GenericGrpcService -class DbscanService: - def __init__( - self, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, - grace_period=GRPC_GRACE_PERIOD): +from dbscanserving.service.DbscanServiceServicerImpl import \ + DbscanServiceServicerImpl - self.address = address - self.port = port - self.endpoint = None - self.max_workers = max_workers - self.grace_period = grace_period - self.dbscan_servicer = None - self.health_servicer = None - self.pool = None - self.server = None +LOGGER = logging.getLogger(__name__) - def start(self): - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port)) - LOGGER.debug('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format( - str(self.endpoint), str(self.max_workers))) - self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers) - self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,)) +class DbscanService(GenericGrpcService): + def __init__(self, cls_name: str = __name__): + port = get_service_port_grpc(ServiceNameEnum.DBSCANSERVING) + super().__init__(port, cls_name=cls_name) self.dbscan_servicer = DbscanServiceServicerImpl() - add_DetectorServicer_to_server(self.dbscan_servicer, self.server) - - self.health_servicer = HealthServicer( - experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1)) - add_HealthServicer_to_server(self.health_servicer, self.server) - port = self.server.add_insecure_port(self.endpoint) - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port)) - LOGGER.info('Listening on {:s}...'.format(self.endpoint)) - self.server.start() - self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member - - LOGGER.debug('Service started') - - def stop(self): - LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period))) - self.health_servicer.enter_graceful_shutdown() - self.server.stop(self.grace_period) - LOGGER.debug('Service stopped') + def install_servicers(self): + add_DetectorServicer_to_server(self.dbscan_servicer, self.server) diff --git a/src/dbscanserving/service/DbscanServiceServicerImpl.py b/src/dbscanserving/service/DbscanServiceServicerImpl.py index e71aac7b4c5899f9f5a01c5427666e8e34944b99..ac4f4c90b51f31de36c6c3b05cf5064840786018 100644 --- a/src/dbscanserving/service/DbscanServiceServicerImpl.py +++ b/src/dbscanserving/service/DbscanServiceServicerImpl.py @@ -12,32 +12,43 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, grpc, logging +import logging + +import grpc from sklearn.cluster import DBSCAN -from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method -from dbscanserving.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse -from dbscanserving.proto.dbscanserving_pb2_grpc import DetectorServicer + +from common.method_wrappers.Decorator import (MetricsPool, + safe_and_metered_rpc_method) +from common.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse +from common.proto.dbscanserving_pb2_grpc import DetectorServicer LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('DbscanServing', 'RPC') +METRICS_POOL = MetricsPool("DBSCANServing", "RPC") class DbscanServiceServicerImpl(DetectorServicer): - def __init__(self): - LOGGER.debug('Creating Servicer...') - LOGGER.debug('Servicer Created') + LOGGER.debug("Creating Servicer...") + LOGGER.debug("Servicer Created") @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def Detect(self, request : DetectionRequest, context : grpc.ServicerContext) -> DetectionResponse: + def Detect( + self, request: DetectionRequest, context: grpc.ServicerContext + ) -> DetectionResponse: if request.num_samples != len(request.samples): - context.set_details("The sample dimension declared does not match with the number of samples received.") - LOGGER.debug(f"The sample dimension declared does not match with the number of samples received. Declared: {request.num_samples} - Received: {len(request.samples)}") + context.set_details( + f"The sample dimension declared ({request.num_samples}) does not match with the number of samples received ({len(request.samples)})." + ) + LOGGER.debug( + f"The sample dimension declared does not match with the number of samples received. Declared: {request.num_samples} - Received: {len(request.samples)}" + ) context.set_code(grpc.StatusCode.INVALID_ARGUMENT) return DetectionResponse() # TODO: implement the validation of the features dimension - clusters = DBSCAN(eps=request.eps, min_samples=request.min_samples).fit_predict([[x for x in sample.features] for sample in request.samples]) + clusters = DBSCAN(eps=request.eps, min_samples=request.min_samples).fit_predict( + [[x for x in sample.features] for sample in request.samples] + ) response = DetectionResponse() for cluster in clusters: response.cluster_indices.append(cluster) diff --git a/src/dbscanserving/service/__init__.py b/src/dbscanserving/service/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dbscanserving/service/__init__.py +++ b/src/dbscanserving/service/__init__.py @@ -11,4 +11,3 @@ # 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/dbscanserving/service/__main__.py b/src/dbscanserving/service/__main__.py index 391229969bb719760897c706e280cfa4566ba7f9..fc0f8346e01b7ec30c4404990148915981ba1cd7 100644 --- a/src/dbscanserving/service/__main__.py +++ b/src/dbscanserving/service/__main__.py @@ -12,53 +12,55 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, logging, signal, sys, time, threading, multiprocessing +import logging +import signal +import sys +import threading + +from common.Settings import get_log_level, get_metrics_port from prometheus_client import start_http_server -from common.Settings import get_setting -from dbscanserving.Config import ( - GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT) + from dbscanserving.service.DbscanService import DbscanService terminate = threading.Event() LOGGER = None -def signal_handler(signal, frame): # pylint: disable=redefined-outer-name - LOGGER.warning('Terminate signal received') + +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 - service_port = get_setting('DBSCANSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT) - max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) - grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD) - log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) - metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) +def main(): + global LOGGER # pylint: disable=global-statement + log_level = get_log_level() logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) - signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) - LOGGER.info('Starting...') + LOGGER.info("Starting...") # Start metrics server + metrics_port = get_metrics_port() start_http_server(metrics_port) # Starting CentralizedCybersecurity service - grpc_service = DbscanService( - port=service_port, max_workers=max_workers, grace_period=grace_period) + grpc_service = DbscanService() grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1): + pass - LOGGER.info('Terminating...') + LOGGER.info("Terminating...") grpc_service.stop() - LOGGER.info('Bye') + LOGGER.info("Bye") return 0 -if __name__ == '__main__': + +if __name__ == "__main__": sys.exit(main()) diff --git a/src/dbscanserving/tests/__init__.py b/src/dbscanserving/tests/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dbscanserving/tests/__init__.py +++ b/src/dbscanserving/tests/__init__.py @@ -11,4 +11,3 @@ # 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/dbscanserving/tests/test_unitary.py b/src/dbscanserving/tests/test_unitary.py index b23a1a726634465a418b3b3eeb4bc9f0ac6d3f87..7349978e51cf5be8aa2f9899a91de91e13d1ae7e 100644 --- a/src/dbscanserving/tests/test_unitary.py +++ b/src/dbscanserving/tests/test_unitary.py @@ -12,32 +12,52 @@ # See the License for the specific language governing permissions and # limitations under the License. -import random, logging, pytest, numpy -from dbscanserving.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD +import logging +import os +import random +from unittest.mock import patch + +import pytest + +from common.proto.dbscanserving_pb2 import (DetectionRequest, + DetectionResponse, Sample) + from dbscanserving.client.DbscanServingClient import DbscanServingClient +from dbscanserving.Config import GRPC_SERVICE_PORT from dbscanserving.service.DbscanService import DbscanService -from dbscanserving.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse, Sample -port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports +port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -@pytest.fixture(scope='session') + +@pytest.fixture(scope="session") def dbscanserving_service(): - _service = DbscanService( - port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD) + _service = DbscanService(port=port) _service.start() yield _service _service.stop() -@pytest.fixture(scope='session') + +@pytest.fixture(scope="session") def dbscanserving_client(): - _client = DbscanServingClient(address='127.0.0.1', port=port) - yield _client + with patch.dict( + os.environ, + { + "DBSCANSERVINGSERVICE_SERVICE_HOST": "127.0.0.1", + "DBSCANSERVINGSERVICE_SERVICE_PORT_GRPC": str(port), + }, + clear=True, + ): + _client = DbscanServingClient() + yield _client _client.close() -def test_detection_correct(dbscanserving_service, dbscanserving_client: DbscanServingClient): + +def test_detection_correct( + dbscanserving_service, dbscanserving_client: DbscanServingClient +): request: DetectionRequest = DetectionRequest() request.num_samples = 310 @@ -48,25 +68,28 @@ def test_detection_correct(dbscanserving_service, dbscanserving_client: DbscanSe for _ in range(200): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(0., 10.)) + grpc_sample.features.append(random.uniform(0.0, 10.0)) request.samples.append(grpc_sample) - + for _ in range(100): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(50., 60.)) + grpc_sample.features.append(random.uniform(50.0, 60.0)) request.samples.append(grpc_sample) - + for _ in range(10): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(5000., 6000.)) + grpc_sample.features.append(random.uniform(5000.0, 6000.0)) request.samples.append(grpc_sample) response: DetectionResponse = dbscanserving_client.Detect(request) assert len(response.cluster_indices) == 310 -def test_detection_incorrect(dbscanserving_service, dbscanserving_client: DbscanServingClient): + +def test_detection_incorrect( + dbscanserving_service, dbscanserving_client: DbscanServingClient +): request: DetectionRequest = DetectionRequest() request.num_samples = 210 @@ -77,25 +100,28 @@ def test_detection_incorrect(dbscanserving_service, dbscanserving_client: Dbscan for _ in range(200): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(0., 10.)) + grpc_sample.features.append(random.uniform(0.0, 10.0)) request.samples.append(grpc_sample) - + for _ in range(100): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(50., 60.)) + grpc_sample.features.append(random.uniform(50.0, 60.0)) request.samples.append(grpc_sample) - + for _ in range(10): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(5000., 6000.)) + grpc_sample.features.append(random.uniform(5000.0, 6000.0)) request.samples.append(grpc_sample) with pytest.raises(Exception): - response: DetectionResponse = dbscanserving_client.Detect(request) + _: DetectionResponse = dbscanserving_client.Detect(request) -def test_detection_clusters(dbscanserving_service, dbscanserving_client: DbscanServingClient): + +def test_detection_clusters( + dbscanserving_service, dbscanserving_client: DbscanServingClient +): request: DetectionRequest = DetectionRequest() request.num_samples = 310 @@ -106,19 +132,19 @@ def test_detection_clusters(dbscanserving_service, dbscanserving_client: DbscanS for _ in range(200): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(0., 10.)) + grpc_sample.features.append(random.uniform(0.0, 10.0)) request.samples.append(grpc_sample) - + for _ in range(100): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(50., 60.)) + grpc_sample.features.append(random.uniform(50.0, 60.0)) request.samples.append(grpc_sample) - + for _ in range(10): grpc_sample = Sample() for __ in range(100): - grpc_sample.features.append(random.uniform(5000., 6000.)) + grpc_sample.features.append(random.uniform(5000.0, 6000.0)) request.samples.append(grpc_sample) response: DetectionResponse = dbscanserving_client.Detect(request) diff --git a/src/device/requirements.in b/src/device/requirements.in index 4e927d65cdb0c3ec6da07db461d52ec03a7bed83..24707e932d6223db476592e0d985f5d6c1dfc852 100644 --- a/src/device/requirements.in +++ b/src/device/requirements.in @@ -31,6 +31,8 @@ ipaddress macaddress pyang git+https://github.com/robshakir/pyangbind.git +websockets==10.4 + # 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 diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py index be40e64ecd25a5c46c23d5ec0a73a2484b65691d..d29d469cb0812218030698284abbfc7551058411 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -12,11 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging -from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method +import grpc, logging, os, time +from typing import Dict +from prometheus_client import Histogram +from common.Constants import ServiceNameEnum +from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name +from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( - Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty) + Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device @@ -28,13 +32,17 @@ from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI from .Tools import ( check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, - populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, populate_initial_config_rules, - subscribe_kpi, unsubscribe_kpi, update_endpoints) + get_device_controller_uuid, populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, + populate_initial_config_rules, subscribe_kpi, unsubscribe_kpi, update_endpoints) LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool('Device', 'RPC') +METRICS_POOL_DETAILS = MetricsPool('Device', 'execution', labels={ + 'driver': '', 'operation': '', 'step': '', +}) + class DeviceServiceServicerImpl(DeviceServiceServicer): def __init__(self, driver_instance_cache : DriverInstanceCache, monitoring_loops : MonitoringLoops) -> None: LOGGER.debug('Creating Servicer...') @@ -45,11 +53,15 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def AddDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId: + t0 = time.time() + device_uuid = request.device_id.device_uuid.uuid connection_config_rules = check_connect_rules(request.device_config) check_no_endpoints(request.device_endpoints) + t1 = time.time() + context_client = ContextClient() device = get_device(context_client, device_uuid, rw_copy=True) if device is None: @@ -67,19 +79,41 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): # update device_uuid to honor UUID provided by Context device_uuid = device.device_id.device_uuid.uuid + t2 = time.time() + self.mutex_queues.wait_my_turn(device_uuid) + t3 = time.time() try: driver : _Driver = get_driver(self.driver_instance_cache, device) + t4 = time.time() + errors = [] + # Sub-devices and sub-links are exposed by intermediate controllers or represent mgmt links. + # They are used to assist in path computation algorithms, and/or to identify dependencies + # (which controller is in charge of which sub-device). + new_sub_devices : Dict[str, Device] = dict() + new_sub_links : Dict[str, Link] = dict() + if len(device.device_endpoints) == 0: + t5 = time.time() # created from request, populate endpoints using driver - errors.extend(populate_endpoints(device, driver, self.monitoring_loops)) + errors.extend(populate_endpoints( + device, driver, self.monitoring_loops, new_sub_devices, new_sub_links)) + t6 = time.time() + t_pop_endpoints = t6 - t5 + else: + t_pop_endpoints = None if len(device.device_config.config_rules) == len(connection_config_rules): # created from request, populate config rules using driver + t7 = time.time() errors.extend(populate_config_rules(device, driver)) + t8 = time.time() + t_pop_config_rules = t8 - t7 + else: + t_pop_config_rules = None # TODO: populate components @@ -87,34 +121,109 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): for error in errors: LOGGER.error(error) raise OperationFailedException('AddDevice', extra_details=errors) + t9 = time.time() + + automation_service_host = get_env_var_name(ServiceNameEnum.AUTOMATION, ENVVAR_SUFIX_SERVICE_HOST) + environment_variables = set(os.environ.keys()) + if automation_service_host in environment_variables: + # Automation component is deployed; leave devices disabled. Automation will enable them. + device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED + else: + # Automation is not deployed; assume the device is ready while onboarding and set them as enabled. + device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + device_id = context_client.SetDevice(device) + t10 = time.time() + + for sub_device in new_sub_devices.values(): + context_client.SetDevice(sub_device) + + t11 = time.time() + + for sub_links in new_sub_links.values(): + context_client.SetLink(sub_links) + + t12 = time.time() + # Update endpoint monitoring resources with UUIDs - device_with_uuids = context_client.GetDevice(device_id) + device_with_uuids = get_device( + context_client, device_id.device_uuid.uuid, rw_copy=False, include_endpoints=True, + include_components=False, include_config_rules=False) populate_endpoint_monitoring_resources(device_with_uuids, self.monitoring_loops) + t13 = time.time() + + context_client.close() + + t14 = time.time() + + metrics_labels = dict(driver=driver.name, operation='add_device') + + histogram_duration : Histogram = METRICS_POOL_DETAILS.get_or_create( + 'details', MetricTypeEnum.HISTOGRAM_DURATION) + histogram_duration.labels(step='total' , **metrics_labels).observe(t14-t0) + histogram_duration.labels(step='execution' , **metrics_labels).observe(t14-t3) + histogram_duration.labels(step='endpoint_checks' , **metrics_labels).observe(t1-t0) + histogram_duration.labels(step='get_device' , **metrics_labels).observe(t2-t1) + histogram_duration.labels(step='wait_queue' , **metrics_labels).observe(t3-t2) + histogram_duration.labels(step='get_driver' , **metrics_labels).observe(t4-t3) + histogram_duration.labels(step='set_device' , **metrics_labels).observe(t10-t9) + histogram_duration.labels(step='populate_monit_rsrc', **metrics_labels).observe(t13-t12) + + if t_pop_endpoints is not None: + histogram_duration.labels(step='populate_endpoints', **metrics_labels).observe(t_pop_endpoints) + + if t_pop_config_rules is not None: + histogram_duration.labels(step='populate_config_rules', **metrics_labels).observe(t_pop_config_rules) + + if len(new_sub_devices) > 0: + histogram_duration.labels(step='set_sub_devices', **metrics_labels).observe(t11-t10) + + if len(new_sub_links) > 0: + histogram_duration.labels(step='set_sub_links', **metrics_labels).observe(t12-t11) + return device_id finally: self.mutex_queues.signal_done(device_uuid) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ConfigureDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId: + t0 = time.time() device_id = request.device_id device_uuid = device_id.device_uuid.uuid self.mutex_queues.wait_my_turn(device_uuid) + t1 = time.time() try: context_client = ContextClient() - device = get_device(context_client, device_uuid, rw_copy=True) + t2 = time.time() + device = get_device( + context_client, device_uuid, rw_copy=True, include_endpoints=False, include_components=False, + include_config_rules=True) if device is None: raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') + t3 = time.time() + device_controller_uuid = get_device_controller_uuid(device) + if device_controller_uuid is not None: + device = get_device( + context_client, device_controller_uuid, rw_copy=True, include_endpoints=False, + include_components=False, include_config_rules=True) + if device is None: + raise NotFoundException( + 'Device', device_controller_uuid, extra_details='loading in ConfigureDevice') + + device_uuid = device.device_id.device_uuid.uuid driver : _Driver = get_driver(self.driver_instance_cache, device) if driver is None: msg = ERROR_MISSING_DRIVER.format(device_uuid=str(device_uuid)) raise OperationFailedException('ConfigureDevice', extra_details=msg) if DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: + device = get_device( + context_client, device_uuid, rw_copy=False, include_endpoints=True, include_components=False, + include_config_rules=True) # P4 Driver, by now, has no means to retrieve endpoints # We allow defining the endpoints manually update_endpoints(request, device) @@ -126,19 +235,46 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): if request.device_operational_status != DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED: device.device_operational_status = request.device_operational_status + t4 = time.time() # TODO: use of datastores (might be virtual ones) to enable rollbacks resources_to_set, resources_to_delete = compute_rules_to_add_delete(device, request) + t5 = time.time() errors = [] errors.extend(configure_rules(device, driver, resources_to_set)) + t6 = time.time() errors.extend(deconfigure_rules(device, driver, resources_to_delete)) + t7 = time.time() if len(errors) > 0: for error in errors: LOGGER.error(error) raise OperationFailedException('ConfigureDevice', extra_details=errors) + # Context Performance+Scalability enhancement: + # This method, besides P4 logic, does not add/update/delete endpoints. + # Remove endpoints to reduce number of inserts done by Context. + # TODO: Add logic to inspect endpoints and keep only those ones modified with respect to Context. + del device.device_endpoints[:] + + t8 = time.time() # Note: Rules are updated by configure_rules() and deconfigure_rules() methods. device_id = context_client.SetDevice(device) + + t9 = time.time() + + metrics_labels = dict(driver=driver.name, operation='configure_device') + + histogram_duration : Histogram = METRICS_POOL_DETAILS.get_or_create( + 'details', MetricTypeEnum.HISTOGRAM_DURATION) + histogram_duration.labels(step='total' , **metrics_labels).observe(t9-t0) + histogram_duration.labels(step='wait_queue' , **metrics_labels).observe(t1-t0) + histogram_duration.labels(step='execution' , **metrics_labels).observe(t9-t1) + histogram_duration.labels(step='get_device' , **metrics_labels).observe(t3-t2) + histogram_duration.labels(step='split_rules' , **metrics_labels).observe(t5-t4) + histogram_duration.labels(step='configure_rules' , **metrics_labels).observe(t6-t5) + histogram_duration.labels(step='deconfigure_rules', **metrics_labels).observe(t7-t6) + histogram_duration.labels(step='set_device' , **metrics_labels).observe(t9-t8) + return device_id finally: self.mutex_queues.signal_done(device_uuid) @@ -150,7 +286,9 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): self.mutex_queues.wait_my_turn(device_uuid) try: context_client = ContextClient() - device = get_device(context_client, device_uuid, rw_copy=False) + device = get_device( + context_client, device_uuid, rw_copy=False, include_endpoints=False, include_config_rules=False, + include_components=False) if device is None: raise NotFoundException('Device', device_uuid, extra_details='loading in DeleteDevice') device_uuid = device.device_id.device_uuid.uuid @@ -169,7 +307,9 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): self.mutex_queues.wait_my_turn(device_uuid) try: context_client = ContextClient() - device = get_device(context_client, device_uuid, rw_copy=False) + device = get_device( + context_client, device_uuid, rw_copy=False, include_endpoints=False, include_components=False, + include_config_rules=True) if device is None: raise NotFoundException('Device', device_uuid, extra_details='loading in DeleteDevice') @@ -208,7 +348,9 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): self.mutex_queues.wait_my_turn(device_uuid) try: context_client = ContextClient() - device = get_device(context_client, device_uuid, rw_copy=False) + device = get_device( + context_client, device_uuid, rw_copy=False, include_endpoints=False, include_components=False, + include_config_rules=True) if device is None: raise NotFoundException('Device', device_uuid, extra_details='loading in DeleteDevice') diff --git a/src/device/service/ErrorMessages.py b/src/device/service/ErrorMessages.py index 1fbea721fdc52bdf759581c0525b30b1206ae844..bb7702e4e629bad43df4870d923f0a1829378e2e 100644 --- a/src/device/service/ErrorMessages.py +++ b/src/device/service/ErrorMessages.py @@ -14,9 +14,9 @@ _DEVICE_ID = 'DeviceId({device_uuid:s})' _ENDPOINT_ID = 'EndpointId({endpoint_uuid:s})' -_ENDPOINT_DATA = 'EndpointId({endpoint_data:s})' _KPI = 'Kpi({kpi_uuid:s})' _DEVICE_ENDPOINT_ID = _DEVICE_ID + '/' + _ENDPOINT_ID +_RESOURCE = 'Resource({resource_data:s})' _RESOURCE_KEY = 'Resource(key={resource_key:s})' _RESOURCE_KEY_VALUE = 'Resource(key={resource_key:s}, value={resource_value:s})' _SUBSCRIPTION = 'Subscription(key={subscr_key:s}, duration={subscr_duration:s}, interval={subscr_interval:s})' @@ -26,7 +26,8 @@ _ERROR = 'Error({error:s})' ERROR_MISSING_DRIVER = _DEVICE_ID + ' has not been added to this Device instance' ERROR_MISSING_KPI = _KPI + ' not found' -ERROR_BAD_ENDPOINT = _DEVICE_ID + ': GetConfig retrieved malformed ' + _ENDPOINT_DATA +ERROR_BAD_RESOURCE = _DEVICE_ID + ': GetConfig retrieved malformed ' + _RESOURCE +ERROR_UNSUP_RESOURCE = _DEVICE_ID + ': GetConfig retrieved unsupported ' + _RESOURCE ERROR_GET = _DEVICE_ID + ': Unable to Get ' + _RESOURCE_KEY + '; ' + _ERROR ERROR_GET_INIT = _DEVICE_ID + ': Unable to Get Initial ' + _RESOURCE_KEY + '; ' + _ERROR diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index b63bac9659521f47117ef97b3ae6d97be653adcf..82bdbf7d7e869c987f06575ec8f519a74fc835ea 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -13,19 +13,20 @@ # limitations under the License. import json, logging -from typing import Any, Dict, List, Tuple, Union +from typing import Any, Dict, List, Optional, Tuple, Union from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.method_wrappers.ServiceExceptions import InvalidArgumentException -from common.proto.context_pb2 import ConfigActionEnum, ConfigRule_ACL, Device, DeviceConfig +from common.proto.context_pb2 import ConfigActionEnum, ConfigRule_ACL, Device, DeviceConfig, Link from common.proto.device_pb2 import MonitoringSettings from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.grpc.ConfigRules import update_config_rule_custom from common.tools.grpc.Tools import grpc_message_to_json +from context.client.ContextClient import ContextClient from .driver_api._Driver import _Driver, RESOURCE_ENDPOINTS from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ( - ERROR_BAD_ENDPOINT, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, - ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE + ERROR_BAD_RESOURCE, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, + ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE, ERROR_UNSUP_RESOURCE ) LOGGER = logging.getLogger(__name__) @@ -77,19 +78,53 @@ def check_no_endpoints(device_endpoints) -> None: extra_details='RPC method AddDevice does not accept Endpoints. Endpoints are discovered through '\ 'interrogation of the physical device.') -def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : MonitoringLoops) -> List[str]: +def get_device_controller_uuid(device : Device) -> Optional[str]: + controller_uuid = device.controller_id.device_uuid.uuid + if len(controller_uuid) > 0: return controller_uuid + #for config_rule in device.device_config.config_rules: + # if config_rule.WhichOneof('config_rule') != 'custom': continue + # if config_rule.custom.resource_key != '_controller': continue + # device_controller_id = json.loads(config_rule.custom.resource_value) + # return device_controller_id['uuid'] + return None + +def populate_endpoints( + device : Device, driver : _Driver, monitoring_loops : MonitoringLoops, + new_sub_devices : Dict[str, Device], new_sub_links : Dict[str, Link] +) -> List[str]: device_uuid = device.device_id.device_uuid.uuid + device_name = device.name resources_to_get = [RESOURCE_ENDPOINTS] results_getconfig = driver.GetConfig(resources_to_get) + LOGGER.debug('results_getconfig = {:s}'.format(str(results_getconfig))) + + # first quick pass to identify need of mgmt endpoints and links + add_mgmt_port = False + for resource_data in results_getconfig: + if len(resource_data) != 2: continue + resource_key, _ = resource_data + if resource_key.startswith('/devices/device'): + add_mgmt_port = True + break + + if add_mgmt_port: + # add mgmt port to main device + device_mgmt_endpoint = device.device_endpoints.add() + device_mgmt_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + device_mgmt_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME + device_mgmt_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid + device_mgmt_endpoint.endpoint_id.endpoint_uuid.uuid = 'mgmt' + device_mgmt_endpoint.name = 'mgmt' + device_mgmt_endpoint.endpoint_type = 'mgmt' errors : List[str] = list() - for endpoint in results_getconfig: - if len(endpoint) != 2: - errors.append(ERROR_BAD_ENDPOINT.format(device_uuid=device_uuid, endpoint_data=str(endpoint))) + for resource_data in results_getconfig: + if len(resource_data) != 2: + errors.append(ERROR_BAD_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data))) continue - resource_key, resource_value = endpoint + resource_key, resource_value = resource_data if isinstance(resource_value, Exception): errors.append(ERROR_GET.format( device_uuid=device_uuid, resource_key=str(resource_key), error=str(resource_value))) @@ -97,19 +132,94 @@ def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : Mon if resource_value is None: continue - endpoint_uuid = resource_value.get('uuid') - - device_endpoint = device.device_endpoints.add() - device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME - device_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME - device_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid - device_endpoint.endpoint_id.endpoint_uuid.uuid = endpoint_uuid - device_endpoint.endpoint_type = resource_value.get('type') + if resource_key.startswith('/devices/device'): + # create sub-device + _sub_device_uuid = resource_value['uuid'] + _sub_device = Device() + _sub_device.device_id.device_uuid.uuid = _sub_device_uuid # pylint: disable=no-member + _sub_device.name = resource_value['name'] + _sub_device.device_type = resource_value['type'] + _sub_device.device_operational_status = resource_value['status'] + + # Sub-devices should not have a driver assigned. Instead, they should have + # a config rule specifying their controller. + #_sub_device.device_drivers.extend(resource_value['drivers']) # pylint: disable=no-member + #controller_config_rule = _sub_device.device_config.config_rules.add() + #controller_config_rule.action = ConfigActionEnum.CONFIGACTION_SET + #controller_config_rule.custom.resource_key = '_controller' + #controller = {'uuid': device_uuid, 'name': device_name} + #controller_config_rule.custom.resource_value = json.dumps(controller, indent=0, sort_keys=True) + _sub_device.controller_id.device_uuid.uuid = device_uuid + + new_sub_devices[_sub_device_uuid] = _sub_device + + # add mgmt port to sub-device + _sub_device_mgmt_endpoint = _sub_device.device_endpoints.add() # pylint: disable=no-member + _sub_device_mgmt_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + _sub_device_mgmt_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME + _sub_device_mgmt_endpoint.endpoint_id.device_id.device_uuid.uuid = _sub_device_uuid + _sub_device_mgmt_endpoint.endpoint_id.endpoint_uuid.uuid = 'mgmt' + _sub_device_mgmt_endpoint.name = 'mgmt' + _sub_device_mgmt_endpoint.endpoint_type = 'mgmt' + + # add mgmt link + _mgmt_link_uuid = '{:s}/{:s}=={:s}/{:s}'.format(device_name, 'mgmt', _sub_device.name, 'mgmt') + _mgmt_link = Link() + _mgmt_link.link_id.link_uuid.uuid = _mgmt_link_uuid # pylint: disable=no-member + _mgmt_link.name = _mgmt_link_uuid + _mgmt_link.link_endpoint_ids.append(device_mgmt_endpoint.endpoint_id) # pylint: disable=no-member + _mgmt_link.link_endpoint_ids.append(_sub_device_mgmt_endpoint.endpoint_id) # pylint: disable=no-member + new_sub_links[_mgmt_link_uuid] = _mgmt_link + + elif resource_key.startswith('/endpoints/endpoint'): + endpoint_uuid = resource_value['uuid'] + _device_uuid = resource_value.get('device_uuid') + + if _device_uuid is None: + # add endpoint to current device + device_endpoint = device.device_endpoints.add() + device_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid + else: + # add endpoint to specified device + device_endpoint = new_sub_devices[_device_uuid].device_endpoints.add() + device_endpoint.endpoint_id.device_id.device_uuid.uuid = _device_uuid + + device_endpoint.endpoint_id.endpoint_uuid.uuid = endpoint_uuid + + endpoint_context_uuid = resource_value.get('context_uuid', DEFAULT_CONTEXT_NAME) + device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = endpoint_context_uuid + + endpoint_topology_uuid = resource_value.get('topology_uuid', DEFAULT_TOPOLOGY_NAME) + device_endpoint.endpoint_id.topology_id.topology_uuid.uuid = endpoint_topology_uuid + + endpoint_name = resource_value.get('name') + if endpoint_name is not None: device_endpoint.name = endpoint_name + + device_endpoint.endpoint_type = resource_value.get('type', '-') + + sample_types : Dict[int, str] = resource_value.get('sample_types', {}) + for kpi_sample_type, monitor_resource_key in sample_types.items(): + device_endpoint.kpi_sample_types.append(kpi_sample_type) + monitoring_loops.add_resource_key(device_uuid, endpoint_uuid, kpi_sample_type, monitor_resource_key) + + elif resource_key.startswith('/links/link'): + # create sub-link + _sub_link_uuid = resource_value['uuid'] + _sub_link = Link() + _sub_link.link_id.link_uuid.uuid = _sub_link_uuid # pylint: disable=no-member + _sub_link.name = resource_value['name'] + new_sub_links[_sub_link_uuid] = _sub_link + + for device_uuid,endpoint_uuid in resource_value['endpoints']: + _sub_link_endpoint_id = _sub_link.link_endpoint_ids.add() # pylint: disable=no-member + _sub_link_endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + _sub_link_endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME + _sub_link_endpoint_id.device_id.device_uuid.uuid = device_uuid + _sub_link_endpoint_id.endpoint_uuid.uuid = endpoint_uuid - sample_types : Dict[int, str] = resource_value.get('sample_types', {}) - for kpi_sample_type, monitor_resource_key in sample_types.items(): - device_endpoint.kpi_sample_types.append(kpi_sample_type) - monitoring_loops.add_resource_key(device_uuid, endpoint_uuid, kpi_sample_type, monitor_resource_key) + else: + errors.append(ERROR_UNSUP_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data))) + continue return errors diff --git a/src/device/service/__main__.py b/src/device/service/__main__.py index 35b548fe9d9422b68138f956ce159ee679d54f1c..a07a2ab90d15d99bdabe6b3fb6b0e0c9c497cf3c 100644 --- a/src/device/service/__main__.py +++ b/src/device/service/__main__.py @@ -66,7 +66,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/device/service/driver_api/ImportTopologyEnum.py b/src/device/service/driver_api/ImportTopologyEnum.py new file mode 100644 index 0000000000000000000000000000000000000000..06f0ff9c2db1f1baccc4b46c5babc4458ca6ffb6 --- /dev/null +++ b/src/device/service/driver_api/ImportTopologyEnum.py @@ -0,0 +1,37 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 enum import Enum +from typing import Dict + +class ImportTopologyEnum(Enum): + # While importing underlying resources, the driver just imports endpoints and exposes them directly. + DISABLED = 'disabled' + + # While importing underlying resources, the driver just imports imports sub-devices but not links + # connecting them. The endpoints are exposed in virtual nodes representing the sub-devices. + # (a remotely-controlled transport domain might exist between nodes) + DEVICES = 'devices' + + # While importing underlying resources, the driver just imports imports sub-devices and links + # connecting them. The endpoints are exposed in virtual nodes representing the sub-devices. + # (enables to define constrained connectivity between the sub-devices) + TOPOLOGY = 'topology' + +def get_import_topology(settings : Dict, default : ImportTopologyEnum = ImportTopologyEnum.DISABLED): + str_import_topology = settings.get('import_topology') + if str_import_topology is None: return default + import_topology = ImportTopologyEnum._value2member_map_.get(str_import_topology) # pylint: disable=no-member + if import_topology is None: raise Exception('Unexpected setting value') + return import_topology diff --git a/src/device/service/driver_api/_Driver.py b/src/device/service/driver_api/_Driver.py index cc9f7a2c63f2f841b864cbe4fa596464a6783cec..7adaec79dc99f9b7c836acaec886b0d5bda97fb8 100644 --- a/src/device/service/driver_api/_Driver.py +++ b/src/device/service/driver_api/_Driver.py @@ -22,11 +22,12 @@ RESOURCE_ENDPOINTS = '__endpoints__' RESOURCE_INTERFACES = '__interfaces__' RESOURCE_NETWORK_INSTANCES = '__network_instances__' RESOURCE_ROUTING_POLICIES = '__routing_policies__' +RESOURCE_SERVICES = '__services__' RESOURCE_ACL = '__acl__' class _Driver: - def __init__(self, address: str, port: int, **settings) -> None: + def __init__(self, name : str, address: str, port: int, **settings) -> None: """ Initialize Driver. Parameters: address : str @@ -36,7 +37,22 @@ class _Driver: **settings Extra settings required by the driver. """ - raise NotImplementedError() + self._name = name + self._address = address + self._port = port + self._settings = settings + + @property + def name(self): return self._name + + @property + def address(self): return self._address + + @property + def port(self): return self._port + + @property + def settings(self): return self._settings def Connect(self) -> bool: """ Connect to the Device. diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index 469abcad387dc055ba17770e4f405db1d1ceaa3b..b3b485a471899dd96a4985fedb4bb6ede2432921 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -74,6 +74,15 @@ DRIVERS.append( #} ])) +from .ietf_l2vpn.IetfL2VpnDriver import IetfL2VpnDriver # pylint: disable=wrong-import-position +DRIVERS.append( + (IetfL2VpnDriver, [ + { + FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.TERAFLOWSDN_CONTROLLER, + FilterFieldEnum.DRIVER: DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN, + } + ])) + if LOAD_ALL_DEVICE_DRIVERS: from .openconfig.OpenConfigDriver import OpenConfigDriver # pylint: disable=wrong-import-position DRIVERS.append( diff --git a/src/device/service/drivers/emulated/EmulatedDriver.py b/src/device/service/drivers/emulated/EmulatedDriver.py index 14925f9f78d143cd998065a43afb624b20c04bfb..8f9453574a7333e599ea56158204627fcfdd3680 100644 --- a/src/device/service/drivers/emulated/EmulatedDriver.py +++ b/src/device/service/drivers/emulated/EmulatedDriver.py @@ -19,7 +19,7 @@ from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.job import Job from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.background import BackgroundScheduler -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.type_checkers.Checkers import chk_float, chk_length, chk_string, chk_type from device.service.driver_api._Driver import _Driver from device.service.driver_api.AnyTreeTools import TreeNode, dump_subtree, get_subnode, set_subnode_value @@ -31,32 +31,18 @@ LOGGER = logging.getLogger(__name__) RE_GET_ENDPOINT_FROM_INTERFACE = re.compile(r'^\/interface\[([^\]]+)\].*') -HISTOGRAM_BUCKETS = ( - # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0001, 0.00025, 0.00050, 0.00075, - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - 10.0, 25.0, 50.0, 75.0, - 100.0, INF -) -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'emulated'}) -METRICS_POOL.get_or_create('GetInitialConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('GetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SubscribeState', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('UnsubscribeState', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) +DRIVER_NAME = 'emulated' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) class EmulatedDriver(_Driver): - def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called + def __init__(self, address : str, port : int, **settings) -> None: + super().__init__(DRIVER_NAME, address, port, **settings) self.__lock = threading.Lock() self.__initial = TreeNode('.') self.__running = TreeNode('.') self.__subscriptions = TreeNode('.') - endpoints = settings.get('endpoints', []) + endpoints = self.settings.get('endpoints', []) endpoint_resources = [] for endpoint in endpoints: endpoint_resource = compose_resource_endpoint(endpoint) diff --git a/src/device/service/drivers/emulated/Tools.py b/src/device/service/drivers/emulated/Tools.py index 4770cc6e6d2b2ccbf86d1e3764e62f03b48837e2..0ac92bf56d5538a5ed4d3e7c53bc480d5ecd40bd 100644 --- a/src/device/service/drivers/emulated/Tools.py +++ b/src/device/service/drivers/emulated/Tools.py @@ -13,34 +13,74 @@ # limitations under the License. import logging -from typing import Any, Dict, Tuple +from typing import Any, Dict, Optional, Tuple from common.proto.kpi_sample_types_pb2 import KpiSampleType +from common.type_checkers.Checkers import chk_attribute, chk_string, chk_type from device.service.driver_api._Driver import RESOURCE_ENDPOINTS from .Constants import SPECIAL_RESOURCE_MAPPINGS LOGGER = logging.getLogger(__name__) -def compose_resource_endpoint(endpoint_data : Dict[str, Any]) -> Tuple[str, Any]: - endpoint_uuid = endpoint_data.get('uuid') - if endpoint_uuid is None: return None - endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS) - endpoint_resource_key = '{:s}/endpoint[{:s}]'.format(endpoint_resource_path, endpoint_uuid) - - endpoint_type = endpoint_data.get('type') - if endpoint_type is None: return None - - endpoint_sample_types = endpoint_data.get('sample_types') - if endpoint_sample_types is None: return None - - sample_types = {} - for endpoint_sample_type in endpoint_sample_types: - try: - metric_name = KpiSampleType.Name(endpoint_sample_type).lower().replace('kpisampletype_', '') - except: # pylint: disable=bare-except - LOGGER.warning('Unsupported EndPointSampleType({:s})'.format(str(endpoint_sample_type))) - continue - monitoring_resource_key = '{:s}/state/{:s}'.format(endpoint_resource_key, metric_name) - sample_types[endpoint_sample_type] = monitoring_resource_key - - endpoint_resource_value = {'uuid': endpoint_uuid, 'type': endpoint_type, 'sample_types': sample_types} - return endpoint_resource_key, endpoint_resource_value +def process_optional_string_field( + endpoint_data : Dict[str, Any], field_name : str, endpoint_resource_value : Dict[str, Any] +) -> None: + field_value = chk_attribute(field_name, endpoint_data, 'endpoint_data', default=None) + if field_value is None: return + chk_string('endpoint_data.{:s}'.format(field_name), field_value) + if len(field_value) > 0: endpoint_resource_value[field_name] = field_value + +def compose_resource_endpoint(endpoint_data : Dict[str, Any]) -> Optional[Tuple[str, Dict]]: + try: + # Check type of endpoint_data + chk_type('endpoint_data', endpoint_data, dict) + + # Check endpoint UUID (mandatory) + endpoint_uuid = chk_attribute('uuid', endpoint_data, 'endpoint_data') + chk_string('endpoint_data.uuid', endpoint_uuid, min_length=1) + endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS) + endpoint_resource_key = '{:s}/endpoint[{:s}]'.format(endpoint_resource_path, endpoint_uuid) + endpoint_resource_value = {'uuid': endpoint_uuid} + + # Check endpoint optional string fields + process_optional_string_field(endpoint_data, 'name', endpoint_resource_value) + process_optional_string_field(endpoint_data, 'type', endpoint_resource_value) + process_optional_string_field(endpoint_data, 'context_uuid', endpoint_resource_value) + process_optional_string_field(endpoint_data, 'topology_uuid', endpoint_resource_value) + + # Check endpoint sample types (optional) + endpoint_sample_types = chk_attribute('sample_types', endpoint_data, 'endpoint_data', default=[]) + chk_type('endpoint_data.sample_types', endpoint_sample_types, list) + sample_types = {} + sample_type_errors = [] + for i,endpoint_sample_type in enumerate(endpoint_sample_types): + field_name = 'endpoint_data.sample_types[{:d}]'.format(i) + try: + chk_type(field_name, endpoint_sample_type, (int, str)) + if isinstance(endpoint_sample_type, int): + metric_name = KpiSampleType.Name(endpoint_sample_type) + metric_id = endpoint_sample_type + elif isinstance(endpoint_sample_type, str): + metric_id = KpiSampleType.Value(endpoint_sample_type) + metric_name = endpoint_sample_type + else: + str_type = str(type(endpoint_sample_type)) + raise Exception('Bad format: {:s}'.format(str_type)) # pylint: disable=broad-exception-raised + except Exception as e: # pylint: disable=broad-exception-caught + MSG = 'Unsupported {:s}({:s}) : {:s}' + sample_type_errors.append(MSG.format(field_name, str(endpoint_sample_type), str(e))) + + metric_name = metric_name.lower().replace('kpisampletype_', '') + monitoring_resource_key = '{:s}/state/{:s}'.format(endpoint_resource_key, metric_name) + sample_types[metric_id] = monitoring_resource_key + + if len(sample_type_errors) > 0: + # pylint: disable=broad-exception-raised + raise Exception('Malformed Sample Types:\n{:s}'.format('\n'.join(sample_type_errors))) + + if len(sample_types) > 0: + endpoint_resource_value['sample_types'] = sample_types + + return endpoint_resource_key, endpoint_resource_value + except: # pylint: disable=bare-except + LOGGER.exception('Problem composing endpoint({:s})'.format(str(endpoint_data))) + return None diff --git a/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py b/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py new file mode 100644 index 0000000000000000000000000000000000000000..9498dc84cc6991fd2295371842fa8508c961f1bc --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py @@ -0,0 +1,190 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json, logging, threading +from typing import Any, Iterator, List, Optional, Tuple, Union +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.tools.object_factory.Device import json_device_id +from common.tools.object_factory.EndPoint import json_endpoint_id +from common.type_checkers.Checkers import chk_string, chk_type +from device.service.driver_api._Driver import _Driver, RESOURCE_ENDPOINTS, RESOURCE_SERVICES +from device.service.drivers.ietf_l2vpn.TfsDebugApiClient import TfsDebugApiClient +from .Tools import connection_point, wim_mapping +from .WimconnectorIETFL2VPN import WimconnectorIETFL2VPN + +LOGGER = logging.getLogger(__name__) + +def service_exists(wim : WimconnectorIETFL2VPN, service_uuid : str) -> bool: + try: + wim.get_connectivity_service_status(service_uuid) + return True + except: # pylint: disable=bare-except + return False + +ALL_RESOURCE_KEYS = [ + RESOURCE_ENDPOINTS, + RESOURCE_SERVICES, +] + +SERVICE_TYPE = 'ELINE' + +DRIVER_NAME = 'ietf_l2vpn' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) + +class IetfL2VpnDriver(_Driver): + def __init__(self, address: str, port: int, **settings) -> None: + super().__init__(DRIVER_NAME, address, port, **settings) + self.__lock = threading.Lock() + self.__started = threading.Event() + self.__terminate = threading.Event() + username = self.settings.get('username') + password = self.settings.get('password') + scheme = self.settings.get('scheme', 'http') + wim = {'wim_url': '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port))} + wim_account = {'user': username, 'password': password} + # Mapping updated dynamically with each request + config = {'mapping_not_needed': False, 'service_endpoint_mapping': []} + self.dac = TfsDebugApiClient(self.address, int(self.port), scheme=scheme, username=username, password=password) + self.wim = WimconnectorIETFL2VPN(wim, wim_account, config=config) + self.conn_info = {} # internal database emulating OSM storage provided to WIM Connectors + + def Connect(self) -> bool: + with self.__lock: + try: + self.wim.check_credentials() + except Exception: # pylint: disable=broad-except + LOGGER.exception('Exception checking credentials') + return False + else: + self.__started.set() + return True + + def Disconnect(self) -> bool: + with self.__lock: + self.__terminate.set() + return True + + @metered_subclass_method(METRICS_POOL) + def GetInitialConfig(self) -> List[Tuple[str, Any]]: + with self.__lock: + return [] + + @metered_subclass_method(METRICS_POOL) + def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: + chk_type('resources', resource_keys, list) + results = [] + with self.__lock: + self.wim.check_credentials() + if len(resource_keys) == 0: resource_keys = ALL_RESOURCE_KEYS + for i, resource_key in enumerate(resource_keys): + str_resource_name = 'resource_key[#{:d}]'.format(i) + try: + chk_string(str_resource_name, resource_key, allow_empty=False) + if resource_key == RESOURCE_ENDPOINTS: + # return endpoints through debug-api and list-devices method + results.extend(self.dac.get_devices_endpoints()) + elif resource_key == RESOURCE_SERVICES: + # return all services through + reply = self.wim.get_all_active_connectivity_services() + results.extend(reply.json()) + else: + # assume single-service retrieval + reply = self.wim.get_connectivity_service(resource_key) + results.append(reply.json()) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unhandled error processing resource_key({:s})'.format(str(resource_key))) + results.append((resource_key, e)) + return results + + @metered_subclass_method(METRICS_POOL) + def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + results = [] + if len(resources) == 0: return results + with self.__lock: + self.wim.check_credentials() + for resource in resources: + LOGGER.info('resource = {:s}'.format(str(resource))) + resource_key,resource_value = resource + try: + resource_value = json.loads(resource_value) + service_uuid = resource_value['uuid'] + + if service_exists(self.wim, service_uuid): + exc = NotImplementedError('IETF L2VPN Service Update is still not supported') + results.append((resource[0], exc)) + continue + + src_device_name = resource_value['src_device_name'] + src_endpoint_name = resource_value['src_endpoint_name'] + dst_device_name = resource_value['dst_device_name'] + dst_endpoint_name = resource_value['dst_endpoint_name'] + encap_type = resource_value['encapsulation_type'] + vlan_id = resource_value['vlan_id'] + + src_endpoint_id = json_endpoint_id(json_device_id(src_device_name), src_endpoint_name) + src_service_endpoint_id, src_mapping = wim_mapping('1', src_endpoint_id) + self.wim.mappings[src_service_endpoint_id] = src_mapping + + dst_endpoint_id = json_endpoint_id(json_device_id(dst_device_name), dst_endpoint_name) + dst_service_endpoint_id, dst_mapping = wim_mapping('2', dst_endpoint_id) + self.wim.mappings[dst_service_endpoint_id] = dst_mapping + + connection_points = [ + connection_point(src_service_endpoint_id, encap_type, vlan_id), + connection_point(dst_service_endpoint_id, encap_type, vlan_id), + ] + + self.wim.create_connectivity_service(service_uuid, SERVICE_TYPE, connection_points) + results.append((resource_key, True)) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unhandled error processing resource_key({:s})'.format(str(resource_key))) + results.append((resource_key, e)) + return results + + @metered_subclass_method(METRICS_POOL) + def DeleteConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + results = [] + if len(resources) == 0: return results + with self.__lock: + self.wim.check_credentials() + for resource in resources: + LOGGER.info('resource = {:s}'.format(str(resource))) + resource_key,resource_value = resource + try: + resource_value = json.loads(resource_value) + service_uuid = resource_value['uuid'] + + if service_exists(self.wim, service_uuid): + self.wim.delete_connectivity_service(service_uuid) + results.append((resource_key, True)) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unhandled error processing resource_key({:s})'.format(str(resource_key))) + results.append((resource_key, e)) + return results + + @metered_subclass_method(METRICS_POOL) + def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: + # TODO: IETF L2VPN does not support monitoring by now + return [False for _ in subscriptions] + + @metered_subclass_method(METRICS_POOL) + def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: + # TODO: IETF L2VPN does not support monitoring by now + return [False for _ in subscriptions] + + def GetState( + self, blocking=False, terminate : Optional[threading.Event] = None + ) -> Iterator[Tuple[float, str, Any]]: + # TODO: IETF L2VPN does not support monitoring by now + return [] diff --git a/src/device/service/drivers/ietf_l2vpn/TfsDebugApiClient.py b/src/device/service/drivers/ietf_l2vpn/TfsDebugApiClient.py new file mode 100644 index 0000000000000000000000000000000000000000..4bf40af030fda990f96efe0ff8ab2ce54f82c312 --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/TfsDebugApiClient.py @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, requests +from requests.auth import HTTPBasicAuth +from typing import Dict, List, Optional + +GET_DEVICES_URL = '{:s}://{:s}:{:d}/restconf/debug-api/devices' +TIMEOUT = 30 + +HTTP_OK_CODES = { + 200, # OK + 201, # Created + 202, # Accepted + 204, # No Content +} + +MAPPING_STATUS = { + 'DEVICEOPERATIONALSTATUS_UNDEFINED': 0, + 'DEVICEOPERATIONALSTATUS_DISABLED' : 1, + 'DEVICEOPERATIONALSTATUS_ENABLED' : 2, +} + +MAPPING_DRIVER = { + 'DEVICEDRIVER_UNDEFINED' : 0, + 'DEVICEDRIVER_OPENCONFIG' : 1, + 'DEVICEDRIVER_TRANSPORT_API' : 2, + 'DEVICEDRIVER_P4' : 3, + 'DEVICEDRIVER_IETF_NETWORK_TOPOLOGY': 4, + 'DEVICEDRIVER_ONF_TR_352' : 5, + 'DEVICEDRIVER_XR' : 6, + 'DEVICEDRIVER_IETF_L2VPN' : 7, +} + +MSG_ERROR = 'Could not retrieve devices in remote TeraFlowSDN instance({:s}). status_code={:s} reply={:s}' + +LOGGER = logging.getLogger(__name__) + +class TfsDebugApiClient: + def __init__( + self, address : str, port : int, scheme : str = 'http', + username : Optional[str] = None, password : Optional[str] = None + ) -> None: + self._url = GET_DEVICES_URL.format(scheme, address, port) + self._auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None + + def get_devices_endpoints(self) -> List[Dict]: + reply = requests.get(self._url, timeout=TIMEOUT, verify=False, auth=self._auth) + if reply.status_code not in HTTP_OK_CODES: + msg = MSG_ERROR.format(str(self._url), str(reply.status_code), str(reply)) + LOGGER.error(msg) + raise Exception(msg) + + result = list() + for json_device in reply.json()['devices']: + device_uuid : str = json_device['device_id']['device_uuid']['uuid'] + device_type : str = json_device['device_type'] + #if not device_type.startswith('emu-'): device_type = 'emu-' + device_type + device_status = json_device['device_operational_status'] + device_url = '/devices/device[{:s}]'.format(device_uuid) + device_data = { + 'uuid': json_device['device_id']['device_uuid']['uuid'], + 'name': json_device['name'], + 'type': device_type, + 'status': MAPPING_STATUS[device_status], + 'drivers': [MAPPING_DRIVER[driver] for driver in json_device['device_drivers']], + } + result.append((device_url, device_data)) + + for json_endpoint in json_device['device_endpoints']: + endpoint_uuid = json_endpoint['endpoint_id']['endpoint_uuid']['uuid'] + endpoint_url = '/endpoints/endpoint[{:s}]'.format(endpoint_uuid) + endpoint_data = { + 'device_uuid': device_uuid, + 'uuid': endpoint_uuid, + 'name': json_endpoint['name'], + 'type': json_endpoint['endpoint_type'], + } + result.append((endpoint_url, endpoint_data)) + + return result diff --git a/src/device/service/drivers/ietf_l2vpn/Tools.py b/src/device/service/drivers/ietf_l2vpn/Tools.py new file mode 100644 index 0000000000000000000000000000000000000000..45dfa23c984e175c01efa77371e94454b98ea94e --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/Tools.py @@ -0,0 +1,48 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import Dict, Optional + +def compose_service_endpoint_id(site_id : str, endpoint_id : Dict): + device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] + endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] + return ':'.join([site_id, device_uuid, endpoint_uuid]) + +def wim_mapping(site_id, ce_endpoint_id, pe_device_id : Optional[Dict] = None, priority=None, redundant=[]): + ce_device_uuid = ce_endpoint_id['device_id']['device_uuid']['uuid'] + ce_endpoint_uuid = ce_endpoint_id['endpoint_uuid']['uuid'] + service_endpoint_id = compose_service_endpoint_id(site_id, ce_endpoint_id) + if pe_device_id is None: + bearer = '{:s}:{:s}'.format(ce_device_uuid, ce_endpoint_uuid) + else: + pe_device_uuid = pe_device_id['device_uuid']['uuid'] + bearer = '{:s}:{:s}'.format(ce_device_uuid, pe_device_uuid) + mapping = { + 'service_endpoint_id': service_endpoint_id, + 'datacenter_id': site_id, 'device_id': ce_device_uuid, 'device_interface_id': ce_endpoint_uuid, + 'service_mapping_info': { + 'site-id': site_id, + 'bearer': {'bearer-reference': bearer}, + } + } + if priority is not None: mapping['service_mapping_info']['priority'] = priority + if len(redundant) > 0: mapping['service_mapping_info']['redundant'] = redundant + return service_endpoint_id, mapping + +def connection_point(service_endpoint_id : str, encapsulation_type : str, vlan_id : int): + return { + 'service_endpoint_id': service_endpoint_id, + 'service_endpoint_encapsulation_type': encapsulation_type, + 'service_endpoint_encapsulation_info': {'vlan': vlan_id} + } diff --git a/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py b/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py new file mode 100644 index 0000000000000000000000000000000000000000..34ff184c022f379e7420de237bd08fc1dc6282a6 --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/WimconnectorIETFL2VPN.py @@ -0,0 +1,565 @@ +# -*- coding: utf-8 -*- +## +# Copyright 2018 Telefonica +# All Rights Reserved. +# +# Contributors: Oscar Gonzalez de Dios, Manuel Lopez Bravo, Guillermo Pajares Martin +# 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. +# +# This work has been performed in the context of the Metro-Haul project - +# funded by the European Commission under Grant number 761727 through the +# Horizon 2020 program. +## +"""The SDN/WIM connector is responsible for establishing wide area network +connectivity. + +This SDN/WIM connector implements the standard IETF RFC 8466 "A YANG Data + Model for Layer 2 Virtual Private Network (L2VPN) Service Delivery" + +It receives the endpoints and the necessary details to request +the Layer 2 service. +""" +import requests +import uuid +import logging +import copy +#from osm_ro_plugin.sdnconn import SdnConnectorBase, SdnConnectorError +from .sdnconn import SdnConnectorBase, SdnConnectorError + +"""Check layer where we move it""" + + +class WimconnectorIETFL2VPN(SdnConnectorBase): + def __init__(self, wim, wim_account, config=None, logger=None): + """IETF L2VPN WIM connector + + Arguments: (To be completed) + wim (dict): WIM record, as stored in the database + wim_account (dict): WIM account record, as stored in the database + """ + self.logger = logging.getLogger("ro.sdn.ietfl2vpn") + super().__init__(wim, wim_account, config, logger) + self.headers = {"Content-Type": "application/json"} + self.mappings = { + m["service_endpoint_id"]: m for m in self.service_endpoint_mapping + } + self.user = wim_account.get("user") + self.passwd = wim_account.get("password") + + if self.user is not None and self.passwd is not None: + self.auth = (self.user, self.passwd) + else: + self.auth = None + + self.logger.info("IETFL2VPN Connector Initialized.") + + def check_credentials(self): + endpoint = "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services".format( + self.wim["wim_url"] + ) + + try: + response = requests.get(endpoint, auth=self.auth) + http_code = response.status_code + except requests.exceptions.RequestException as e: + raise SdnConnectorError(e.response, http_code=503) + + if http_code != 200: + raise SdnConnectorError("Failed while authenticating", http_code=http_code) + + self.logger.info("Credentials checked") + + def get_connectivity_service_status(self, service_uuid, conn_info=None): + """Monitor the status of the connectivity service stablished + + Arguments: + service_uuid: Connectivity service unique identifier + + Returns: + Examples:: + {'sdn_status': 'ACTIVE'} + {'sdn_status': 'INACTIVE'} + {'sdn_status': 'DOWN'} + {'sdn_status': 'ERROR'} + """ + try: + self.logger.info("Sending get connectivity service stuatus") + servicepoint = "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services/vpn-service={}/".format( + self.wim["wim_url"], service_uuid + ) + response = requests.get(servicepoint, auth=self.auth) + self.logger.warning('response.status_code={:s}'.format(str(response.status_code))) + if response.status_code != requests.codes.ok: + raise SdnConnectorError( + "Unable to obtain connectivity servcice status", + http_code=response.status_code, + ) + + service_status = {"sdn_status": "ACTIVE"} + + return service_status + except requests.exceptions.ConnectionError: + raise SdnConnectorError("Request Timeout", http_code=408) + + def search_mapp(self, connection_point): + id = connection_point["service_endpoint_id"] + if id not in self.mappings: + raise SdnConnectorError("Endpoint {} not located".format(str(id))) + else: + return self.mappings[id] + + def create_connectivity_service(self, service_uuid, service_type, connection_points, **kwargs): + """Stablish WAN connectivity between the endpoints + + Arguments: + service_type (str): ``ELINE`` (L2), ``ELAN`` (L2), ``ETREE`` (L2), + ``L3``. + connection_points (list): each point corresponds to + an entry point from the DC to the transport network. One + connection point serves to identify the specific access and + some other service parameters, such as encapsulation type. + Represented by a dict as follows:: + + { + "service_endpoint_id": ..., (str[uuid]) + "service_endpoint_encapsulation_type": ..., + (enum: none, dot1q, ...) + "service_endpoint_encapsulation_info": { + ... (dict) + "vlan": ..., (int, present if encapsulation is dot1q) + "vni": ... (int, present if encapsulation is vxlan), + "peers": [(ipv4_1), (ipv4_2)] + (present if encapsulation is vxlan) + } + } + + The service endpoint ID should be previously informed to the WIM + engine in the RO when the WIM port mapping is registered. + + Keyword Arguments: + bandwidth (int): value in kilobytes + latency (int): value in milliseconds + + Other QoS might be passed as keyword arguments. + + Returns: + tuple: ``conn_info``: + - *conn_info* (dict or None): Information to be stored at the + database (or ``None``). This information will be provided to + the :meth:`~.edit_connectivity_service` and :obj:`~.delete`. + **MUST** be JSON/YAML-serializable (plain data structures). + + Raises: + SdnConnectorException: In case of error. + """ + SETTINGS = { # min_endpoints, max_endpoints, vpn_service_type + 'ELINE': (2, 2, 'vpws'), # Virtual Private Wire Service + 'ELAN' : (2, None, 'vpls'), # Virtual Private LAN Service + } + settings = SETTINGS.get(service_type) + if settings is None: raise NotImplementedError('Unsupported service_type({:s})'.format(str(service_type))) + min_endpoints, max_endpoints, vpn_service_type = settings + + if max_endpoints is not None and len(connection_points) > max_endpoints: + msg = "Connections between more than {:d} endpoints are not supported for service_type {:s}" + raise SdnConnectorError(msg.format(max_endpoints, service_type)) + + if min_endpoints is not None and len(connection_points) < min_endpoints: + msg = "Connections must be of at least {:d} endpoints for service_type {:s}" + raise SdnConnectorError(msg.format(min_endpoints, service_type)) + + """First step, create the vpn service""" + vpn_service = {} + vpn_service["vpn-id"] = service_uuid + vpn_service["vpn-svc-type"] = vpn_service_type + vpn_service["svc-topo"] = "any-to-any" + vpn_service["customer-name"] = "osm" + vpn_service_list = [] + vpn_service_list.append(vpn_service) + vpn_service_l = {"ietf-l2vpn-svc:vpn-service": vpn_service_list} + response_service_creation = None + conn_info = [] + self.logger.info("Sending vpn-service :{}".format(vpn_service_l)) + + try: + endpoint_service_creation = ( + "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services".format( + self.wim["wim_url"] + ) + ) + response_service_creation = requests.post( + endpoint_service_creation, + headers=self.headers, + json=vpn_service_l, + auth=self.auth, + ) + except requests.exceptions.ConnectionError: + raise SdnConnectorError( + "Request to create service Timeout", http_code=408 + ) + + if response_service_creation.status_code == 409: + raise SdnConnectorError( + "Service already exists", + http_code=response_service_creation.status_code, + ) + elif response_service_creation.status_code != requests.codes.created: + raise SdnConnectorError( + "Request to create service not accepted", + http_code=response_service_creation.status_code, + ) + + self.logger.info('connection_points = {:s}'.format(str(connection_points))) + + # Check if protected paths are requested + extended_connection_points = [] + for connection_point in connection_points: + extended_connection_points.append(connection_point) + + connection_point_wan_info = self.search_mapp(connection_point) + service_mapping_info = connection_point_wan_info.get('service_mapping_info', {}) + redundant_service_endpoint_ids = service_mapping_info.get('redundant') + + if redundant_service_endpoint_ids is None: continue + if len(redundant_service_endpoint_ids) == 0: continue + + for redundant_service_endpoint_id in redundant_service_endpoint_ids: + redundant_connection_point = copy.deepcopy(connection_point) + redundant_connection_point['service_endpoint_id'] = redundant_service_endpoint_id + extended_connection_points.append(redundant_connection_point) + + self.logger.info('extended_connection_points = {:s}'.format(str(extended_connection_points))) + + """Second step, create the connections and vpn attachments""" + for connection_point in extended_connection_points: + connection_point_wan_info = self.search_mapp(connection_point) + site_network_access = {} + connection = {} + + if connection_point["service_endpoint_encapsulation_type"] != "none": + if ( + connection_point["service_endpoint_encapsulation_type"] + == "dot1q" + ): + """The connection is a VLAN""" + connection["encapsulation-type"] = "dot1q-vlan-tagged" + tagged = {} + tagged_interf = {} + service_endpoint_encapsulation_info = connection_point[ + "service_endpoint_encapsulation_info" + ] + + if service_endpoint_encapsulation_info["vlan"] is None: + raise SdnConnectorError("VLAN must be provided") + + tagged_interf["cvlan-id"] = service_endpoint_encapsulation_info[ + "vlan" + ] + tagged["dot1q-vlan-tagged"] = tagged_interf + connection["tagged-interface"] = tagged + else: + raise NotImplementedError("Encapsulation type not implemented") + + site_network_access["connection"] = connection + self.logger.info("Sending connection:{}".format(connection)) + vpn_attach = {} + vpn_attach["vpn-id"] = service_uuid + vpn_attach["site-role"] = vpn_service["svc-topo"] + "-role" + site_network_access["vpn-attachment"] = vpn_attach + self.logger.info("Sending vpn-attachement :{}".format(vpn_attach)) + uuid_sna = str(uuid.uuid4()) + site_network_access["network-access-id"] = uuid_sna + site_network_access["bearer"] = connection_point_wan_info[ + "service_mapping_info" + ]["bearer"] + + access_priority = connection_point_wan_info["service_mapping_info"].get("priority") + if access_priority is not None: + availability = {} + availability["access-priority"] = access_priority + availability["single-active"] = [None] + site_network_access["availability"] = availability + + constraint = {} + constraint['constraint-type'] = 'end-to-end-diverse' + constraint['target'] = {'all-other-accesses': [None]} + + access_diversity = {} + access_diversity['constraints'] = {'constraint': []} + access_diversity['constraints']['constraint'].append(constraint) + site_network_access["access-diversity"] = access_diversity + + site_network_accesses = {} + site_network_access_list = [] + site_network_access_list.append(site_network_access) + site_network_accesses[ + "ietf-l2vpn-svc:site-network-access" + ] = site_network_access_list + conn_info_d = {} + conn_info_d["site"] = connection_point_wan_info["service_mapping_info"][ + "site-id" + ] + conn_info_d["site-network-access-id"] = site_network_access[ + "network-access-id" + ] + conn_info_d["mapping"] = None + conn_info.append(conn_info_d) + + try: + endpoint_site_network_access_creation = ( + "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/" + "sites/site={}/site-network-accesses/".format( + self.wim["wim_url"], + connection_point_wan_info["service_mapping_info"][ + "site-id" + ], + ) + ) + response_endpoint_site_network_access_creation = requests.post( + endpoint_site_network_access_creation, + headers=self.headers, + json=site_network_accesses, + auth=self.auth, + ) + + if ( + response_endpoint_site_network_access_creation.status_code + == 409 + ): + self.delete_connectivity_service(vpn_service["vpn-id"]) + + raise SdnConnectorError( + "Site_Network_Access with ID '{}' already exists".format( + site_network_access["network-access-id"] + ), + http_code=response_endpoint_site_network_access_creation.status_code, + ) + elif ( + response_endpoint_site_network_access_creation.status_code + == 400 + ): + self.delete_connectivity_service(vpn_service["vpn-id"]) + + raise SdnConnectorError( + "Site {} does not exist".format( + connection_point_wan_info["service_mapping_info"][ + "site-id" + ] + ), + http_code=response_endpoint_site_network_access_creation.status_code, + ) + elif ( + response_endpoint_site_network_access_creation.status_code + != requests.codes.created + and response_endpoint_site_network_access_creation.status_code + != requests.codes.no_content + ): + self.delete_connectivity_service(vpn_service["vpn-id"]) + + raise SdnConnectorError( + "Request not accepted", + http_code=response_endpoint_site_network_access_creation.status_code, + ) + except requests.exceptions.ConnectionError: + self.delete_connectivity_service(vpn_service["vpn-id"]) + + raise SdnConnectorError("Request Timeout", http_code=408) + + return conn_info + + def delete_connectivity_service(self, service_uuid, conn_info=None): + """Disconnect multi-site endpoints previously connected + + This method should receive as the first argument the UUID generated by + the ``create_connectivity_service`` + """ + try: + self.logger.info("Sending delete") + servicepoint = "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services/vpn-service={}/".format( + self.wim["wim_url"], service_uuid + ) + response = requests.delete(servicepoint, auth=self.auth) + + if response.status_code != requests.codes.no_content: + raise SdnConnectorError( + "Error in the request", http_code=response.status_code + ) + except requests.exceptions.ConnectionError: + raise SdnConnectorError("Request Timeout", http_code=408) + + def edit_connectivity_service( + self, service_uuid, conn_info=None, connection_points=None, **kwargs + ): + """Change an existing connectivity service, see + ``create_connectivity_service``""" + # sites = {"sites": {}} + # site_list = [] + vpn_service = {} + vpn_service["svc-topo"] = "any-to-any" + counter = 0 + + for connection_point in connection_points: + site_network_access = {} + connection_point_wan_info = self.search_mapp(connection_point) + params_site = {} + params_site["site-id"] = connection_point_wan_info["service_mapping_info"][ + "site-id" + ] + params_site["site-vpn-flavor"] = "site-vpn-flavor-single" + device_site = {} + device_site["device-id"] = connection_point_wan_info["device-id"] + params_site["devices"] = device_site + # network_access = {} + connection = {} + + if connection_point["service_endpoint_encapsulation_type"] != "none": + if connection_point["service_endpoint_encapsulation_type"] == "dot1q": + """The connection is a VLAN""" + connection["encapsulation-type"] = "dot1q-vlan-tagged" + tagged = {} + tagged_interf = {} + service_endpoint_encapsulation_info = connection_point[ + "service_endpoint_encapsulation_info" + ] + + if service_endpoint_encapsulation_info["vlan"] is None: + raise SdnConnectorError("VLAN must be provided") + + tagged_interf["cvlan-id"] = service_endpoint_encapsulation_info[ + "vlan" + ] + tagged["dot1q-vlan-tagged"] = tagged_interf + connection["tagged-interface"] = tagged + else: + raise NotImplementedError("Encapsulation type not implemented") + + site_network_access["connection"] = connection + vpn_attach = {} + vpn_attach["vpn-id"] = service_uuid + vpn_attach["site-role"] = vpn_service["svc-topo"] + "-role" + site_network_access["vpn-attachment"] = vpn_attach + uuid_sna = conn_info[counter]["site-network-access-id"] + site_network_access["network-access-id"] = uuid_sna + site_network_access["bearer"] = connection_point_wan_info[ + "service_mapping_info" + ]["bearer"] + site_network_accesses = {} + site_network_access_list = [] + site_network_access_list.append(site_network_access) + site_network_accesses[ + "ietf-l2vpn-svc:site-network-access" + ] = site_network_access_list + + try: + endpoint_site_network_access_edit = ( + "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/" + "sites/site={}/site-network-accesses/".format( + self.wim["wim_url"], + connection_point_wan_info["service_mapping_info"]["site-id"], + ) + ) + response_endpoint_site_network_access_creation = requests.put( + endpoint_site_network_access_edit, + headers=self.headers, + json=site_network_accesses, + auth=self.auth, + ) + + if response_endpoint_site_network_access_creation.status_code == 400: + raise SdnConnectorError( + "Service does not exist", + http_code=response_endpoint_site_network_access_creation.status_code, + ) + elif ( + response_endpoint_site_network_access_creation.status_code != 201 + and response_endpoint_site_network_access_creation.status_code + != 204 + ): + raise SdnConnectorError( + "Request no accepted", + http_code=response_endpoint_site_network_access_creation.status_code, + ) + except requests.exceptions.ConnectionError: + raise SdnConnectorError("Request Timeout", http_code=408) + + counter += 1 + + return None + + def clear_all_connectivity_services(self): + """Delete all WAN Links corresponding to a WIM""" + try: + self.logger.info("Sending clear all connectivity services") + servicepoint = ( + "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services".format( + self.wim["wim_url"] + ) + ) + response = requests.delete(servicepoint, auth=self.auth) + + if response.status_code != requests.codes.no_content: + raise SdnConnectorError( + "Unable to clear all connectivity services", + http_code=response.status_code, + ) + except requests.exceptions.ConnectionError: + raise SdnConnectorError("Request Timeout", http_code=408) + + def get_all_active_connectivity_services(self): + """Provide information about all active connections provisioned by a + WIM + """ + try: + self.logger.info("Sending get all connectivity services") + servicepoint = ( + "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services".format( + self.wim["wim_url"] + ) + ) + response = requests.get(servicepoint, auth=self.auth) + + if response.status_code != requests.codes.ok: + raise SdnConnectorError( + "Unable to get all connectivity services", + http_code=response.status_code, + ) + + return response + except requests.exceptions.ConnectionError: + raise SdnConnectorError("Request Timeout", http_code=408) + + def get_connectivity_service(self, service_uuid, conn_info=None): + """Provide information about a specific connection provisioned by a WIM. + + This method should receive as the first argument the UUID generated by + the ``create_connectivity_service`` + """ + try: + self.logger.info("Sending get connectivity service") + servicepoint = ( + "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services/vpn-service={}/".format( + self.wim["wim_url"], service_uuid + ) + ) + response = requests.get(servicepoint, auth=self.auth) + + if response.status_code != requests.codes.ok: + raise SdnConnectorError( + "Unable to get connectivity service {:s}".format(str(service_uuid)), + http_code=response.status_code, + ) + + return response + except requests.exceptions.ConnectionError: + raise SdnConnectorError("Request Timeout", http_code=408) diff --git a/src/device/service/drivers/ietf_l2vpn/__init__.py b/src/device/service/drivers/ietf_l2vpn/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/device/service/drivers/ietf_l2vpn/acknowledgements.txt b/src/device/service/drivers/ietf_l2vpn/acknowledgements.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a7ed47ad6626ad13f4176bd696ec7e7dbab20ee --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/acknowledgements.txt @@ -0,0 +1,3 @@ +IETF L2VPN Driver is based on source code taken from: +https://osm.etsi.org/gitlab/osm/ro/-/blob/master/RO-plugin/osm_ro_plugin/sdnconn.py +https://osm.etsi.org/gitlab/osm/ro/-/blob/master/RO-SDN-ietfl2vpn/osm_rosdn_ietfl2vpn/wimconn_ietfl2vpn.py diff --git a/src/device/service/drivers/ietf_l2vpn/sdnconn.py b/src/device/service/drivers/ietf_l2vpn/sdnconn.py new file mode 100644 index 0000000000000000000000000000000000000000..a1849c9ef3e1a1260ff42bbadabc99f91a6435d7 --- /dev/null +++ b/src/device/service/drivers/ietf_l2vpn/sdnconn.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +## +# Copyright 2018 University of Bristol - High Performance Networks Research +# Group +# All Rights Reserved. +# +# Contributors: Anderson Bravalheri, Dimitrios Gkounis, Abubakar Siddique +# Muqaddas, Navdeep Uniyal, Reza Nejabati and Dimitra Simeonidou +# +# 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. +# +# For those usages not covered by the Apache License, Version 2.0 please +# contact with: +# +# Neither the name of the University of Bristol nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# This work has been performed in the context of DCMS UK 5G Testbeds +# & Trials Programme and in the framework of the Metro-Haul project - +# funded by the European Commission under Grant number 761727 through the +# Horizon 2020 and 5G-PPP programmes. +## +"""The SDN connector is responsible for establishing both wide area network connectivity (WIM) +and intranet SDN connectivity. + +It receives information from ports to be connected . +""" + +import logging +from http import HTTPStatus + + +class SdnConnectorError(Exception): + """Base Exception for all connector related errors + provide the parameter 'http_code' (int) with the error code: + Bad_Request = 400 + Unauthorized = 401 (e.g. credentials are not valid) + Not_Found = 404 (e.g. try to edit or delete a non existing connectivity service) + Forbidden = 403 + Method_Not_Allowed = 405 + Not_Acceptable = 406 + Request_Timeout = 408 (e.g timeout reaching server, or cannot reach the server) + Conflict = 409 + Service_Unavailable = 503 + Internal_Server_Error = 500 + """ + + def __init__(self, message, http_code=HTTPStatus.INTERNAL_SERVER_ERROR.value): + Exception.__init__(self, message) + self.http_code = http_code + + +class SdnConnectorBase(object): + """Abstract base class for all the SDN connectors + + Arguments: + wim (dict): WIM record, as stored in the database + wim_account (dict): WIM account record, as stored in the database + config + The arguments of the constructor are converted to object attributes. + An extra property, ``service_endpoint_mapping`` is created from ``config``. + """ + + def __init__(self, wim, wim_account, config=None, logger=None): + """ + :param wim: (dict). Contains among others 'wim_url' + :param wim_account: (dict). Contains among others 'uuid' (internal id), 'name', + 'sdn' (True if is intended for SDN-assist or False if intended for WIM), 'user', 'password'. + :param config: (dict or None): Particular information of plugin. These keys if present have a common meaning: + 'mapping_not_needed': (bool) False by default or if missing, indicates that mapping is not needed. + 'service_endpoint_mapping': (list) provides the internal endpoint mapping. The meaning is: + KEY meaning for WIM meaning for SDN assist + -------- -------- -------- + device_id pop_switch_dpid compute_id + device_interface_id pop_switch_port compute_pci_address + service_endpoint_id wan_service_endpoint_id SDN_service_endpoint_id + service_mapping_info wan_service_mapping_info SDN_service_mapping_info + contains extra information if needed. Text in Yaml format + switch_dpid wan_switch_dpid SDN_switch_dpid + switch_port wan_switch_port SDN_switch_port + datacenter_id vim_account vim_account + id: (internal, do not use) + wim_id: (internal, do not use) + :param logger (logging.Logger): optional logger object. If none is passed 'openmano.sdn.sdnconn' is used. + """ + self.logger = logger or logging.getLogger("ro.sdn") + self.wim = wim + self.wim_account = wim_account + self.config = config or {} + self.service_endpoint_mapping = self.config.get("service_endpoint_mapping", []) + + def check_credentials(self): + """Check if the connector itself can access the SDN/WIM with the provided url (wim.wim_url), + user (wim_account.user), and password (wim_account.password) + + Raises: + SdnConnectorError: Issues regarding authorization, access to + external URLs, etc are detected. + """ + raise NotImplementedError + + def get_connectivity_service_status(self, service_uuid, conn_info=None): + """Monitor the status of the connectivity service established + + Arguments: + service_uuid (str): UUID of the connectivity service + conn_info (dict or None): Information returned by the connector + during the service creation/edition and subsequently stored in + the database. + + Returns: + dict: JSON/YAML-serializable dict that contains a mandatory key + ``sdn_status`` associated with one of the following values:: + + {'sdn_status': 'ACTIVE'} + # The service is up and running. + + {'sdn_status': 'INACTIVE'} + # The service was created, but the connector + # cannot determine yet if connectivity exists + # (ideally, the caller needs to wait and check again). + + {'sdn_status': 'DOWN'} + # Connection was previously established, + # but an error/failure was detected. + + {'sdn_status': 'ERROR'} + # An error occurred when trying to create the service/ + # establish the connectivity. + + {'sdn_status': 'BUILD'} + # Still trying to create the service, the caller + # needs to wait and check again. + + Additionally ``error_msg``(**str**) and ``sdn_info``(**dict**) + keys can be used to provide additional status explanation or + new information available for the connectivity service. + """ + raise NotImplementedError + + def create_connectivity_service(self, service_type, connection_points, **kwargs): + """ + Establish SDN/WAN connectivity between the endpoints + :param service_type: (str): ``ELINE`` (L2), ``ELAN`` (L2), ``ETREE`` (L2), ``L3``. + :param connection_points: (list): each point corresponds to + an entry point to be connected. For WIM: from the DC to the transport network. + For SDN: Compute/PCI to the transport network. One + connection point serves to identify the specific access and + some other service parameters, such as encapsulation type. + Each item of the list is a dict with: + "service_endpoint_id": (str)(uuid) Same meaning that for 'service_endpoint_mapping' (see __init__) + In case the config attribute mapping_not_needed is True, this value is not relevant. In this case + it will contain the string "device_id:device_interface_id" + "service_endpoint_encapsulation_type": None, "dot1q", ... + "service_endpoint_encapsulation_info": (dict) with: + "vlan": ..., (int, present if encapsulation is dot1q) + "vni": ... (int, present if encapsulation is vxlan), + "peers": [(ipv4_1), (ipv4_2)] (present if encapsulation is vxlan) + "mac": ... + "device_id": ..., same meaning that for 'service_endpoint_mapping' (see __init__) + "device_interface_id": same meaning that for 'service_endpoint_mapping' (see __init__) + "switch_dpid": ..., present if mapping has been found for this device_id,device_interface_id + "swith_port": ... present if mapping has been found for this device_id,device_interface_id + "service_mapping_info": present if mapping has been found for this device_id,device_interface_id + :param kwargs: For future versions: + bandwidth (int): value in kilobytes + latency (int): value in milliseconds + Other QoS might be passed as keyword arguments. + :return: tuple: ``(service_id, conn_info)`` containing: + - *service_uuid* (str): UUID of the established connectivity service + - *conn_info* (dict or None): Information to be stored at the database (or ``None``). + This information will be provided to the :meth:`~.edit_connectivity_service` and :obj:`~.delete`. + **MUST** be JSON/YAML-serializable (plain data structures). + :raises: SdnConnectorException: In case of error. Nothing should be created in this case. + Provide the parameter http_code + """ + raise NotImplementedError + + def delete_connectivity_service(self, service_uuid, conn_info=None): + """ + Disconnect multi-site endpoints previously connected + + :param service_uuid: The one returned by create_connectivity_service + :param conn_info: The one returned by last call to 'create_connectivity_service' or 'edit_connectivity_service' + if they do not return None + :return: None + :raises: SdnConnectorException: In case of error. The parameter http_code must be filled + """ + raise NotImplementedError + + def edit_connectivity_service( + self, service_uuid, conn_info=None, connection_points=None, **kwargs + ): + """Change an existing connectivity service. + + This method's arguments and return value follow the same convention as + :meth:`~.create_connectivity_service`. + + :param service_uuid: UUID of the connectivity service. + :param conn_info: (dict or None): Information previously returned by last call to create_connectivity_service + or edit_connectivity_service + :param connection_points: (list): If provided, the old list of connection points will be replaced. + :param kwargs: Same meaning that create_connectivity_service + :return: dict or None: Information to be updated and stored at the database. + When ``None`` is returned, no information should be changed. + When an empty dict is returned, the database record will be deleted. + **MUST** be JSON/YAML-serializable (plain data structures). + Raises: + SdnConnectorException: In case of error. + """ + + def clear_all_connectivity_services(self): + """Delete all WAN Links in a WIM. + + This method is intended for debugging only, and should delete all the + connections controlled by the WIM/SDN, not only the connections that + a specific RO is aware of. + + Raises: + SdnConnectorException: In case of error. + """ + raise NotImplementedError + + def get_all_active_connectivity_services(self): + """Provide information about all active connections provisioned by a + WIM. + + Raises: + SdnConnectorException: In case of error. + """ + raise NotImplementedError diff --git a/src/device/service/drivers/microwave/IETFApiDriver.py b/src/device/service/drivers/microwave/IETFApiDriver.py index fad7cd0736ec35c5675461af241b2e7de2295dac..a8ef9094652378df8d1f1a55868849316b7ec95b 100644 --- a/src/device/service/drivers/microwave/IETFApiDriver.py +++ b/src/device/service/drivers/microwave/IETFApiDriver.py @@ -23,20 +23,22 @@ from .Tools import create_connectivity_service, find_key, config_getter, delete_ LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'microwave'}) +DRIVER_NAME = 'microwave' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) class IETFApiDriver(_Driver): - def __init__(self, address: str, port: int, **settings) -> None: # pylint: disable=super-init-not-called + def __init__(self, address: str, port: int, **settings) -> None: + super().__init__(DRIVER_NAME, address, port, **settings) self.__lock = threading.Lock() self.__started = threading.Event() self.__terminate = threading.Event() - username = settings.get('username') - password = settings.get('password') + username = self.settings.get('username') + password = self.settings.get('password') self.__auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None - scheme = settings.get('scheme', 'http') - self.__ietf_root = '{:s}://{:s}:{:d}'.format(scheme, address, int(port)) - self.__timeout = int(settings.get('timeout', 120)) - self.__node_ids = set(settings.get('node_ids', [])) + scheme = self.settings.get('scheme', 'http') + self.__ietf_root = '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port)) + self.__timeout = int(self.settings.get('timeout', 120)) + self.__node_ids = set(self.settings.get('node_ids', [])) def Connect(self) -> bool: url = self.__ietf_root + '/nmswebs/restconf/data/ietf-network:networks' diff --git a/src/device/service/drivers/microwave/Tools.py b/src/device/service/drivers/microwave/Tools.py index 711fb55fd4bd9e1bcb16e851aa73f3a61f4bf4bd..4490c0f63fe6a517e5f31a5acd62208013bbaad0 100644 --- a/src/device/service/drivers/microwave/Tools.py +++ b/src/device/service/drivers/microwave/Tools.py @@ -14,7 +14,7 @@ import json, logging, requests from requests.auth import HTTPBasicAuth -from typing import Optional, Set +from typing import Dict, Optional, Set from device.service.driver_api._Driver import RESOURCE_ENDPOINTS LOGGER = logging.getLogger(__name__) @@ -43,6 +43,14 @@ def is_exportable_endpoint(node, termination_point_id, links): return False return True +VLAN_CLASSIFICATION_TYPES = {'ietf-eth-tran-types:vlan-classification', 'vlan-classification'} +OUTER_TAG_C_TYPE = {'ietf-eth-tran-types:classify-c-vlan', 'classify-c-vlan'} +def get_vlan_outer_tag(endpoint : Dict) -> Optional[int]: + if endpoint.get('service-classification-type', '') not in VLAN_CLASSIFICATION_TYPES: return None + outer_tag = endpoint.get('outer-tag', {}) + if outer_tag.get('tag-type', '') not in OUTER_TAG_C_TYPE: return None + return outer_tag.get('vlan-value') + def config_getter( root_url : str, resource_key : str, auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None, node_ids : Set[str] = set() @@ -92,7 +100,35 @@ def config_getter( for service in service_instances: service_name = service['etht-svc-name'] resource_key = '/services/service[{:s}]'.format(service_name) - result.append((resource_key, service)) + resource_value = {'uuid': service.get('etht-svc-name', '')} + + for endpoint in service.get('etht-svc-end-points', []): + _vlan_id = get_vlan_outer_tag(endpoint) + if _vlan_id is not None: + vlan_id = resource_value.get('vlan_id') + if vlan_id is None: + resource_value['vlan_id'] = _vlan_id + elif vlan_id != _vlan_id: + raise Exception('Incompatible VLAN Ids: {:s}'.format(str(service))) + access_points = endpoint.get('etht-svc-access-points', []) + for access_point in access_points: + if access_point['access-point-id'] == '1': + resource_value['node_id_src'] = access_point['access-node-id'] + resource_value['tp_id_src'] = access_point['access-ltp-id'] + elif access_point['access-point-id'] == '2': + resource_value['node_id_dst'] = access_point['access-node-id'] + resource_value['tp_id_dst'] = access_point['access-ltp-id'] + + if len(node_ids) > 0: + node_id_src = resource_value.get('node_id_src') + if node_id_src is None: continue + if node_id_src not in node_ids: continue + + node_id_dst = resource_value.get('node_id_dst') + if node_id_dst is None: continue + if node_id_dst not in node_ids: continue + + result.append((resource_key, resource_value)) except requests.exceptions.Timeout: LOGGER.exception('Timeout connecting {:s}'.format(url)) except Exception as e: # pylint: disable=broad-except diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py index 86026350e2d6c135c142719af58d1abc55623ab2..ec49765a125e7965500a28d47a1d4da109b09e5d 100644 --- a/src/device/service/drivers/openconfig/OpenConfigDriver.py +++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py @@ -21,7 +21,7 @@ from apscheduler.job import Job from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.background import BackgroundScheduler from ncclient.manager import Manager, connect_ssh -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.tools.client.RetryDecorator import delay_exponential from common.type_checkers.Checkers import chk_length, chk_string, chk_type, chk_float from device.service.driver_api.Exceptions import UnsupportedResourceKeyException @@ -121,9 +121,11 @@ class NetconfSessionHandler: config, target=target, default_operation=default_operation, test_option=test_option, error_option=error_option, format=format) + @RETRY_DECORATOR def locked(self, target): return self.__manager.locked(target=target) + @RETRY_DECORATOR def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None): return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id) @@ -242,27 +244,13 @@ def edit_config( results = [e for _ in resources] # if commit fails, set exception in each resource return results -HISTOGRAM_BUCKETS = ( - # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0001, 0.00025, 0.00050, 0.00075, - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - 10.0, 25.0, 50.0, 75.0, - 100.0, INF -) -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'openconfig'}) -METRICS_POOL.get_or_create('GetInitialConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('GetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SubscribeState', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('UnsubscribeState', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) +DRIVER_NAME = 'openconfig' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) class OpenConfigDriver(_Driver): - def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called - self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(address), str(port))) + def __init__(self, address : str, port : int, **settings) -> None: + super().__init__(DRIVER_NAME, address, port, **settings) + self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(self.address), str(self.port))) self.__lock = threading.Lock() #self.__initial = TreeNode('.') #self.__running = TreeNode('.') @@ -272,11 +260,11 @@ class OpenConfigDriver(_Driver): self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events self.__scheduler.configure( jobstores = {'default': MemoryJobStore()}, - executors = {'default': ThreadPoolExecutor(max_workers=1)}, + executors = {'default': ThreadPoolExecutor(max_workers=1)}, # important! 1 = avoid concurrent requests job_defaults = {'coalesce': False, 'max_instances': 3}, timezone=pytz.utc) self.__out_samples = queue.Queue() - self.__netconf_handler : NetconfSessionHandler = NetconfSessionHandler(address, port, **settings) + self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings)) self.__samples_cache = SamplesCache(self.__netconf_handler, self.__logger) def Connect(self) -> bool: diff --git a/src/device/service/drivers/openconfig/templates/EndPoints.py b/src/device/service/drivers/openconfig/templates/EndPoints.py index 02fda8f0e195c267fddb1109f184c8a06e4a6787..f16f0ffcd09a07f6c109328b1c5f0ee101af545a 100644 --- a/src/device/service/drivers/openconfig/templates/EndPoints.py +++ b/src/device/service/drivers/openconfig/templates/EndPoints.py @@ -55,5 +55,5 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]: add_value_from_collection(endpoint, 'sample_types', sample_types) if len(endpoint) == 0: continue - response.append(('/endpoint[{:s}]'.format(endpoint['uuid']), endpoint)) + response.append(('/endpoints/endpoint[{:s}]'.format(endpoint['uuid']), endpoint)) return response diff --git a/src/device/service/drivers/p4/p4_driver.py b/src/device/service/drivers/p4/p4_driver.py index de47f49c05b0f344999382883233a12eceb43c1b..9577b9dad436929d9d9ee1804bcac47cf5c26f91 100644 --- a/src/device/service/drivers/p4/p4_driver.py +++ b/src/device/service/drivers/p4/p4_driver.py @@ -41,7 +41,8 @@ except ImportError: LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'p4'}) +DRIVER_NAME = 'p4' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) class P4Driver(_Driver): """ @@ -80,7 +81,7 @@ class P4Driver(_Driver): self.__endpoint = None self.__settings = settings self.__id = None - self.__name = None + self.__name = DRIVER_NAME self.__vendor = P4_VAL_DEF_VENDOR self.__hw_version = P4_VAL_DEF_HW_VER self.__sw_version = P4_VAL_DEF_SW_VER diff --git a/src/device/service/drivers/transport_api/Tools.py b/src/device/service/drivers/transport_api/Tools.py index 4943648dcab21159b213f9ee938987995be61b0e..bbd4247f0debdd17885c5aadccafc32607e4cbe5 100644 --- a/src/device/service/drivers/transport_api/Tools.py +++ b/src/device/service/drivers/transport_api/Tools.py @@ -15,7 +15,7 @@ import json, logging, operator, requests from requests.auth import HTTPBasicAuth from typing import Optional -from device.service.driver_api._Driver import RESOURCE_ENDPOINTS +from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_SERVICES LOGGER = logging.getLogger(__name__) @@ -52,27 +52,74 @@ def config_getter( result.append((resource_key, e)) return result - if resource_key != RESOURCE_ENDPOINTS: return result - - if 'tapi-common:context' in context: - context = context['tapi-common:context'] - elif 'context' in context: - context = context['context'] - - for sip in context['service-interface-point']: - layer_protocol_name = sip.get('layer-protocol-name', '?') - supportable_spectrum = sip.get('tapi-photonic-media:media-channel-service-interface-point-spec', {}) - supportable_spectrum = supportable_spectrum.get('mc-pool', {}) - supportable_spectrum = supportable_spectrum.get('supportable-spectrum', []) - supportable_spectrum = supportable_spectrum[0] if len(supportable_spectrum) == 1 else {} - grid_type = supportable_spectrum.get('frequency-constraint', {}).get('grid-type') - granularity = supportable_spectrum.get('frequency-constraint', {}).get('adjustment-granularity') - direction = sip.get('direction', '?') - endpoint_type = [layer_protocol_name, grid_type, granularity, direction] - str_endpoint_type = ':'.join(filter(lambda i: operator.is_not(i, None), endpoint_type)) - endpoint_url = '/endpoints/endpoint[{:s}]'.format(sip['uuid']) - endpoint_data = {'uuid': sip['uuid'], 'type': str_endpoint_type} - result.append((endpoint_url, endpoint_data)) + if resource_key == RESOURCE_ENDPOINTS: + if 'tapi-common:context' in context: + context = context['tapi-common:context'] + elif 'context' in context: + context = context['context'] + + for sip in context['service-interface-point']: + layer_protocol_name = sip.get('layer-protocol-name', '?') + supportable_spectrum = sip.get('tapi-photonic-media:media-channel-service-interface-point-spec', {}) + supportable_spectrum = supportable_spectrum.get('mc-pool', {}) + supportable_spectrum = supportable_spectrum.get('supportable-spectrum', []) + supportable_spectrum = supportable_spectrum[0] if len(supportable_spectrum) == 1 else {} + grid_type = supportable_spectrum.get('frequency-constraint', {}).get('grid-type') + granularity = supportable_spectrum.get('frequency-constraint', {}).get('adjustment-granularity') + direction = sip.get('direction', '?') + + endpoint_type = [layer_protocol_name, grid_type, granularity, direction] + str_endpoint_type = ':'.join(filter(lambda i: operator.is_not(i, None), endpoint_type)) + sip_uuid = sip['uuid'] + + sip_names = sip.get('name', []) + sip_name = next(iter([ + sip_name['value'] + for sip_name in sip_names + if sip_name['value-name'] == 'local-name' + ]), sip_uuid) + + endpoint_url = '/endpoints/endpoint[{:s}]'.format(sip_uuid) + endpoint_data = {'uuid': sip_uuid, 'name': sip_name, 'type': str_endpoint_type} + result.append((endpoint_url, endpoint_data)) + + elif resource_key == RESOURCE_SERVICES: + if 'tapi-common:context' in context: + context = context['tapi-common:context'] + elif 'context' in context: + context = context['context'] + + if 'tapi-connectivity:connectivity-context' in context: + context = context['tapi-connectivity:connectivity-context'] + elif 'connectivity-context' in context: + context = context['connectivity-context'] + + for conn_svc in context['connectivity-service']: + service_uuid = conn_svc['uuid'] + constraints = conn_svc.get('connectivity-constraint', {}) + total_req_cap = constraints.get('requested-capacity', {}).get('total-size', {}) + + service_url = '/services/service[{:s}]'.format(service_uuid) + service_data = { + 'uuid': service_uuid, + 'direction': constraints.get('connectivity-direction', 'UNIDIRECTIONAL'), + 'capacity_unit': total_req_cap.get('unit', ''), + 'capacity_value': total_req_cap.get('value', ''), + } + + for i,endpoint in enumerate(conn_svc.get('end-point', [])): + layer_protocol_name = endpoint.get('layer-protocol-name') + if layer_protocol_name is not None: + service_data['layer_protocol_name'] = layer_protocol_name + + layer_protocol_qualifier = endpoint.get('layer-protocol-qualifier') + if layer_protocol_qualifier is not None: + service_data['layer_protocol_qualifier'] = layer_protocol_qualifier + + sip = endpoint['service-interface-point']['service-interface-point-uuid'] + service_data['input_sip' if i == 0 else 'output_sip'] = sip + + result.append((service_url, service_data)) return result diff --git a/src/device/service/drivers/transport_api/TransportApiDriver.py b/src/device/service/drivers/transport_api/TransportApiDriver.py index 8b84274e075e10af04924cefa03768d1c340fb52..98ed8e6aae613ea45519143c89e72af32f3b2620 100644 --- a/src/device/service/drivers/transport_api/TransportApiDriver.py +++ b/src/device/service/drivers/transport_api/TransportApiDriver.py @@ -23,19 +23,21 @@ from .Tools import create_connectivity_service, find_key, config_getter, delete_ LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'transport_api'}) +DRIVER_NAME = 'transport_api' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) class TransportApiDriver(_Driver): - def __init__(self, address: str, port: int, **settings) -> None: # pylint: disable=super-init-not-called + def __init__(self, address: str, port: int, **settings) -> None: + super().__init__(DRIVER_NAME, address, port, **settings) self.__lock = threading.Lock() self.__started = threading.Event() self.__terminate = threading.Event() - username = settings.get('username') - password = settings.get('password') + username = self.settings.get('username') + password = self.settings.get('password') self.__auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None - scheme = settings.get('scheme', 'http') - self.__tapi_root = '{:s}://{:s}:{:d}'.format(scheme, address, int(port)) - self.__timeout = int(settings.get('timeout', 120)) + scheme = self.settings.get('scheme', 'http') + self.__tapi_root = '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port)) + self.__timeout = int(self.settings.get('timeout', 120)) def Connect(self) -> bool: url = self.__tapi_root + '/restconf/data/tapi-common:context' @@ -85,9 +87,9 @@ class TransportApiDriver(_Driver): for resource in resources: LOGGER.info('resource = {:s}'.format(str(resource))) - input_sip = find_key(resource, 'input_sip') - output_sip = find_key(resource, 'output_sip') uuid = find_key(resource, 'uuid') + input_sip = find_key(resource, 'input_sip_uuid') + output_sip = find_key(resource, 'output_sip_uuid') capacity_value = find_key(resource, 'capacity_value') capacity_unit = find_key(resource, 'capacity_unit') layer_protocol_name = find_key(resource, 'layer_protocol_name') diff --git a/src/device/service/drivers/transport_api/__init__.py b/src/device/service/drivers/transport_api/__init__.py index 2d3f6df3276f063cd9b414f47bba41b656682049..d5073c330b89bed63f08b0da86c4a7649c87b3dd 100644 --- a/src/device/service/drivers/transport_api/__init__.py +++ b/src/device/service/drivers/transport_api/__init__.py @@ -12,16 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES +from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_SERVICES ALL_RESOURCE_KEYS = [ RESOURCE_ENDPOINTS, - RESOURCE_INTERFACES, - RESOURCE_NETWORK_INSTANCES, + RESOURCE_SERVICES, ] - -RESOURCE_KEY_MAPPINGS = { - RESOURCE_ENDPOINTS : 'component', - RESOURCE_INTERFACES : 'interface', - RESOURCE_NETWORK_INSTANCES: 'network_instance', -} diff --git a/src/device/service/drivers/xr/README_XR.md b/src/device/service/drivers/xr/README_XR.md index fa1bc944035d27769cd9c16e0c29318e554e9489..9c64cdef1b773e84153c0d27a58e71af8bdf238f 100644 --- a/src/device/service/drivers/xr/README_XR.md +++ b/src/device/service/drivers/xr/README_XR.md @@ -107,7 +107,7 @@ This will make imports to work properly in all cases. Run deploy script to build in docker containers and then instantiate to configured K8s cluster. Deploy script must be sources for this to work! ```bash -./deploy.sh +./deploy/all.sh ``` If protobuf definitions have changed, regenerate version controlled Java files manually diff --git a/src/device/service/drivers/xr/XrDriver.py b/src/device/service/drivers/xr/XrDriver.py index 605f4ce8d0f9c875a4b1736ff0aaa02fcb468778..46269ff8904a0e20dbcb08202220412e64cb6283 100644 --- a/src/device/service/drivers/xr/XrDriver.py +++ b/src/device/service/drivers/xr/XrDriver.py @@ -16,10 +16,13 @@ import logging import threading import json -from typing import Any, Iterator, List, Optional, Tuple, Union +from typing import Any, Iterator, List, Optional, Set, Tuple, Union import urllib3 +from common.DeviceTypes import DeviceTypeEnum from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum from common.type_checkers.Checkers import chk_type +from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum, get_import_topology from device.service.driver_api._Driver import _Driver from .cm.cm_connection import CmConnection, ConsistencyMode from .cm import tf @@ -30,22 +33,32 @@ urllib3.disable_warnings() LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'xr'}) +DRIVER_NAME = 'xr' +METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME}) class XrDriver(_Driver): - def __init__(self, address: str, port: int, **settings) -> None: # pylint: disable=super-init-not-called + def __init__(self, address: str, port: int, **settings) -> None: + super().__init__(DRIVER_NAME, address, port, **settings) self.__lock = threading.Lock() self.__started = threading.Event() self.__terminate = threading.Event() - self.__timeout = int(settings.get('timeout', 120)) - self.__cm_address = address + self.__timeout = int(self.settings.get('timeout', 120)) + self.__cm_address = self.address # Mandatory key, an exception will get thrown if missing - self.__hub_module_name = settings["hub_module_name"] + self.__hub_module_name = self.settings["hub_module_name"] tls_verify = False # Currently using self signed certificates - username = settings.get("username", "xr-user-1") - password = settings.get("password", "xr-user-1") - + username = self.settings.get("username", "xr-user-1") + password = self.settings.get("password", "xr-user-1") + + # Options are: + # disabled --> just import endpoints as usual + # devices --> imports sub-devices but not links connecting them. + # (a remotely-controlled transport domain might exist between them) + # topology --> imports sub-devices and links connecting them. + # (not supported by XR driver) + self.__import_topology = get_import_topology(self.settings, default=ImportTopologyEnum.DISABLED) + # Options are: # asynchronous --> operation considered complete when IPM responds with suitable status code, # including "accepted", that only means request is semantically good and queued. @@ -53,12 +66,12 @@ class XrDriver(_Driver): # lifecycle --> operation is considered successfull once IPM has completed pluggaable configuration # or failed in it. This is typically unsuitable for production use # (as some optics may be transiently unreachable), but is convenient for demos and testin. - consistency_mode = ConsistencyMode.from_str(settings.get("consistency-mode", "asynchronous")) + consistency_mode = ConsistencyMode.from_str(self.settings.get("consistency-mode", "asynchronous")) - self.__cm_connection = CmConnection(address, int(port), username, password, self.__timeout, tls_verify = tls_verify, consistency_mode=consistency_mode) + self.__cm_connection = CmConnection(self.address, int(self.port), username, password, self.__timeout, tls_verify = tls_verify, consistency_mode=consistency_mode) self.__constellation = None - LOGGER.info(f"XrDriver instantiated, cm {address}:{port}, consistency mode {str(consistency_mode)}, {settings=}") + LOGGER.info(f"XrDriver instantiated, cm {self.address}:{self.port}, consistency mode {str(consistency_mode)}, {self.settings=}") def __str__(self): return f"{self.__hub_module_name}@{self.__cm_address}" @@ -77,6 +90,7 @@ class XrDriver(_Driver): def Disconnect(self) -> bool: LOGGER.info(f"Disconnect[{self}]") with self.__lock: + self.__cm_connection.stop_monitoring_errors() self.__terminate.set() return True @@ -98,7 +112,56 @@ class XrDriver(_Driver): constellation = self.__cm_connection.get_constellation_by_hub_name(self.__hub_module_name) if constellation: self.__constellation = constellation - return [(f"/endpoints/endpoint[{ifname}]", {'uuid': ifname, 'type': 'optical', 'sample_types': {}}) for ifname in constellation.ifnames()] + if self.__import_topology == ImportTopologyEnum.DISABLED: + return [ + (f"/endpoints/endpoint[{ifname}]", {'uuid': ifname, 'type': 'optical', 'sample_types': {}}) + for ifname in constellation.ifnames() + ] + elif self.__import_topology == ImportTopologyEnum.DEVICES: + devices : Set[str] = set() + pluggables : Set[str] = set() + devices_and_endpoints = [] + for ifname in constellation.ifnames(): + device_name,pluggable_name = ifname.split('|') + + if device_name not in devices: + device_url = '/devices/device[{:s}]'.format(device_name) + device_data = { + 'uuid': device_name, 'name': device_name, + 'type': DeviceTypeEnum.EMULATED_PACKET_ROUTER.value, + 'status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, + 'drivers': [DeviceDriverEnum.DEVICEDRIVER_UNDEFINED], + } + devices_and_endpoints.append((device_url, device_data)) + + for copper_if_index in range(4): + copper_ifname = '1/{:d}'.format(copper_if_index + 1) + endpoint_url = '/endpoints/endpoint[{:s}]'.format(copper_ifname) + endpoint_data = { + 'device_uuid': device_name, 'uuid': copper_ifname, 'name': copper_ifname, + 'type': 'copper/internal', 'sample_types': {} + } + devices_and_endpoints.append((endpoint_url, endpoint_data)) + + devices.add(device_name) + + if ifname not in pluggables: + endpoint_url = '/endpoints/endpoint[{:s}]'.format(ifname) + if 'hub' in ifname.lower(): + endpoint_type = 'optical/xr-hub' + elif 'leaf' in ifname.lower(): + endpoint_type = 'optical/xr-leaf' + else: + endpoint_type = 'optical/xr' + endpoint_data = { + 'device_uuid': device_name, 'uuid': pluggable_name, 'name': pluggable_name, + 'type': endpoint_type, 'sample_types': {} + } + devices_and_endpoints.append((endpoint_url, endpoint_data)) + + return devices_and_endpoints + else: + raise Exception('Unsupported import_topology mode: {:s}'.format(str(self.__import_topology))) else: return [] diff --git a/src/device/service/drivers/xr/cm-cli.py b/src/device/service/drivers/xr/cm-cli.py index 924ca0c966bbefd8b72c655ea788bdfd0ed08c5d..9aefe969c0549819568882a6215ae3dd86b7df3b 100755 --- a/src/device/service/drivers/xr/cm-cli.py +++ b/src/device/service/drivers/xr/cm-cli.py @@ -16,16 +16,22 @@ # Test program for CmConnection import argparse +import signal import logging import traceback +import threading from typing import Tuple -from cm.cm_connection import CmConnection, ConsistencyMode +from cm.cm_connection import CmConnection, ConsistencyMode, ErrorFromIpm from cm.tf_service import TFService from cm.transport_capacity import TransportCapacity from cm.connection import Connection import cm.tf as tf +import asyncio +import websockets +import ssl +import time -logging.basicConfig(level=logging.INFO) +logging.basicConfig(level=logging.WARNING) parser = argparse.ArgumentParser(description='CM Connectin Test Utility') parser.add_argument('ip', help='CM IP address or domain name') @@ -33,6 +39,7 @@ parser.add_argument('port', help='CM port', type=int) parser.add_argument('username', help='Username') parser.add_argument('password', help='Password') +parser.add_argument('--monitor-errors', action='store_true') parser.add_argument('--list-constellations', action='store_true') parser.add_argument('--show-constellation-by-hub-name', nargs='?', type=str) parser.add_argument('--create-connection', nargs='?', type=str, help="uuid;ifname;ifname;capacity") @@ -84,98 +91,118 @@ else: retry_interval = 0.2 cm = CmConnection(args.ip, args.port, args.username, args.password, timeout=args.timeout, tls_verify=False, consistency_mode=consistency_mode, retry_interval=retry_interval) -if not cm.Connect(): - exit(-1) - -if args.list_constellations: - constellations = cm.list_constellations() - for constellation in constellations: - print("Constellation:", constellation.constellation_id) - for if_name in constellation.ifnames(): - print(f" {if_name}") - -if args.show_constellation_by_hub_name: - constellation = cm.get_constellation_by_hub_name(args.show_constellation_by_hub_name) - if constellation: - print(f"Constellation: {constellation.constellation_id}, traffic-mode: {constellation.traffic_mode}") - for if_name in constellation.ifnames(): - print(f" {if_name}") - -if args.create_connection: - tf_service = cli_create_string_to_tf_service(args.create_connection) - connection = Connection(from_tf_service=tf_service) - created_service = cm.create_connection(connection) - if created_service: - print(f"Created {created_service} for {connection}") - else: - print(f"Failed to create {connection}") - -if args.modify_connection: - href, tf_service = cli_modify_string_to_tf_service(args.modify_connection) - mc_args = args.modify_connection.split(";") - connection = Connection(from_tf_service=tf_service) - result = cm.update_connection(href, connection) - if result: - print(f"Updated {href} for {connection}") - else: - print(f"Failed to update {href} for {connection}") - -if args.show_connection_by_name: - connection = cm.get_connection_by_name(args.show_connection_by_name) - if connection: - print(str(connection)) - -if args.list_connections: - connections = cm.get_connections() - for c in connections: - print(str(c)) - -if args.delete_connection: - was_deleted = cm.delete_connection(args.delete_connection) - if was_deleted: - print(f"Successfully deleted {args.delete_connection}") - else: - print(f"Failed to delete {args.delete_connection}") - -if args.list_transport_capacities: - tcs = cm.get_transport_capacities() - for tc in tcs: - print(str(tc)) - -if args.create_transport_capacity: - tf_service = cli_create_string_to_tf_service(args.create_transport_capacity) - tc = TransportCapacity(from_tf_service=tf_service) - created_service = cm.create_transport_capacity(tc) - if created_service: - print(f"Created {created_service} for {tc}") - else: - print(f"Failed to create {tc}") - -if args.emulate_tf_set_config_service: - eargs = args.emulate_tf_set_config_service.split(";") - if len(eargs) < 5: - print("Mandatory tokens missing for --emulate-tf-set-config-service") - exit(-1) - hub_module_name, uuid, input_sip, output_sip, capacity_value = eargs[0:5] - capacity_value = int(capacity_value) - config = { - "input_sip": input_sip, - "output_sip": output_sip, - "capacity_value": capacity_value, - "capacity_unit": "gigabit" - } +terminate = threading.Event() +def signal_handler(sig, frame): + cm.stop_monitoring_errors() + terminate.set() - constellation = cm.get_constellation_by_hub_name(hub_module_name) +signal.signal(signal.SIGINT, signal_handler) - # Allow testing some of the VTI code before we have CM that has VTI - if len(eargs) > 5 and eargs[5] == "FORCE-VTI-ON": - constellation.traffic_mode = "VTIMode" - - if constellation is None: - print(f"Unable to find constellation for hub-module {hub_module_name}") +try: + if not cm.Connect(): exit(-1) - result = tf.set_config_for_service(cm, constellation, uuid, config) - print(f"Emulated SetConfig() for service result: {result}") - if isinstance(result, Exception): - traceback.print_exception(result) + + if args.list_constellations: + constellations = cm.list_constellations() + for constellation in constellations: + print("Constellation:", constellation.constellation_id) + for if_name in constellation.ifnames(): + print(f" {if_name}") + + if args.show_constellation_by_hub_name: + constellation = cm.get_constellation_by_hub_name(args.show_constellation_by_hub_name) + if constellation: + print(f"Constellation: {constellation.constellation_id}, traffic-mode: {constellation.traffic_mode}") + for if_name in constellation.ifnames(): + print(f" {if_name}") + + if args.create_connection: + tf_service = cli_create_string_to_tf_service(args.create_connection) + connection = Connection(from_tf_service=tf_service) + try: + created_service = cm.create_connection(connection) + if created_service: + print(f"Created {created_service} for {connection}") + else: + print(f"Failed to create {connection}") + except ErrorFromIpm as ipm_err: + print(f"Failed to create {connection}: {str(ipm_err)}") + + if args.modify_connection: + href, tf_service = cli_modify_string_to_tf_service(args.modify_connection) + mc_args = args.modify_connection.split(";") + connection = Connection(from_tf_service=tf_service) + result = cm.update_connection(href, connection) + if result: + print(f"Updated {href} for {connection}") + else: + print(f"Failed to update {href} for {connection}") + + if args.show_connection_by_name: + connection = cm.get_connection_by_name(args.show_connection_by_name) + if connection: + print(str(connection)) + + if args.list_connections: + connections = cm.get_connections() + for c in connections: + print(str(c)) + + if args.delete_connection: + was_deleted = cm.delete_connection(args.delete_connection) + if was_deleted: + print(f"Successfully deleted {args.delete_connection}") + else: + print(f"Failed to delete {args.delete_connection}") + + if args.list_transport_capacities: + tcs = cm.get_transport_capacities() + for tc in tcs: + print(str(tc)) + + if args.create_transport_capacity: + tf_service = cli_create_string_to_tf_service(args.create_transport_capacity) + tc = TransportCapacity(from_tf_service=tf_service) + created_service = cm.create_transport_capacity(tc) + if created_service: + print(f"Created {created_service} for {tc}") + else: + print(f"Failed to create {tc}") + + if args.emulate_tf_set_config_service: + eargs = args.emulate_tf_set_config_service.split(";") + if len(eargs) < 5: + print("Mandatory tokens missing for --emulate-tf-set-config-service") + exit(-1) + + hub_module_name, uuid, input_sip, output_sip, capacity_value = eargs[0:5] + capacity_value = int(capacity_value) + config = { + "input_sip_name": input_sip, + "output_sip_name": output_sip, + "capacity_value": capacity_value, + "capacity_unit": "gigabit" + } + + constellation = cm.get_constellation_by_hub_name(hub_module_name) + + # Allow testing some of the VTI code before we have CM that has VTI + if len(eargs) > 5 and eargs[5] == "FORCE-VTI-ON": + constellation.traffic_mode = "VTIMode" + + if constellation is None: + print(f"Unable to find constellation for hub-module {hub_module_name}") + exit(-1) + result = tf.set_config_for_service(cm, constellation, uuid, config) + print(f"Emulated SetConfig() for service result: {result}") + if isinstance(result, Exception): + traceback.print_exception(result) + + if args.monitor_errors: + cm.print_received_errors = True + terminate.wait() + +finally: +# Delete subscriptions. It will end monitoring thread and ensure that program terminates normally + cm.stop_monitoring_errors() diff --git a/src/device/service/drivers/xr/cm/cm_connection.py b/src/device/service/drivers/xr/cm/cm_connection.py index 7128494510f40914917d2c3981158b6dd3571c70..bcd62862de82f115c7c1ef7e98039e6398e62891 100644 --- a/src/device/service/drivers/xr/cm/cm_connection.py +++ b/src/device/service/drivers/xr/cm/cm_connection.py @@ -15,9 +15,13 @@ from __future__ import annotations import collections.abc +import threading import logging import json import time +import asyncio +import websockets +import ssl from typing import Optional, List, Dict, Union import re import requests @@ -51,6 +55,55 @@ class ExpiringValue: class UnexpectedEmptyBody(Exception): pass +class ExternalError(Exception): + pass + +class ApiErrorFromIpm(Exception): + pass + +class ErrorFromIpm(ExternalError): + def __init__(self, err_dict): + msg = str(err_dict) + # Try to extract a short error message + try: + # Only look at first message + err_messages = err_dict["errors"]["errors"][0]["messages"] + for err_msg in err_messages: + if err_msg["lang"] == "en": + msg = err_msg["message"] + except KeyError: + pass + except IndexError: + pass + super().__init__(msg) + +class CreateConsistencyError(Exception): + pass + +class ErrorStore: + def __init__(self): + self.__lock = threading.Lock() + self.__db={} + self.__enabled=False + + def get_error(self, uri: str) -> Optional[dict]: + with self.__lock: + return self.__db.pop(uri, None) + + def set_error(self, uri: str, err_dict: dict): + with self.__lock: + if self.__enabled: + self.__db[uri] = err_dict + + def enable(self): + with self.__lock: + self.__enabled = True + + def disable(self): + with self.__lock: + self.__enabled = False + self.__db.clear() + # This is enum, not a regular class, see https://docs.python.org/3/library/enum.html # String based enums require python 3.11, so use nunber based and custom parser class ConsistencyMode(Enum): @@ -134,10 +187,25 @@ class HttpResult: return True + def raise_as_exception(self): + if self.exception is not None: + raise ExternalError(f"Failure for request {str(self)}") from self.exception + + status_code = self.status_code if self.status_code is not None else "" + + # Try to get error message from IPM + if self.json is not None and "errors" in self.json: + err_list = self.json["errors"] + if len(err_list) > 0 and "message" in err_list[0]: + err_msg = err_list[0]["message"] + raise ApiErrorFromIpm(f"{self.method} {self.url} {self.params}, status {status_code}, IPM reported error: {err_msg}") + + raise ExternalError(str(self)) + class CmConnection: CONSISTENCY_WAIT_LOG_INTERVAL = 1.0 - def __init__(self, address: str, port: int, username: str, password: str, timeout=30, tls_verify=True, consistency_mode: ConsistencyMode = ConsistencyMode.asynchronous, retry_interval: float=0.2, max_consistency_tries:int = 100_000) -> None: + def __init__(self, address: str, port: int, username: str, password: str, timeout=30, tls_verify=True, consistency_mode: ConsistencyMode = ConsistencyMode.asynchronous, retry_interval: float=0.2, max_consistency_tries:int = 100_000, monitor_error_stream: bool = True) -> None: self.__tls_verify = tls_verify if not tls_verify: urllib3.disable_warnings() @@ -151,7 +219,18 @@ class CmConnection: self.__username = username self.__password = password self.__cm_root = 'https://' + address + ':' + str(port) + self.__cm_ws_root = 'wss://' + address + ':' + str(port) self.__access_token = None + self.__monitor_error_stream = monitor_error_stream + self.__err_store=ErrorStore() + self.__err_monitor_thread = None + self.__err_monitor_connected = threading.Event() + self.__err_monitor_sub_id = None + self.__err_monitor_terminate = threading.Event() + self.print_received_errors = False + + def __del__(self): + self.stop_monitoring_errors() def __perform_request(self, http_result: HttpResult, permit_empty_body: bool, fn, *args, **kwargs): try: @@ -238,7 +317,121 @@ class CmConnection: self.__acquire_access_token() def Connect(self) -> bool: - return self.__acquire_access_token() + if not self.__acquire_access_token(): + return False + return self.monitor_errors() if self.__monitor_error_stream else True + + def subscribe_errors(self): + sub = [ + { + "subscriptionName": "TfXrDriverErrorMonitopr", + "subscriptionFilters": [ + { + "requestedNotificationTypes": [ "Error" ], + "requestedResources": [ + { + "resourceType": "cm.network-connection", + } + ] + }, + ] + } + ] + + r = self.__post("/api/v1/subscriptions/events", sub) + #print(r.status_code, r.text) + if not r.is_valid_json_list_with_status(201) or len(r.json) != 1: + return None, None + try: + return self.__cm_ws_root + r.json[0]["notificationChannel"]["streamAddress"], r.json[0]["subscriptionId"] + except KeyError: + return None, None + + def unsubscribe(self, sub_id: str): + resp = self.__delete(f"/api/v1/subscriptions/events/{sub_id}") + if resp.is_valid_with_status_ignore_body(202): + LOGGER.info(f"Deleted subscription {sub_id=}") + return True + else: + LOGGER.info(f"Deleting subscription {sub_id=} failed, status {resp.status_code}") + return False + + def monitor_errors(self) -> bool: + uri, sub_id = self.subscribe_errors() + if not uri or not sub_id: + return False + self.__err_monitor_sub_id = sub_id + + def err_monitor_thread(): + LOGGER.info(f"Listening errors via {uri}") + + ctx = ssl.create_default_context() + if not self.__tls_verify: + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + + async def receive_websock(uri, ssl_ctx): + while not self.__err_monitor_terminate.is_set(): + try: + async with websockets.connect(uri, ssl=ssl_ctx) as websocket: + LOGGER.info(f"err_monitor_thread(): WebSock connected to {uri}") + self.__err_monitor_connected.set() + while not self.__err_monitor_terminate.is_set(): + # 5s timeout is used for forced checking of terminate flag + # In normal termmination timeout is not experienced, as + # we unsubscribe and that will trigger server to close the + # connection. This timeout exists purely as backup + # in case unsubscribe fails + try: + msg = await asyncio.wait_for(websocket.recv(), timeout=5.0) + except asyncio.exceptions.TimeoutError: + continue + if self.print_received_errors: + print(f"RX: {msg}") + try: + msg_json = json.loads(msg) + href = msg_json["href"] + LOGGER.debug(f"err_monitor_thread(): RX [{href}]: {msg}") + self.__err_store.set_error(href, msg_json) + except json.JSONDecodeError as json_err: + LOGGER.error(f"err_monitor_thread(): Invalid message received: {msg}, JSON decode error {str(json_err)}") + except KeyError: + LOGGER.error(f"err_monitor_thread(): Missing href in message: {msg}") + except asyncio.CancelledError as e: + LOGGER.debug("err_monitor_thread(): monitoring cancelled") + raise e + except Exception as e: + if not self.__err_monitor_terminate.is_set(): + LOGGER.error(f"err_monitor_thread(): exception {str(e)}, reconnecting") + time.sleep(1) + + asyncio.run(receive_websock(uri, ctx)) + LOGGER.debug("err_monitor_thread(): thread terminating") + + assert self.__err_monitor_thread is None + self.__err_monitor_terminate.clear() + self.__err_monitor_thread = threading.Thread(target=err_monitor_thread) + self.__err_monitor_thread.start() + # If we can get connection soon, wait for it, otherwise proceed without delay + # Not waiting for connection may miss some errors (-->timeout later), waiting too long + # makes for bad experience + self.__err_monitor_connected.wait(0.5) + + return True + + def stop_monitoring_errors(self): + self.__err_monitor_terminate.set() + + if self.__err_monitor_sub_id: + LOGGER.debug(f"Disabling error subscribtion {self.__err_monitor_sub_id }") + self.unsubscribe(self.__err_monitor_sub_id) + self.__err_monitor_sub_id = None + + if self.__err_monitor_thread is not None: + LOGGER.debug("Terminating error monitoring thread") + self.__err_monitor_thread.join() + LOGGER.info("Error monitoring thread terminated") + self.__err_monitor_thread = None def list_constellations(self) -> List[Constellation]: r = self.__get("/api/v1/xr-networks?content=expanded") @@ -246,7 +439,6 @@ class CmConnection: return [] return [Constellation(c) for c in r.json] - def get_constellation_by_hub_name(self, hub_module_name: str) -> Optional[Constellation]: qparams = [ ('content', 'expanded'), @@ -324,6 +516,11 @@ class CmConnection: log_ts = ts LOGGER.info(f"apply_create_consistency(): waiting for life cycle state progress for {get_result}, current: {str(get_result.life_cycle_info)}, ellapsed time {ts-ts_start} seconds") else: + err_info = self.__err_store.get_error(obj.href) + if err_info is not None: + LOGGER.info(f"apply_create_consistency(): asynchronous error reported for {obj}: {str(err_info)}") + raise ErrorFromIpm(err_info) + ts = time.perf_counter() if ts - log_ts >= self.CONSISTENCY_WAIT_LOG_INTERVAL: log_ts = ts @@ -337,10 +534,13 @@ class CmConnection: duration = time.perf_counter() - ts_start if not valid: if get_result: - LOGGER.info(f"Failed to apply create consistency for {get_result}, insufficient life-cycle-state progress ({str(get_result.life_cycle_info)}), duration {duration} seconds") + msg = f"Failed to apply create consistency for {get_result}, insufficient life-cycle-state progress ({str(get_result.life_cycle_info)}), duration {duration} seconds" + LOGGER.info(msg) + raise CreateConsistencyError(msg) else: - LOGGER.info(f"Failed to apply create consistency for {obj}, REST object did not appear, duration {duration} seconds") - return None + msg = f"Failed to apply create consistency for {obj}, REST object did not appear, duration {duration} seconds" + LOGGER.info(msg) + raise CreateConsistencyError(msg) else: LOGGER.info(f"Applied create consistency for {get_result}, final life-cycle-state {str(get_result.life_cycle_info)}, duration {duration} seconds") @@ -399,20 +599,24 @@ class CmConnection: # Create wants a list, so wrap connection to list cfg = [connection.create_config()] - resp = self.__post("/api/v1/network-connections", cfg) - if resp.is_valid_json_list_with_status(202, 1, 1) and "href" in resp.json[0]: - connection.href = resp.json[0]["href"] - LOGGER.info(f"IPM accepted create request for connection {connection}") - new_connection = self.apply_create_consistency(connection, lambda: self.get_connection_by_href(connection.href)) - if new_connection: - LOGGER.info(f"Created connection {new_connection}") - return new_connection.href + self.__err_store.enable() + try: + resp = self.__post("/api/v1/network-connections", cfg) + if resp.is_valid_json_list_with_status(202, 1, 1) and "href" in resp.json[0]: + connection.href = resp.json[0]["href"] + LOGGER.info(f"IPM accepted create request for connection {connection}") + new_connection = self.apply_create_consistency(connection, lambda: self.get_connection_by_href(connection.href)) + if new_connection: + LOGGER.info(f"Created connection {new_connection}") + return new_connection.href + else: + LOGGER.error(f"Consistency failure for connection {connection}, result {resp}") + return None else: - LOGGER.error(f"Consistency failure for connection {connection}, result {resp}") - return None - else: - LOGGER.error(f"Create failure for connection {connection}, result {resp}") - return None + LOGGER.error(f"Create failure for connection {connection}, result {resp}") + resp.raise_as_exception() + finally: + self.__err_store.disable() def update_connection(self, href: str, connection: Connection, existing_connection: Optional[Connection]=None) -> Optional[str]: cfg = connection.create_config() diff --git a/src/device/service/drivers/xr/cm/tests/test_cm_connection.py b/src/device/service/drivers/xr/cm/tests/test_cm_connection.py index a7944ed220c6d68aad2f122a0bb0d2c1f83fdd06..22b74f36a60e3eda4a0d08d9791cae112b7fd605 100644 --- a/src/device/service/drivers/xr/cm/tests/test_cm_connection.py +++ b/src/device/service/drivers/xr/cm/tests/test_cm_connection.py @@ -37,30 +37,30 @@ def test_cmc_connect(): # Valid access token with requests_mock.Mocker() as m: m.post('https://127.0.0.1:9999/realms/xr-cm/protocol/openid-connect/token', text=access_token) - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert cm.Connect() # Valid JSON but no access token with requests_mock.Mocker() as m: m.post('https://127.0.0.1:9999/realms/xr-cm/protocol/openid-connect/token', text=r'{"a": "b"}') - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert not cm.Connect() # Invalid JSON with requests_mock.Mocker() as m: m.post('https://127.0.0.1:9999/realms/xr-cm/protocol/openid-connect/token', text=r'}}}') - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert not cm.Connect() with requests_mock.Mocker() as m: # No mock present for the destination - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert not cm.Connect() def test_cmc_get_constellations(): with mock_cm_connectivity() as m: m.get("https://127.0.0.1:9999/api/v1/xr-networks?content=expanded", text=res_constellations) - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert cm.Connect() # List all constellations diff --git a/src/device/service/drivers/xr/cm/tests/test_xr_service_set_config.py b/src/device/service/drivers/xr/cm/tests/test_xr_service_set_config.py index e9b16b62034bcd42061907d920b757b59766f562..42785caad79f4ba6000877e81d3caf403c463c1a 100644 --- a/src/device/service/drivers/xr/cm/tests/test_xr_service_set_config.py +++ b/src/device/service/drivers/xr/cm/tests/test_xr_service_set_config.py @@ -20,7 +20,7 @@ import traceback import copy import requests_mock -from ..cm_connection import CmConnection, ConsistencyMode +from ..cm_connection import CmConnection, ConsistencyMode, CreateConsistencyError from ..tf import set_config_for_service access_token = r'{"access_token":"eyI3...","expires_in":3600,"refresh_expires_in":0,"refresh_token":"ey...","token_type":"Bearer","not-before-policy":0,"session_state":"f6e235c4-4ca4-4258-bede-4f2b7125adfb","scope":"profile email offline_access"}' @@ -44,20 +44,23 @@ def mock_cm(): uuid = "12345ABCDEFGHIJKLMN" config = { - "input_sip": "XR HUB 1|XR-T4;", - "output_sip": "XR LEAF 1|XR-T1", + "input_sip_name": "XR HUB 1|XR-T4;", + "output_sip_name": "XR LEAF 1|XR-T1", "capacity_value": 125, "capacity_unit": "gigabit" } def _validate_result(result, expect): - if isinstance(result, Exception): - traceback.print_exception(result) - assert result is expect # Not, "is", not ==, we want type checking in this case, as also an exception can be returned (as return value) + if isinstance(expect, Exception): + assert type(result) == type(expect) + else: + if isinstance(result, Exception): + traceback.print_exception(result) + assert result is expect # Not, "is", not ==, we want type checking in this case, as also an exception can be returned (as return value) def test_xr_set_config(): with mock_cm() as m: - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert cm.Connect() constellation = cm.get_constellation_by_hub_name("XR HUB 1") @@ -86,7 +89,7 @@ def repeat_last_expected(expected: list[tuple], called: list[tuple]) -> list[tup def test_xr_set_config_consistency_lifecycle(): with mock_cm() as m: - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, consistency_mode=ConsistencyMode.lifecycle, retry_interval=0, timeout=1, max_consistency_tries=3) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, consistency_mode=ConsistencyMode.lifecycle, retry_interval=0, timeout=1, max_consistency_tries=3, monitor_error_stream=False) assert cm.Connect() constellation = cm.get_constellation_by_hub_name("XR HUB 1") @@ -125,7 +128,7 @@ def test_xr_set_config_consistency_lifecycle(): { 'json': json_non_terminal, 'status_code': 200 }]) result = set_config_for_service(cm, constellation, uuid, config) - _validate_result(result, False) # Service creation failure due to insufficient progress + _validate_result(result, CreateConsistencyError("")) # Service creation failure due to insufficient progress called_mocks = [(r._request.method, r._request.url) for r in m._adapter.request_history] expected_mocks_no_connect = [ @@ -139,7 +142,7 @@ def test_xr_set_config_consistency_lifecycle(): ################################################################################ # Same as before, but CmConnection no longer requiring lifcycle progress m.reset_mock() - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, consistency_mode=ConsistencyMode.synchronous, retry_interval=0, timeout=1, max_consistency_tries=3) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, consistency_mode=ConsistencyMode.synchronous, retry_interval=0, timeout=1, max_consistency_tries=3, monitor_error_stream=False) assert cm.Connect() constellation = cm.get_constellation_by_hub_name("XR HUB 1") assert constellation @@ -154,21 +157,21 @@ def test_xr_set_config_consistency_lifecycle(): ################################################################################ # Same as above, but without REST object appearing m.reset_mock() - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, consistency_mode=ConsistencyMode.synchronous, retry_interval=0, timeout=1, max_consistency_tries=3) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, consistency_mode=ConsistencyMode.synchronous, retry_interval=0, timeout=1, max_consistency_tries=3, monitor_error_stream=False) assert cm.Connect() constellation = cm.get_constellation_by_hub_name("XR HUB 1") assert constellation m.get("https://127.0.0.1:9999/api/v1/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432", [{'text': '', 'status_code': 401}]) result = set_config_for_service(cm, constellation, uuid, config) - _validate_result(result, False) + _validate_result(result, CreateConsistencyError("")) called_mocks = [(r._request.method, r._request.url) for r in m._adapter.request_history] assert called_mocks == repeat_last_expected(expected_mocks[:2] + expected_mocks_no_connect, called_mocks) def test_xr_set_config_update_case(): with mock_cm() as m: - cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False) + cm = CmConnection("127.0.0.1", 9999, "xr-user", "xr-password", tls_verify=False, monitor_error_stream=False) assert cm.Connect() constellation = cm.get_constellation_by_hub_name("XR HUB 1") diff --git a/src/device/service/drivers/xr/cm/tf.py b/src/device/service/drivers/xr/cm/tf.py index c44cb0c9f3ce0e755ce375908a520374e639e40f..4b1352216d79aea46beca8c5383f64f39869f91b 100644 --- a/src/device/service/drivers/xr/cm/tf.py +++ b/src/device/service/drivers/xr/cm/tf.py @@ -15,7 +15,7 @@ from typing import Dict, Union import logging -from .cm_connection import CmConnection +from .cm_connection import CmConnection, ExternalError from .constellation import Constellation from .tf_service import TFService from .transport_capacity import TransportCapacity @@ -38,7 +38,7 @@ def _get_capacity(config) -> int: def set_config_for_service(cm_connection: CmConnection, constellation: Constellation, uuid: str, config: Dict[str, any]) -> Union[bool, Exception]: try: - service = TFService(uuid, config["input_sip"], config["output_sip"], _get_capacity(config)) + service = TFService(uuid, config["input_sip_name"], config["output_sip_name"], _get_capacity(config)) if constellation.is_vti_mode(): desired_tc = TransportCapacity(from_tf_service=service) active_tc = cm_connection.get_transport_capacity_by_name(service.name()) @@ -57,13 +57,17 @@ def set_config_for_service(cm_connection: CmConnection, constellation: Constella LOGGER.error(f"set_config_for_service: Failed to create Transport Capacity ({desired_tc=})") return False connection = Connection(from_tf_service=service) - href = cm_connection.create_or_update_connection(connection) - if href: - LOGGER.info(f"set_config_for_service: Created service {uuid} as {href} (connection={str(connection)})") - return True - else: - LOGGER.error(f"set_config_for_service: Service creation failure for {uuid} (connection={str(connection)})") - return False + try: + href = cm_connection.create_or_update_connection(connection) + if href: + LOGGER.info(f"set_config_for_service: Created service {uuid} as {href} (connection={str(connection)})") + return True + else: + LOGGER.error(f"set_config_for_service: Service creation failure for {uuid} (connection={str(connection)})") + return False + except ExternalError as e: + LOGGER.error(f"set_config_for_service: Service creation failure for {uuid} (connection={str(connection)}): {str(e)}") + return e # Intentionally catching all exceptions, as they are stored in a list as return values # by the caller # pylint: disable=broad-except diff --git a/src/dlt/connector/service/__main__.py b/src/dlt/connector/service/__main__.py index c9812f90a76ebb06e35bde23033758e5740b877a..9d73ca9fcbfb8d7cda2308b2f58a3f84f72f072e 100644 --- a/src/dlt/connector/service/__main__.py +++ b/src/dlt/connector/service/__main__.py @@ -58,7 +58,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/dlt/mock_blockchain/service/__main__.py b/src/dlt/mock_blockchain/service/__main__.py index e4cffac51064b68c2acc494410e51785c45cd437..65a80ed51c25afcf825fff427a41c7d484e25595 100644 --- a/src/dlt/mock_blockchain/service/__main__.py +++ b/src/dlt/mock_blockchain/service/__main__.py @@ -49,7 +49,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/interdomain/service/InterdomainServiceServicerImpl.py b/src/interdomain/service/InterdomainServiceServicerImpl.py index b72fc1b3122c3d04bde5394ae33d973fa33fa3b8..51c8ee39aa0fc70aa96fe8154cbc312043d2c488 100644 --- a/src/interdomain/service/InterdomainServiceServicerImpl.py +++ b/src/interdomain/service/InterdomainServiceServicerImpl.py @@ -13,7 +13,8 @@ # limitations under the License. import grpc, logging, uuid -from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, ServiceNameEnum +from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, find_missing_environment_variables, get_env_var_name from common.proto.context_pb2 import AuthenticationResult, Slice, SliceId, SliceStatusEnum, TeraFlowController, TopologyId from common.proto.interdomain_pb2_grpc import InterdomainServiceServicer from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method @@ -35,8 +36,6 @@ LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool('Interdomain', 'RPC') -USE_DLT = True - class InterdomainServiceServicerImpl(InterdomainServiceServicer): def __init__(self, remote_domain_clients : RemoteDomainClients): LOGGER.debug('Creating Servicer...') @@ -48,7 +47,6 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): context_client = ContextClient() pathcomp_client = PathCompClient() slice_client = SliceClient() - dlt_connector_client = DltConnectorClient() local_device_uuids = get_local_device_uuids(context_client) slice_owner_uuid = request.slice_owner.owner_uuid.uuid @@ -87,6 +85,17 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): reply = Slice() reply.CopyFrom(request) + missing_env_vars = find_missing_environment_variables([ + get_env_var_name(ServiceNameEnum.DLT, ENVVAR_SUFIX_SERVICE_HOST ), + get_env_var_name(ServiceNameEnum.DLT, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ]) + if len(missing_env_vars) == 0: + # DLT available + dlt_connector_client = DltConnectorClient() + dlt_connector_client.connect() + else: + dlt_connector_client = None + dlt_record_sender = DltRecordSender(context_client, dlt_connector_client) for domain_uuid, is_local_domain, endpoint_ids in traversed_domains: @@ -119,7 +128,7 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): LOGGER.info('[loop] [remote] sub_slice={:s}'.format(grpc_message_to_json_string(sub_slice))) sub_slice_id = context_client.SetSlice(sub_slice) - if USE_DLT: + if dlt_connector_client is not None: topology_id = TopologyId(**json_topology_id(domain_uuid)) dlt_record_sender.add_slice(topology_id, sub_slice) else: @@ -137,8 +146,9 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): LOGGER.info('[loop] adding sub-slice') reply.slice_subslice_ids.add().CopyFrom(sub_slice_id) # pylint: disable=no-member - LOGGER.info('Recording Remote Slice requests to DLT') - dlt_record_sender.commit() + if dlt_connector_client is not None: + LOGGER.info('Recording Remote Slice requests to DLT') + dlt_record_sender.commit() LOGGER.info('Activating interdomain slice') reply.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_ACTIVE # pylint: disable=no-member diff --git a/src/interdomain/service/RemoteDomainClients.py b/src/interdomain/service/RemoteDomainClients.py index 297c9a60d0cc4c67fda7f746e5fead1837b9d4ee..e28176ef4fad2d3f2e2c6b1d7f0eb8d24116308a 100644 --- a/src/interdomain/service/RemoteDomainClients.py +++ b/src/interdomain/service/RemoteDomainClients.py @@ -12,44 +12,101 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, socket +import logging, threading +from typing import Optional, Tuple from common.Constants import DEFAULT_CONTEXT_NAME, ServiceNameEnum +from common.DeviceTypes import DeviceTypeEnum from common.Settings import get_service_host, get_service_port_grpc +from common.proto.context_pb2 import ConfigActionEnum, DeviceEvent from common.proto.context_pb2 import TeraFlowController +from common.tools.context_queries.Device import get_device +from common.tools.grpc.Tools import grpc_message_to_json_string +from context.client.ContextClient import ContextClient +from context.client.EventsCollector import EventsCollector from interdomain.client.InterdomainClient import InterdomainClient LOGGER = logging.getLogger(__name__) -class RemoteDomainClients: +def get_domain_data(context_client : ContextClient, event : DeviceEvent) -> Optional[Tuple[str, str, int]]: + device_uuid = event.device_id.device_uuid.uuid + device = get_device( + context_client, device_uuid, include_endpoints=False, + include_components=False, include_config_rules=True) + if device.device_type != DeviceTypeEnum.NETWORK.value: return None + idc_domain_name = device.name + idc_domain_address = None + idc_domain_port = None + for config_rule in device.device_config.config_rules: + if config_rule.action != ConfigActionEnum.CONFIGACTION_SET: continue + if config_rule.WhichOneof('config_rule') != 'custom': continue + if config_rule.custom.resource_key == '_connect/address': + idc_domain_address = config_rule.custom.resource_value + if config_rule.custom.resource_key == '_connect/port': + idc_domain_port = int(config_rule.custom.resource_value) + if idc_domain_address is None: return None + if idc_domain_port is None: return None + return idc_domain_name, idc_domain_address, idc_domain_port + +class RemoteDomainClients(threading.Thread): def __init__(self) -> None: - self.peer_domain = {} + super().__init__(daemon=True) + self.terminate = threading.Event() + self.lock = threading.Lock() + self.peer_domains = {} + self.context_client = ContextClient() + self.context_event_collector = EventsCollector(self.context_client) - def add_peer( - self, domain_name : str, host : str, port : int, context_uuid : str = DEFAULT_CONTEXT_NAME - ) -> None: - while True: + def stop(self): + self.terminate.set() + + def run(self) -> None: + self.context_client.connect() + self.context_event_collector.start() + + while not self.terminate.is_set(): + event = self.context_event_collector.get_event(timeout=0.1) + if event is None: continue + if not isinstance(event, DeviceEvent): continue + LOGGER.info('Processing Event({:s})...'.format(grpc_message_to_json_string(event))) + domain_data = get_domain_data(self.context_client, event) + domain_name, domain_address, domain_port = domain_data try: - remote_teraflow_ip = socket.gethostbyname(host) - if len(remote_teraflow_ip) > 0: break - except socket.gaierror as e: - if str(e) == '[Errno -2] Name or service not known': continue + self.add_peer(domain_name, domain_address, domain_port) + except: # pylint: disable=bare-except + MSG = 'Unable to connect to remote domain {:s} ({:s}:{:d})' + LOGGER.exception(MSG.format(domain_name, domain_address, domain_port)) - interdomain_client = InterdomainClient(host=host, port=port) + self.context_event_collector.stop() + self.context_client.close() + + def add_peer( + self, domain_name : str, domain_address : str, domain_port : int, context_uuid : str = DEFAULT_CONTEXT_NAME + ) -> None: request = TeraFlowController() - request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME # pylint: disable=no-member + request.context_id.context_uuid.uuid = context_uuid # pylint: disable=no-member request.ip_address = get_service_host(ServiceNameEnum.INTERDOMAIN) request.port = int(get_service_port_grpc(ServiceNameEnum.INTERDOMAIN)) + interdomain_client = InterdomainClient(host=domain_address, port=domain_port) + interdomain_client.connect() + reply = interdomain_client.Authenticate(request) + if not reply.authenticated: - msg = 'Authentication against {:s}:{:d} rejected' - raise Exception(msg.format(str(remote_teraflow_ip), port)) + MSG = 'Authentication against {:s}:{:d} with Context({:s}) rejected' + # pylint: disable=broad-exception-raised + raise Exception(MSG.format(domain_address, domain_port, domain_name)) - self.peer_domain[domain_name] = interdomain_client + with self.lock: + self.peer_domains[domain_name] = interdomain_client + LOGGER.info('Added peer domain {:s} ({:s}:{:d})'.format(domain_name, domain_address, domain_port)) def get_peer(self, domain_name : str) -> InterdomainClient: - LOGGER.warning('peers: {:s}'.format(str(self.peer_domain))) - return self.peer_domain.get(domain_name) + with self.lock: + LOGGER.warning('peers: {:s}'.format(str(self.peer_domains))) + return self.peer_domains.get(domain_name) def remove_peer(self, domain_name : str) -> None: - return self.peer_domain.pop(domain_name, None) + with self.lock: + self.peer_domains.pop(domain_name, None) + LOGGER.info('Removed peer domain {:s}'.format(domain_name)) diff --git a/src/interdomain/service/__main__.py b/src/interdomain/service/__main__.py index f4bdbb7b80ca3f355a92268e74d28e02f7883302..f867dc378020f3ef2ca8fb43b3beed538a1ebb9c 100644 --- a/src/interdomain/service/__main__.py +++ b/src/interdomain/service/__main__.py @@ -43,8 +43,6 @@ def main(): get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC), get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_HOST ), get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC), - get_env_var_name(ServiceNameEnum.DLT, ENVVAR_SUFIX_SERVICE_HOST ), - get_env_var_name(ServiceNameEnum.DLT, ENVVAR_SUFIX_SERVICE_PORT_GRPC), ]) signal.signal(signal.SIGINT, signal_handler) @@ -58,6 +56,7 @@ def main(): # Define remote domain clients remote_domain_clients = RemoteDomainClients() + remote_domain_clients.start() # Starting Interdomain service grpc_service = InterdomainService(remote_domain_clients) @@ -67,16 +66,13 @@ def main(): topology_abstractor = TopologyAbstractor() topology_abstractor.start() - # TODO: improve with configuration the definition of the remote peers - #interdomain_service_port_grpc = get_service_port_grpc(ServiceNameEnum.INTERDOMAIN) - #remote_domain_clients.add_peer('remote-teraflow', 'remote-teraflow', interdomain_service_port_grpc) - # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') topology_abstractor.stop() grpc_service.stop() + remote_domain_clients.stop() LOGGER.info('Bye') return 0 diff --git a/src/interdomain/service/_old_code/add_peer_manually.txt b/src/interdomain/service/_old_code/add_peer_manually.txt new file mode 100644 index 0000000000000000000000000000000000000000..6582044b3dcef3ab81cc7b85655dce85c505aacd --- /dev/null +++ b/src/interdomain/service/_old_code/add_peer_manually.txt @@ -0,0 +1,3 @@ +# TODO: improve with configuration the definition of the remote peers +#interdomain_service_port_grpc = get_service_port_grpc(ServiceNameEnum.INTERDOMAIN) +#remote_domain_clients.add_peer('remote-teraflow', 'remote-teraflow', interdomain_service_port_grpc) diff --git a/src/interdomain/service/topology_abstractor/DltRecordSender.py b/src/interdomain/service/topology_abstractor/DltRecordSender.py index d6efbc809ef848067d7ee496dca300ab8a04f406..c9a61ef6956acf461124a50e146a2d104ff2e131 100644 --- a/src/interdomain/service/topology_abstractor/DltRecordSender.py +++ b/src/interdomain/service/topology_abstractor/DltRecordSender.py @@ -13,7 +13,7 @@ # limitations under the License. import logging -from typing import Dict, List, Tuple +from typing import Dict, List, Optional, Tuple from common.proto.context_pb2 import Device, Link, Service, Slice, TopologyId from common.proto.dlt_connector_pb2 import DltDeviceId, DltLinkId, DltServiceId, DltSliceId from context.client.ContextClient import ContextClient @@ -23,7 +23,7 @@ from .Types import DltRecordTypes LOGGER = logging.getLogger(__name__) class DltRecordSender: - def __init__(self, context_client : ContextClient, dlt_connector_client : DltConnectorClient) -> None: + def __init__(self, context_client : ContextClient, dlt_connector_client : Optional[DltConnectorClient]) -> None: self.context_client = context_client self.dlt_connector_client = dlt_connector_client self.dlt_record_uuids : List[str] = list() @@ -65,24 +65,28 @@ class DltRecordSender: topology_id,dlt_record = self.dlt_record_uuid_to_data[dlt_record_uuid] if isinstance(dlt_record, Device): device_id = self.context_client.SetDevice(dlt_record) + if self.dlt_connector_client is None: continue dlt_device_id = DltDeviceId() dlt_device_id.topology_id.CopyFrom(topology_id) # pylint: disable=no-member dlt_device_id.device_id.CopyFrom(device_id) # pylint: disable=no-member self.dlt_connector_client.RecordDevice(dlt_device_id) elif isinstance(dlt_record, Link): link_id = self.context_client.SetLink(dlt_record) + if self.dlt_connector_client is None: continue dlt_link_id = DltLinkId() dlt_link_id.topology_id.CopyFrom(topology_id) # pylint: disable=no-member dlt_link_id.link_id.CopyFrom(link_id) # pylint: disable=no-member self.dlt_connector_client.RecordLink(dlt_link_id) elif isinstance(dlt_record, Service): service_id = self.context_client.SetService(dlt_record) + if self.dlt_connector_client is None: continue dlt_service_id = DltServiceId() dlt_service_id.topology_id.CopyFrom(topology_id) # pylint: disable=no-member dlt_service_id.service_id.CopyFrom(service_id) # pylint: disable=no-member self.dlt_connector_client.RecordService(dlt_service_id) elif isinstance(dlt_record, Slice): slice_id = self.context_client.SetSlice(dlt_record) + if self.dlt_connector_client is None: continue dlt_slice_id = DltSliceId() dlt_slice_id.topology_id.CopyFrom(topology_id) # pylint: disable=no-member dlt_slice_id.slice_id.CopyFrom(slice_id) # pylint: disable=no-member diff --git a/src/interdomain/service/topology_abstractor/TopologyAbstractor.py b/src/interdomain/service/topology_abstractor/TopologyAbstractor.py index bdbf016f85a0c58969b7a58677f9695e2635c8c0..20b186f307fb583734f8d0e96cea2a26e24e5590 100644 --- a/src/interdomain/service/topology_abstractor/TopologyAbstractor.py +++ b/src/interdomain/service/topology_abstractor/TopologyAbstractor.py @@ -14,8 +14,9 @@ import logging, threading from typing import Dict, Optional, Tuple -from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME, ServiceNameEnum from common.DeviceTypes import DeviceTypeEnum +from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, find_missing_environment_variables, get_env_var_name from common.proto.context_pb2 import ( ContextEvent, ContextId, Device, DeviceEvent, DeviceId, EndPoint, EndPointId, Link, LinkEvent, TopologyId, TopologyEvent) @@ -48,7 +49,6 @@ class TopologyAbstractor(threading.Thread): self.terminate = threading.Event() self.context_client = ContextClient() - self.dlt_connector_client = DltConnectorClient() self.context_event_collector = EventsCollector(self.context_client) self.real_to_abstract_device_uuid : Dict[str, str] = dict() @@ -69,7 +69,6 @@ class TopologyAbstractor(threading.Thread): topology_uuids = [DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME] create_missing_topologies(self.context_client, ADMIN_CONTEXT_ID, topology_uuids) - self.dlt_connector_client.connect() self.context_event_collector.start() while not self.terminate.is_set(): @@ -81,7 +80,6 @@ class TopologyAbstractor(threading.Thread): self.context_event_collector.stop() self.context_client.close() - self.dlt_connector_client.close() #def ignore_event(self, event : EventTypes) -> List[DltRecordIdTypes]: # # TODO: filter events resulting from abstraction computation @@ -226,7 +224,18 @@ class TopologyAbstractor(threading.Thread): if changed: dlt_record_sender.add_link(INTERDOMAIN_TOPOLOGY_ID, abstract_link.link) def update_abstraction(self, event : EventTypes) -> None: - dlt_record_sender = DltRecordSender(self.context_client, self.dlt_connector_client) + missing_env_vars = find_missing_environment_variables([ + get_env_var_name(ServiceNameEnum.DLT, ENVVAR_SUFIX_SERVICE_HOST ), + get_env_var_name(ServiceNameEnum.DLT, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ]) + if len(missing_env_vars) == 0: + # DLT available + dlt_connector_client = DltConnectorClient() + dlt_connector_client.connect() + else: + dlt_connector_client = None + + dlt_record_sender = DltRecordSender(self.context_client, dlt_connector_client) if isinstance(event, ContextEvent): LOGGER.warning('Ignoring Event({:s})'.format(grpc_message_to_json_string(event))) @@ -286,3 +295,4 @@ class TopologyAbstractor(threading.Thread): LOGGER.warning('Unsupported Event({:s})'.format(grpc_message_to_json_string(event))) dlt_record_sender.commit() + dlt_connector_client.close() diff --git a/src/l3_attackmitigator/Config.py b/src/l3_attackmitigator/Config.py index fafeb8d11d1ec5e5dd2da16c699161ea03f4995d..48b6dbab894e2081066bb12d883e826df34e81ca 100644 --- a/src/l3_attackmitigator/Config.py +++ b/src/l3_attackmitigator/Config.py @@ -18,7 +18,7 @@ import logging LOG_LEVEL = logging.WARNING # gRPC settings -GRPC_SERVICE_PORT = 10002 # TODO UPM FIXME +GRPC_SERVICE_PORT = 10002 GRPC_MAX_WORKERS = 10 GRPC_GRACE_PERIOD = 60 diff --git a/src/l3_attackmitigator/Dockerfile b/src/l3_attackmitigator/Dockerfile index da9ed75ad4f627b5f5f54d21c2f1a8544a600e03..99b7e7a9435ca4172e4ec38f8f8d13c20ebdce57 100644 --- a/src/l3_attackmitigator/Dockerfile +++ b/src/l3_attackmitigator/Dockerfile @@ -63,6 +63,9 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow COPY src/l3_attackmitigator/. l3_attackmitigator +COPY src/monitoring/. monitoring +COPY src/context/. context/ +COPY src/service/. service/ # Start the service ENTRYPOINT ["python", "-m", "l3_attackmitigator.service"] diff --git a/src/l3_attackmitigator/client/l3_attackmitigatorClient.py b/src/l3_attackmitigator/client/l3_attackmitigatorClient.py index fad553cc25ce655ed6ba6435b6511cf440774950..c5d98b1c4974172e50e65db16ba4753e742eab28 100644 --- a/src/l3_attackmitigator/client/l3_attackmitigatorClient.py +++ b/src/l3_attackmitigator/client/l3_attackmitigatorClient.py @@ -13,13 +13,18 @@ # 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.tools.client.RetryDecorator import retry, delay_exponential from common.proto.l3_attackmitigator_pb2_grpc import ( L3AttackmitigatorStub, ) from common.proto.l3_attackmitigator_pb2 import ( - Output, - EmptyMitigator + L3AttackmitigatorOutput, ACLRules +) + +from common.proto.context_pb2 import ( + Empty ) LOGGER = logging.getLogger(__name__) @@ -28,8 +33,10 @@ 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 l3_attackmitigatorClient: - def __init__(self, address, port): - self.endpoint = "{}:{}".format(address, port) + def __init__(self, host=None, port=None): + if not host: host = get_service_host(ServiceNameEnum.L3_AM) + if not port: port = get_service_port_grpc(ServiceNameEnum.L3_AM) + self.endpoint = "{}:{}".format(host, port) LOGGER.debug("Creating channel to {}...".format(self.endpoint)) self.channel = None self.stub = None @@ -47,16 +54,23 @@ class l3_attackmitigatorClient: self.stub = None @RETRY_DECORATOR - def SendOutput(self, request: Output) -> EmptyMitigator: - LOGGER.debug('SendOutput request: {}'.format(request)) - response = self.stub.SendOutput(request) - LOGGER.debug('SendOutput result: {}'.format(response)) + def PerformMitigation(self, request: L3AttackmitigatorOutput) -> Empty: + LOGGER.debug('PerformMitigation request: {}'.format(request)) + response = self.stub.PerformMitigation(request) + LOGGER.debug('PerformMitigation result: {}'.format(response)) return response - + @RETRY_DECORATOR - def GetMitigation(self, request: EmptyMitigator) -> EmptyMitigator: + def GetMitigation(self, request: Empty) -> Empty: LOGGER.debug('GetMitigation request: {}'.format(request)) response = self.stub.GetMitigation(request) LOGGER.debug('GetMitigation result: {}'.format(response)) return response + + @RETRY_DECORATOR + def GetConfiguredACLRules(self, request: Empty) -> ACLRules: + LOGGER.debug('GetConfiguredACLRules request: {}'.format(request)) + response = self.stub.GetConfiguredACLRules(request) + LOGGER.debug('GetConfiguredACLRules result: {}'.format(response)) + return response diff --git a/src/l3_attackmitigator/service/__main__.py b/src/l3_attackmitigator/service/__main__.py index 1e91d5e9729f027b096afa97d1808795193dc2fa..aadccbdab47a2bc6fce860ffe762018bec78be31 100644 --- a/src/l3_attackmitigator/service/__main__.py +++ b/src/l3_attackmitigator/service/__main__.py @@ -52,7 +52,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass logger.info('Terminating...') grpc_service.stop() diff --git a/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py b/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py index b697a83ff43c28a9051fb6465db3803ca1c068d8..34cfcd5d081a431f165461564eeb5a3390a3bda5 100644 --- a/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py +++ b/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py @@ -14,41 +14,184 @@ from __future__ import print_function import logging -from common.proto.l3_attackmitigator_pb2 import ( - EmptyMitigator -) -from common.proto.l3_attackmitigator_pb2_grpc import ( - L3AttackmitigatorServicer, +import time + +from common.proto.l3_centralizedattackdetector_pb2 import Empty +from common.proto.l3_attackmitigator_pb2_grpc import L3AttackmitigatorServicer +from common.proto.l3_attackmitigator_pb2 import ACLRules +from common.proto.context_pb2 import ( + ServiceId, + ConfigActionEnum, ) +from common.proto.acl_pb2 import AclForwardActionEnum, AclLogActionEnum, AclRuleTypeEnum +from common.proto.context_pb2 import ConfigActionEnum, Service, ServiceId, ConfigRule +from common.tools.grpc.Tools import grpc_message_to_json_string +from context.client.ContextClient import ContextClient +from service.client.ServiceClient import ServiceClient + +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method + LOGGER = logging.getLogger(__name__) -class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer): +METRICS_POOL = MetricsPool('l3_attackmitigator', 'RPC') + +class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer): def __init__(self): - LOGGER.debug("Creating Servicer...") + LOGGER.info("Creating Attack Mitigator Service") + self.last_value = -1 self.last_tag = 0 - - def SendOutput(self, request, context): - # SEND CONFIDENCE TO MITIGATION SERVER - logging.debug("") - print("Server received mitigation values...", request.confidence) + self.sequence_id = 0 + + self.context_client = ContextClient() + self.service_client = ServiceClient() + self.configured_acl_config_rules = [] + + def configure_acl_rule( + self, + context_uuid: str, + service_uuid: str, + device_uuid: str, + endpoint_uuid: str, + src_ip: str, + dst_ip: str, + src_port: str, + dst_port: str, + ) -> None: + # Create ServiceId + service_id = ServiceId() + service_id.context_id.context_uuid.uuid = context_uuid + service_id.service_uuid.uuid = service_uuid + + # Get service form Context + # context_client = ContextClient() + + try: + _service: Service = self.context_client.GetService(service_id) + except: + raise Exception("Service({:s}) not found".format(grpc_message_to_json_string(service_id))) + + # _service is read-only; copy it to have an updatable service message + service_request = Service() + service_request.CopyFrom(_service) + + # Add ACL ConfigRule into the service service_request + acl_config_rule = service_request.service_config.config_rules.add() + acl_config_rule.action = ConfigActionEnum.CONFIGACTION_SET + + # Set EndpointId associated to the ACLRuleSet + acl_endpoint_id = acl_config_rule.acl.endpoint_id + acl_endpoint_id.device_id.device_uuid.uuid = device_uuid + acl_endpoint_id.endpoint_uuid.uuid = endpoint_uuid + + # Set RuleSet for this ACL ConfigRule + acl_rule_set = acl_config_rule.acl.rule_set + # TODO: update the following parameters; for instance, add them as parameters of the method configure_acl_rule + # acl_rule_set.name = "DROP-HTTPS" + acl_rule_set.name = "DROP-TCP" + acl_rule_set.type = AclRuleTypeEnum.ACLRULETYPE_IPV4 + # acl_rule_set.description = "DROP undesired HTTPS traffic" + acl_rule_set.description = "DROP undesired TCP traffic" + + # Add ACLEntry to the ACLRuleSet + acl_entry = acl_rule_set.entries.add() + acl_entry.sequence_id = self.sequence_id + acl_entry.description = "DROP-{src_ip}:{src_port}-{dst_ip}:{dst_port}".format( + src_ip=src_ip, src_port=src_port, dst_ip=dst_ip, dst_port=dst_port + ) + acl_entry.match.protocol = ( + 6 # TCP according to https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + ) + acl_entry.match.src_address = "{}/32".format(src_ip) + acl_entry.match.dst_address = "{}/32".format(dst_ip) + acl_entry.match.src_port = int(src_port) + acl_entry.match.dst_port = int(dst_port) + # TODO: update the following parameters; for instance, add them as parameters of the method configure_acl_rule + acl_entry.action.forward_action = AclForwardActionEnum.ACLFORWARDINGACTION_DROP + acl_entry.action.log_action = AclLogActionEnum.ACLLOGACTION_NOLOG + + LOGGER.info("ACL Rule Set: %s", acl_rule_set) + LOGGER.info("ACL Config Rule: %s", acl_config_rule) + + # Add the ACLRuleSet to the list of configured ACLRuleSets + self.configured_acl_config_rules.append(acl_config_rule) + + # Update the Service with the new ACL RuleSet + # service_client = ServiceClient() + service_reply: ServiceId = self.service_client.UpdateService(service_request) + + # TODO: Log the service_reply details + + if service_reply != service_request.service_id: # pylint: disable=no-member + raise Exception("Service update failed. Wrong ServiceId was returned") + + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def PerformMitigation(self, request, context): last_value = request.confidence last_tag = request.tag - # RETURN OK TO THE CALLER - return EmptyMitigator( - message=f"OK, received values: {last_tag} with confidence {last_value}." + + LOGGER.info( + "Attack Mitigator received attack mitigation information. Prediction confidence: %s, Predicted class: %s", + last_value, + last_tag, ) - def GetMitigation(self, request, context): - # GET OR PERFORM MITIGATION STRATEGY - logging.debug("") - print("Returing mitigation strategy...") - k = self.last_value * 2 - return EmptyMitigator( - message=f"Mitigation with double confidence = {k}" + ip_o = request.ip_o + ip_d = request.ip_d + port_o = request.port_o + port_d = request.port_d + + sentinel = True + counter = 0 + service_id = request.service_id + + LOGGER.info("Service Id.:\n{}".format(service_id)) + + LOGGER.info("Retrieving service from Context") + while sentinel: + try: + service = self.context_client.GetService(service_id) + sentinel = False + except Exception as e: + counter = counter + 1 + LOGGER.debug("Waiting 2 seconds", counter, e) + time.sleep(2) + + LOGGER.info(f"Service with Service Id.: {service_id}\n{service}") + + LOGGER.info("Adding new rule to the service to block the attack") + self.configure_acl_rule( + context_uuid=service_id.context_id.context_uuid.uuid, + service_uuid=service_id.service_uuid.uuid, + device_uuid=request.endpoint_id.device_id.device_uuid.uuid, + endpoint_uuid=request.endpoint_id.endpoint_uuid.uuid, + src_ip=ip_o, + dst_ip=ip_d, + src_port=port_o, + dst_port=port_d, ) + LOGGER.info("Service with new rule:\n{}".format(service)) + + LOGGER.info("Updating service with the new rule") + self.service_client.UpdateService(service) + + LOGGER.info( + "Service obtained from Context after updating with the new rule:\n{}".format( + self.context_client.GetService(service_id) + ) + ) + + return Empty(message=f"OK, received values: {last_tag} with confidence {last_value}.") + + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetConfiguredACLRules(self, request, context): + acl_rules = ACLRules() + for acl_config_rule in self.configured_acl_config_rules: + acl_rules.acl_rules.append(acl_config_rule) - + return acl_rules diff --git a/src/l3_attackmitigator/service/test_create_service.py b/src/l3_attackmitigator/service/test_create_service.py new file mode 100644 index 0000000000000000000000000000000000000000..01cf769a271de1bbbd0329a3ce21ea476ac10cab --- /dev/null +++ b/src/l3_attackmitigator/service/test_create_service.py @@ -0,0 +1,267 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 __future__ import print_function +import logging +from common.proto.l3_centralizedattackdetector_pb2 import ( + Empty +) +from common.proto.l3_attackmitigator_pb2_grpc import ( + L3AttackmitigatorServicer, +) +from common.proto.context_pb2 import ( + Service, ServiceId, ServiceConfig, ServiceTypeEnum, ServiceStatusEnum, ServiceStatus, Context, ContextId, Uuid, + Timestamp, ConfigRule, ConfigRule_Custom, ConfigActionEnum, Device, DeviceId, DeviceConfig, + DeviceOperationalStatusEnum, DeviceDriverEnum, EndPoint, Link, LinkId, EndPoint, EndPointId, Topology, TopologyId +) +from common.proto.context_pb2_grpc import ( + ContextServiceStub +) +from common.proto.service_pb2_grpc import ( + ServiceServiceStub +) +from datetime import datetime +import grpc + +LOGGER = logging.getLogger(__name__) +CONTEXT_CHANNEL = "192.168.165.78:1010" +SERVICE_CHANNEL = "192.168.165.78:3030" + +class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer): + + def GetNewService(self, service_id): + service = Service() + service_id_obj = self.GenerateServiceId(service_id) + service.service_id.CopyFrom(service_id_obj) + service.service_type = ServiceTypeEnum.SERVICETYPE_L3NM + service_status = ServiceStatus() + service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE + service.service_status.CopyFrom(service_status) + timestamp = Timestamp() + timestamp.timestamp = datetime.timestamp(datetime.now()) + service.timestamp.CopyFrom(timestamp) + return service + + def GetNewContext(self, service_id): + context = Context() + context_id = ContextId() + uuid = Uuid() + uuid.uuid = service_id + context_id.context_uuid.CopyFrom(uuid) + context.context_id.CopyFrom(context_id) + return context + + def GetNewDevice(self, service_id): + device = Device() + device_id = DeviceId() + uuid = Uuid() + uuid.uuid = service_id + device_id.device_uuid.CopyFrom(uuid) + device.device_type="test" + device.device_id.CopyFrom(device_id) + device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + return device + + def GetNewLink(self, service_id): + link = Link() + link_id = LinkId() + uuid = Uuid() + uuid.uuid = service_id + link_id.link_uuid.CopyFrom(uuid) + link.link_id.CopyFrom(link_id) + return link + + def GetNewTopology(self,context_id, device_id, link_id): + topology = Topology() + topology_id = TopologyId() + topology_id.context_id.CopyFrom(context_id) + uuid = Uuid() + uuid.uuid = "test_crypto" + topology_id.topology_uuid.CopyFrom(uuid) + topology.topology_id.CopyFrom(topology_id) + topology.device_ids.extend([device_id]) + topology.link_ids.extend([link_id]) + return topology + + def GetNewEndpoint(self, topology_id, device_id, uuid_name): + endpoint = EndPoint() + endpoint_id = EndPointId() + endpoint_id.topology_id.CopyFrom(topology_id) + endpoint_id.device_id.CopyFrom(device_id) + uuid = Uuid() + uuid.uuid = uuid_name + endpoint_id.endpoint_uuid.CopyFrom(uuid) + endpoint.endpoint_id.CopyFrom(endpoint_id) + endpoint.endpoint_type = "test" + return endpoint + + + def __init__(self): + LOGGER.debug("Creating Servicer...") + self.last_value = -1 + self.last_tag = 0 + """ + context = self.GetNewContext("test_crypto") + print(context, flush=True) + print(self.SetContext(context)) + + service = self.GetNewService("test_crypto") + print("This is the new service", self.CreateService(service), flush = True) + + ip_o = "127.0.0.1" + ip_d = "127.0.0.2" + port_o = "123" + port_d = "124" + + service_id = self.GenerateServiceId("test_crypto") + + config_rule = self.GetConfigRule(ip_o, ip_d, port_o, port_d) + + service = self.GetService(service_id) + print("Service obtained from id", service, flush=True) + + config_rule = self.GetConfigRule(ip_o, ip_d, port_o, port_d) + + #service_config = service.service_config + #service_config.append(config_rule) + + service_config = ServiceConfig() + service_config.config_rules.extend([config_rule]) + service.service_config.CopyFrom(service_config) + + device = self.GetNewDevice("test_crypto") + print("New device", device, flush=True) + device_id = self.SetDevice(device) + + link = self.GetNewLink("test_crypto") + print("New link", link, flush=True) + link_id = self.SetLink(link) + + topology = self.GetNewTopology(context.context_id, device.device_id, link.link_id) + print("New topology", topology, flush=True) + topology_id = self.SetTopology(topology) + + endpoint = self.GetNewEndpoint(topology.topology_id, device.device_id, "test_crypto") + print("New endpoint", endpoint, flush=True) + link.link_endpoint_ids.extend([endpoint.endpoint_id]) + + self.SetLink(link) + + print("Service with new rule", service, flush=True) + self.UpdateService(service) + + service2 = self.GetService(service_id) + print("Service obtained from id after updating", service2, flush=True) + """ + + def GenerateRuleValue(self, ip_o, ip_d, port_o, port_d): + value = { + 'ipv4:source-address': ip_o, + 'ipv4:destination-address': ip_d, + 'transport:source-port': port_o, + 'transport:destination-port': port_d, + 'forwarding-action': 'DROP', + } + return value + + def GetConfigRule(self, ip_o, ip_d, port_o, port_d): + config_rule = ConfigRule() + config_rule_custom = ConfigRule_Custom() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule_custom.resource_key = 'test' + config_rule_custom.resource_value = str(self.GenerateRuleValue(ip_o, ip_d, port_o, port_d)) + config_rule.custom.CopyFrom(config_rule_custom) + return config_rule + + def GenerateServiceId(self, service_id): + service_id_obj = ServiceId() + context_id = ContextId() + uuid = Uuid() + uuid.uuid = service_id + context_id.context_uuid.CopyFrom(uuid) + service_id_obj.context_id.CopyFrom(context_id) + service_id_obj.service_uuid.CopyFrom(uuid) + return service_id_obj + + def SendOutput(self, request, context): + # SEND CONFIDENCE TO MITIGATION SERVER + print("Server received mitigation values...", request.confidence, flush=True) + + last_value = request.confidence + last_tag = request.tag + + ip_o = request.ip_o + ip_d = request.ip_d + port_o = request.port_o + port_d = request.port_d + + service_id = self.GenerateServiceId(request.service_id) + + config_rule = self.GetConfigRule(ip_o, ip_d, port_o, port_d) + + service = GetService(service_id) + print(service) + #service.config_rules.append(config_rule) + #UpdateService(service) + + # RETURN OK TO THE CALLER + return Empty( + message=f"OK, received values: {last_tag} with confidence {last_value}." + ) + + def SetDevice(self, device): + with grpc.insecure_channel(CONTEXT_CHANNEL) as channel: + stub = ContextServiceStub(channel) + return stub.SetDevice(device) + + def SetLink(self, link): + with grpc.insecure_channel(CONTEXT_CHANNEL) as channel: + stub = ContextServiceStub(channel) + return stub.SetLink(link) + + def SetTopology(self, link): + with grpc.insecure_channel(CONTEXT_CHANNEL) as channel: + stub = ContextServiceStub(channel) + return stub.SetTopology(link) + + + def GetService(self, service_id): + with grpc.insecure_channel(CONTEXT_CHANNEL) as channel: + stub = ContextServiceStub(channel) + return stub.GetService(service_id) + + def SetContext(self, context): + with grpc.insecure_channel(CONTEXT_CHANNEL) as channel: + stub = ContextServiceStub(channel) + return stub.SetContext(context) + + def UpdateService(self, service): + with grpc.insecure_channel(SERVICE_CHANNEL) as channel: + stub = ServiceServiceStub(channel) + stub.UpdateService(service) + + def CreateService(self, service): + with grpc.insecure_channel(SERVICE_CHANNEL) as channel: + stub = ServiceServiceStub(channel) + stub.CreateService(service) + + def GetMitigation(self, request, context): + # GET OR PERFORM MITIGATION STRATEGY + logging.debug("") + print("Returing mitigation strategy...") + k = self.last_value * 2 + return Empty( + message=f"Mitigation with double confidence = {k}" + ) + diff --git a/src/l3_centralizedattackdetector/.gitlab-ci.yml b/src/l3_centralizedattackdetector/.gitlab-ci.yml index 791b917524fa3ad2fa91e0bc4f928fcb60851341..057545eb1b65aac26610c6460a47592b4e7604c2 100644 --- a/src/l3_centralizedattackdetector/.gitlab-ci.yml +++ b/src/l3_centralizedattackdetector/.gitlab-ci.yml @@ -52,7 +52,7 @@ unit test l3_centralizedattackdetector: - 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 10001:10001 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG + - docker run --name $IMAGE_NAME -d -p 10001:10001 --env CAD_CLASSIFICATION_THRESHOLD=0.5 -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 diff --git a/src/l3_centralizedattackdetector/Dockerfile b/src/l3_centralizedattackdetector/Dockerfile index e5b9aa33b78b2593dc1df6d48edaf8c41b65a02b..377ecd21b0ad553512797ce7a31f1ce520462a13 100644 --- a/src/l3_centralizedattackdetector/Dockerfile +++ b/src/l3_centralizedattackdetector/Dockerfile @@ -44,6 +44,10 @@ WORKDIR /var/teraflow/common COPY src/common/. ./ RUN rm -rf proto +RUN mkdir -p /var/teraflow/l3_attackmitigator +WORKDIR /var/teraflow/l3_attackmitigator +COPY src/l3_attackmitigator/. ./ + # Create proto sub-folder, copy .proto files, and generate Python code RUN mkdir -p /var/teraflow/common/proto WORKDIR /var/teraflow/common/proto @@ -63,6 +67,7 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow COPY src/l3_centralizedattackdetector/. l3_centralizedattackdetector +COPY src/monitoring/. monitoring # Start the service ENTRYPOINT ["python", "-m", "l3_centralizedattackdetector.service"] diff --git a/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py b/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py index f84bd84217c30e25c6e8ccfbb9b9e48c073a5ee5..2ef33438e77dbe4c3609bd21133fb3a9c95c8bcc 100644 --- a/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py +++ b/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py @@ -18,7 +18,10 @@ from common.proto.l3_centralizedattackdetector_pb2_grpc import ( L3CentralizedattackdetectorStub, ) from common.proto.l3_centralizedattackdetector_pb2 import ( + AutoFeatures, Empty, + L3CentralizedattackdetectorBatchInput, + L3CentralizedattackdetectorMetrics, ModelInput, ModelOutput ) @@ -48,17 +51,24 @@ class l3_centralizedattackdetectorClient: self.stub = None @RETRY_DECORATOR - def SendInput(self, request: ModelInput) -> Empty: - LOGGER.debug('SendInput request: {}'.format(request)) - response = self.stub.SendInput(request) - LOGGER.debug('SendInput result: {}'.format(response)) + def AnalyzeConnectionStatistics(self, request: L3CentralizedattackdetectorMetrics) -> Empty: + LOGGER.debug('AnalyzeConnectionStatistics request: {}'.format(request)) + response = self.stub.AnalyzeConnectionStatistics(request) + LOGGER.debug('AnalyzeConnectionStatistics result: {}'.format(response)) return response @RETRY_DECORATOR - def GetOutput(self, request: Empty) -> ModelOutput: - LOGGER.debug('GetOutput request: {}'.format(request)) + def AnalyzeBatchConnectionStatistics(self, request: L3CentralizedattackdetectorBatchInput) -> Empty: + LOGGER.debug('AnalyzeBatchConnectionStatistics request: {}'.format(request)) response = self.stub.GetOutput(request) - LOGGER.debug('GetOutput result: {}'.format(response)) + LOGGER.debug('AnalyzeBatchConnectionStatistics result: {}'.format(response)) + return response + + @RETRY_DECORATOR + def GetFeaturesIds(self, request: Empty) -> AutoFeatures: + LOGGER.debug('GetFeaturesIds request: {}'.format(request)) + response = self.stub.GetOutput(request) + LOGGER.debug('GetFeaturesIds result: {}'.format(response)) return response diff --git a/src/l3_centralizedattackdetector/service/__main__.py b/src/l3_centralizedattackdetector/service/__main__.py index 3408127242a01c110263d14947d63e64cfaa79a2..5b8873afd6d67e586ce727eaafdf51f1c0002814 100644 --- a/src/l3_centralizedattackdetector/service/__main__.py +++ b/src/l3_centralizedattackdetector/service/__main__.py @@ -53,7 +53,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass logger.info('Terminating...') grpc_service.stop() diff --git a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py index bf58247d3c6467b6f9b3ca7d0dcbc9c5239195c4..857f0e448725399caa82b3fdd331ff9ceff623a8 100644 --- a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py +++ b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py @@ -85,7 +85,6 @@ class l3_centralizedattackdetectorService: ) # pylint: disable=maybe-no-member LOGGER.debug("Service started") - #self.l3_centralizedattackdetector_servicer.setup_l3_centralizedattackdetector() def stop(self): LOGGER.debug( diff --git a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py index dfe67813f875cbbc3173460efed73b212ba0ee0f..8f59c81150345f15faaf69824d1036b87f5bd80d 100644 --- a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py +++ b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py @@ -14,118 +14,763 @@ from __future__ import print_function from datetime import datetime +from datetime import timedelta + import os -import grpc import numpy as np import onnxruntime as rt import logging -from common.proto.l3_centralizedattackdetector_pb2 import ( - Empty, -) -from common.proto.l3_centralizedattackdetector_pb2_grpc import ( - L3CentralizedattackdetectorServicer, -) - -from common.proto.l3_attackmitigator_pb2 import ( - L3AttackmitigatorOutput, -) -from common.proto.l3_attackmitigator_pb2_grpc import ( - L3AttackmitigatorStub, -) +import time + +from common.proto.l3_centralizedattackdetector_pb2 import Empty, AutoFeatures +from common.proto.l3_centralizedattackdetector_pb2_grpc import L3CentralizedattackdetectorServicer + +from common.proto.l3_attackmitigator_pb2 import L3AttackmitigatorOutput + +from common.proto.monitoring_pb2 import KpiDescriptor +from common.proto.kpi_sample_types_pb2 import KpiSampleType + +from monitoring.client.MonitoringClient import MonitoringClient +from common.proto.monitoring_pb2 import Kpi + +from common.tools.timestamp.Converters import timestamp_utcnow_to_float +from common.proto.context_pb2 import Timestamp, SliceId, ConnectionId + +from l3_attackmitigator.client.l3_attackmitigatorClient import l3_attackmitigatorClient + +import uuid + +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method + LOGGER = logging.getLogger(__name__) -here = os.path.dirname(os.path.abspath(__file__)) -MODEL_FILE = os.path.join(here, "ml_model/teraflow_rf.onnx") +current_dir = os.path.dirname(os.path.abspath(__file__)) + +# Demo constants +DEMO_MODE = False +ATTACK_IPS = ["37.187.95.110", "91.121.140.167", "94.23.23.52", "94.23.247.226", "149.202.83.171"] + +BATCH_SIZE= 10 + +METRICS_POOL = MetricsPool('l3_centralizedattackdetector', 'RPC') + + +class ConnectionInfo: + def __init__(self, ip_o, port_o, ip_d, port_d): + self.ip_o = ip_o + self.port_o = port_o + self.ip_d = ip_d + self.port_d = port_d + + def __eq__(self, other): + return ( + self.ip_o == other.ip_o + and self.port_o == other.port_o + and self.ip_d == other.ip_d + and self.port_d == other.port_d + ) + + def __str__(self): + return "ip_o: " + self.ip_o + "\nport_o: " + self.port_o + "\nip_d: " + self.ip_d + "\nport_d: " + self.port_d + class l3_centralizedattackdetectorServiceServicerImpl(L3CentralizedattackdetectorServicer): + """ + Initialize variables, prediction model and clients of components used by CAD + """ + def __init__(self): - LOGGER.debug("Creating Servicer...") + LOGGER.info("Creating Centralized Attack Detector Service") + self.inference_values = [] - self.model = rt.InferenceSession(MODEL_FILE) - self.input_name = self.model.get_inputs()[0].name - self.label_name = self.model.get_outputs()[0].name - self.prob_name = self.model.get_outputs()[1].name + self.inference_results = [] + self.cryptomining_detector_path = os.path.join(current_dir, "ml_model/cryptomining_detector/") + self.cryptomining_detector_file_name = os.listdir(self.cryptomining_detector_path)[0] + self.cryptomining_detector_model_path = os.path.join( + self.cryptomining_detector_path, self.cryptomining_detector_file_name + ) + self.cryptomining_detector_model = rt.InferenceSession(self.cryptomining_detector_model_path) + + # Load cryptomining detector features metadata from ONNX file + self.cryptomining_detector_features_metadata = list( + self.cryptomining_detector_model.get_modelmeta().custom_metadata_map.values() + ) + self.cryptomining_detector_features_metadata = [float(x) for x in self.cryptomining_detector_features_metadata] + self.cryptomining_detector_features_metadata.sort() + LOGGER.info("Cryptomining Detector Features: " + str(self.cryptomining_detector_features_metadata)) + + LOGGER.info("Batch size: " + str(BATCH_SIZE)) + + self.input_name = self.cryptomining_detector_model.get_inputs()[0].name + self.label_name = self.cryptomining_detector_model.get_outputs()[0].name + self.prob_name = self.cryptomining_detector_model.get_outputs()[1].name + + # Kpi values + self.l3_security_status = 0 # unnecessary + self.l3_ml_model_confidence = 0 + self.l3_inferences_in_interval_counter = 0 + + self.l3_ml_model_confidence_normal = 0 + self.l3_inferences_in_interval_counter_normal = 0 + + self.l3_ml_model_confidence_crypto = 0 + self.l3_inferences_in_interval_counter_crypto = 0 + + self.l3_attacks = [] + self.l3_unique_attack_conns = 0 + self.l3_unique_compromised_clients = 0 + self.l3_unique_attackers = 0 + + self.l3_non_empty_time_interval = False + self.active_requests = [] + + self.monitoring_client = MonitoringClient() + self.service_ids = [] + self.monitored_kpis = { + "l3_security_status": { + "kpi_id": None, + "description": "L3 - Confidence of the cryptomining detector in the security status in the last time interval of the service {service_id}", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_SECURITY_STATUS_CRYPTO, + "service_ids": [], + }, + "l3_ml_model_confidence": { + "kpi_id": None, + "description": "L3 - Security status of the service in a time interval of the service {service_id} (“0” if no attack has been detected on the service and “1” if a cryptomining attack has been detected)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_ML_CONFIDENCE, + "service_ids": [], + }, + "l3_unique_attack_conns": { + "kpi_id": None, + "description": "L3 - Number of attack connections detected in a time interval of the service {service_id} (attacks of the same connection [origin IP, origin port, destination IP and destination port] are only considered once)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_UNIQUE_ATTACK_CONNS, + "service_ids": [], + }, + "l3_unique_compromised_clients": { + "kpi_id": None, + "description": "L3 - Number of unique compromised clients of the service in a time interval of the service {service_id} (attacks from the same origin IP are only considered once)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_UNIQUE_COMPROMISED_CLIENTS, + "service_ids": [], + }, + "l3_unique_attackers": { + "kpi_id": None, + "description": "L3 - number of unique attackers of the service in a time interval of the service {service_id} (attacks from the same destination IP are only considered once)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_UNIQUE_ATTACKERS, + "service_ids": [], + }, + } + self.attackmitigator_client = l3_attackmitigatorClient() + + # Environment variables + self.CLASSIFICATION_THRESHOLD = os.getenv("CAD_CLASSIFICATION_THRESHOLD", 0.5) + self.MONITORED_KPIS_TIME_INTERVAL_AGG = os.getenv("MONITORED_KPIS_TIME_INTERVAL_AGG", 60) + + # Constants + self.NORMAL_CLASS = 0 + self.CRYPTO_CLASS = 1 + + self.kpi_test = None + self.time_interval_start = None + self.time_interval_end = None + + # CAD evaluation tests + self.cad_inference_times = [] + self.cad_num_inference_measurements = 100 + + # AM evaluation tests + self.am_notification_times = [] + + # List of attack connections + self.attack_connections = [] + + self.correct_attack_conns = 0 + self.correct_predictions = 0 + self.total_predictions = 0 + self.false_positives = 0 + self.false_negatives = 0 + + """ + Create a monitored KPI for a specific service and add it to the Monitoring Client + -input: + + service_id: service ID where the KPI will be monitored + + kpi_name: name of the KPI + + kpi_description: description of the KPI + + kpi_sample_type: KPI sample type of the KPI (it must be defined in the kpi_sample_types.proto file) + -output: KPI identifier representing the KPI + """ + + def create_kpi( + self, + service_id, + kpi_name, + kpi_description, + kpi_sample_type, + ): + kpidescriptor = KpiDescriptor() + kpidescriptor.kpi_description = kpi_description + kpidescriptor.service_id.service_uuid.uuid = service_id.service_uuid.uuid + kpidescriptor.kpi_sample_type = kpi_sample_type + new_kpi = self.monitoring_client.SetKpi(kpidescriptor) + + LOGGER.info("Created KPI {}".format(kpi_name)) + + return new_kpi + + """ + Create the monitored KPIs for a specific service, add them to the Monitoring Client and store their identifiers in the monitored_kpis dictionary + -input: + + service_id: service ID where the KPIs will be monitored + -output: None + """ + + def create_kpis(self, service_id, device_id, endpoint_id): + LOGGER.info("Creating KPIs for service {}".format(service_id)) + + # for now, all the KPIs are created for all the services from which requests are received + for kpi in self.monitored_kpis: + # generate random slice_id + slice_id = SliceId() + slice_id.slice_uuid.uuid = str(uuid.uuid4()) + + # generate random connection_id + connection_id = ConnectionId() + connection_id.connection_uuid.uuid = str(uuid.uuid4()) + + created_kpi = self.create_kpi( + service_id, + kpi, + self.monitored_kpis[kpi]["description"].format(service_id=service_id.service_uuid.uuid), + self.monitored_kpis[kpi]["kpi_sample_type"], + ) + self.monitored_kpis[kpi]["kpi_id"] = created_kpi.kpi_id + self.monitored_kpis[kpi]["service_ids"].append(service_id.service_uuid.uuid) + + LOGGER.info("Created KPIs for service {}".format(service_id)) + + def monitor_kpis(self): + monitor_inference_results = self.inference_results + monitor_service_ids = self.service_ids + + self.assign_timestamp(monitor_inference_results) + + non_empty_time_interval = self.l3_non_empty_time_interval + + if non_empty_time_interval: + for service_id in monitor_service_ids: + LOGGER.debug("service_id: {}".format(service_id)) + + self.monitor_compute_l3_kpi(service_id, monitor_inference_results) + + # Demo mode inference results are erased + """if DEMO_MODE: + # Delete fist half of the inference results + LOGGER.debug("inference_results len: {}".format(len(self.inference_results))) + self.inference_results = self.inference_results[len(self.inference_results)//2:] + LOGGER.debug("inference_results len after erase: {}".format(len(self.inference_results)))""" + # end = time.time() + # LOGGER.debug("Time to process inference results with erase: {}".format(end - start)) + LOGGER.debug("KPIs sent to monitoring server") + else: + LOGGER.debug("No KPIs sent to monitoring server") + + def assign_timestamp(self, monitor_inference_results): + time_interval = self.MONITORED_KPIS_TIME_INTERVAL_AGG + + # assign the timestamp of the first inference result to the time_interval_start + if self.time_interval_start is None: + self.time_interval_start = monitor_inference_results[0]["timestamp"] + LOGGER.debug("self.time_interval_start: {}".format(self.time_interval_start)) + + # add time_interval to the current time to get the time interval end + LOGGER.debug("time_interval: {}".format(time_interval)) + LOGGER.debug(timedelta(seconds=time_interval)) + self.time_interval_end = self.time_interval_start + timedelta(seconds=time_interval) + + current_time = datetime.utcnow() + + LOGGER.debug("current_time: {}".format(current_time)) + + if current_time >= self.time_interval_end: + self.time_interval_start = self.time_interval_end + self.time_interval_end = self.time_interval_start + timedelta(seconds=time_interval) + self.l3_security_status = 0 # unnecessary + self.l3_ml_model_confidence = 0 + self.l3_inferences_in_interval_counter = 0 + + self.l3_ml_model_confidence_normal = 0 + self.l3_inferences_in_interval_counter_normal = 0 + + self.l3_ml_model_confidence_crypto = 0 + self.l3_inferences_in_interval_counter_crypto = 0 + + self.l3_attacks = [] + self.l3_unique_attack_conns = 0 + self.l3_unique_compromised_clients = 0 + self.l3_unique_attackers = 0 + + self.l3_non_empty_time_interval = False + + LOGGER.debug("time_interval_start: {}".format(self.time_interval_start)) + LOGGER.debug("time_interval_end: {}".format(self.time_interval_end)) + + def monitor_compute_l3_kpi(self, service_id, monitor_inference_results): + # L3 security status + kpi_security_status = Kpi() + kpi_security_status.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_security_status"]["kpi_id"]) + kpi_security_status.kpi_value.int32Val = self.l3_security_status + + # L3 ML model confidence + kpi_conf = Kpi() + kpi_conf.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_ml_model_confidence"]["kpi_id"]) + kpi_conf.kpi_value.floatVal = self.monitor_ml_model_confidence() + + # L3 unique attack connections + kpi_unique_attack_conns = Kpi() + kpi_unique_attack_conns.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_unique_attack_conns"]["kpi_id"]) + kpi_unique_attack_conns.kpi_value.int32Val = self.l3_unique_attack_conns + + # L3 unique compromised clients + kpi_unique_compromised_clients = Kpi() + kpi_unique_compromised_clients.kpi_id.kpi_id.CopyFrom( + self.monitored_kpis["l3_unique_compromised_clients"]["kpi_id"] + ) + kpi_unique_compromised_clients.kpi_value.int32Val = self.l3_unique_compromised_clients + + # L3 unique attackers + kpi_unique_attackers = Kpi() + kpi_unique_attackers.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_unique_attackers"]["kpi_id"]) + kpi_unique_attackers.kpi_value.int32Val = self.l3_unique_attackers + + timestamp = Timestamp() + timestamp.timestamp = timestamp_utcnow_to_float() + + kpi_security_status.timestamp.CopyFrom(timestamp) + kpi_conf.timestamp.CopyFrom(timestamp) + kpi_unique_attack_conns.timestamp.CopyFrom(timestamp) + kpi_unique_compromised_clients.timestamp.CopyFrom(timestamp) + kpi_unique_attackers.timestamp.CopyFrom(timestamp) + + LOGGER.debug("Sending KPIs to monitoring server") + + LOGGER.debug("kpi_security_status: {}".format(kpi_security_status)) + LOGGER.debug("kpi_conf: {}".format(kpi_conf)) + LOGGER.debug("kpi_unique_attack_conns: {}".format(kpi_unique_attack_conns)) + LOGGER.debug("kpi_unique_compromised_clients: {}".format(kpi_unique_compromised_clients)) + LOGGER.debug("kpi_unique_attackers: {}".format(kpi_unique_attackers)) + + try: + self.monitoring_client.IncludeKpi(kpi_security_status) + self.monitoring_client.IncludeKpi(kpi_conf) + self.monitoring_client.IncludeKpi(kpi_unique_attack_conns) + self.monitoring_client.IncludeKpi(kpi_unique_compromised_clients) + self.monitoring_client.IncludeKpi(kpi_unique_attackers) + except Exception as e: + LOGGER.debug("Error sending KPIs to monitoring server: {}".format(e)) + + def monitor_ml_model_confidence(self): + if self.l3_security_status == 0: + return self.l3_ml_model_confidence_normal - def make_inference(self, request): - # ML MODEL - x_data = np.array([ - [ - request.n_packets_server_seconds, - request.n_packets_client_seconds, - request.n_bits_server_seconds, - request.n_bits_client_seconds, - request.n_bits_server_n_packets_server, - request.n_bits_client_n_packets_client, - request.n_packets_server_n_packets_client, - request.n_bits_server_n_bits_client, - ] - ]) - - predictions = self.model.run( - [self.prob_name], {self.input_name: x_data.astype(np.float32)})[0] - # Output format + return self.l3_ml_model_confidence_crypto + + """ + Classify connection as standard traffic or cryptomining attack and return results + -input: + + request: L3CentralizedattackdetectorMetrics object with connection features information + -output: L3AttackmitigatorOutput object with information about the assigned class and prediction confidence + """ + + def perform_inference(self, request): + x_data = np.array([[feature.feature for feature in request.features]]) + + # Print input data shape + LOGGER.debug("x_data.shape: {}".format(x_data.shape)) + + # Get batch size + batch_size = x_data.shape[0] + + # Print batch size + LOGGER.debug("batch_size: {}".format(batch_size)) + LOGGER.debug("x_data.shape: {}".format(x_data.shape)) + + inference_time_start = time.perf_counter() + + # Perform inference + predictions = self.cryptomining_detector_model.run( + [self.prob_name], {self.input_name: x_data.astype(np.float32)} + )[0] + + inference_time_end = time.perf_counter() + + # Measure inference time + inference_time = inference_time_end - inference_time_start + self.cad_inference_times.append(inference_time) + + if len(self.cad_inference_times) > self.cad_num_inference_measurements: + inference_times_np_array = np.array(self.cad_inference_times) + np.save(f"inference_times_{batch_size}.npy", inference_times_np_array) + + avg_inference_time = np.mean(inference_times_np_array) + max_inference_time = np.max(inference_times_np_array) + min_inference_time = np.min(inference_times_np_array) + std_inference_time = np.std(inference_times_np_array) + median_inference_time = np.median(inference_times_np_array) + + LOGGER.debug("Average inference time: {}".format(avg_inference_time)) + LOGGER.debug("Max inference time: {}".format(max_inference_time)) + LOGGER.debug("Min inference time: {}".format(min_inference_time)) + LOGGER.debug("Standard deviation inference time: {}".format(std_inference_time)) + LOGGER.debug("Median inference time: {}".format(median_inference_time)) + + with open(f"inference_times_stats_{batch_size}.txt", "w") as f: + f.write("Average inference time: {}\n".format(avg_inference_time)) + f.write("Max inference time: {}\n".format(max_inference_time)) + f.write("Min inference time: {}\n".format(min_inference_time)) + f.write("Standard deviation inference time: {}\n".format(std_inference_time)) + f.write("Median inference time: {}\n".format(median_inference_time)) + + # Gather the predicted class, the probability of that class and other relevant information required to block the attack output_message = { "confidence": None, "timestamp": datetime.now().strftime("%d/%m/%Y %H:%M:%S"), - "ip_o": request.ip_o, + "ip_o": request.connection_metadata.ip_o, + "ip_d": request.connection_metadata.ip_d, "tag_name": None, "tag": None, - "flow_id": request.flow_id, - "protocol": request.protocol, - "port_d": request.port_d, - "ml_id": "RandomForest", - "time_start": request.time_start, - "time_end": request.time_end, + "flow_id": request.connection_metadata.flow_id, + "protocol": request.connection_metadata.protocol, + "port_o": request.connection_metadata.port_o, + "port_d": request.connection_metadata.port_d, + "ml_id": self.cryptomining_detector_file_name, + "service_id": request.connection_metadata.service_id, + "endpoint_id": request.connection_metadata.endpoint_id, + "time_start": request.connection_metadata.time_start, + "time_end": request.connection_metadata.time_end, } - if predictions[0][1] >= 0.5: + + if predictions[0][1] >= self.CLASSIFICATION_THRESHOLD: output_message["confidence"] = predictions[0][1] output_message["tag_name"] = "Crypto" - output_message["tag"] = 1 + output_message["tag"] = self.CRYPTO_CLASS else: output_message["confidence"] = predictions[0][0] output_message["tag_name"] = "Normal" - output_message["tag"] = 0 + output_message["tag"] = self.NORMAL_CLASS - return L3AttackmitigatorOutput(**output_message) + return output_message + + """ + Classify connection as standard traffic or cryptomining attack and return results + -input: + + request: L3CentralizedattackdetectorMetrics object with connection features information + -output: L3AttackmitigatorOutput object with information about the assigned class and prediction confidence + """ - def SendInput(self, request, context): - # PERFORM INFERENCE WITH SENT INPUTS - logging.debug("") - print("Inferencing ...") + def perform_distributed_inference(self, requests): + batch_size = len(requests) - # STORE VALUES - self.inference_values.append(request) + # Create an empty array to hold the input data + x_data = np.empty((batch_size, len(requests[0].features))) - # MAKE INFERENCE - output = self.make_inference(request) + # Fill in the input data array with features from each request + for i, request in enumerate(requests): + x_data[i] = [feature.feature for feature in request.features] - # SEND INFO TO MITIGATION SERVER - try: - with grpc.insecure_channel("localhost:10002") as channel: - stub = L3AttackmitigatorStub(channel) - print("Sending to mitigator...") - response = stub.SendOutput(output) - print("Sent output to mitigator and received: ", response.message) - - # RETURN "OK" TO THE CALLER - return Empty( - message="OK, information received and mitigator notified" + # Print input data shape + LOGGER.debug("x_data.shape: {}".format(x_data.shape)) + + inference_time_start = time.perf_counter() + + # Perform inference + predictions = self.cryptomining_detector_model.run( + [self.prob_name], {self.input_name: x_data.astype(np.float32)} + )[0] + + inference_time_end = time.perf_counter() + + # Measure inference time + inference_time = inference_time_end - inference_time_start + self.cad_inference_times.append(inference_time) + + if len(self.cad_inference_times) > self.cad_num_inference_measurements: + inference_times_np_array = np.array(self.cad_inference_times) + np.save(f"inference_times_{batch_size}.npy", inference_times_np_array) + + avg_inference_time = np.mean(inference_times_np_array) + max_inference_time = np.max(inference_times_np_array) + min_inference_time = np.min(inference_times_np_array) + std_inference_time = np.std(inference_times_np_array) + median_inference_time = np.median(inference_times_np_array) + + LOGGER.debug("Average inference time: {}".format(avg_inference_time)) + LOGGER.debug("Max inference time: {}".format(max_inference_time)) + LOGGER.debug("Min inference time: {}".format(min_inference_time)) + LOGGER.debug("Standard deviation inference time: {}".format(std_inference_time)) + LOGGER.debug("Median inference time: {}".format(median_inference_time)) + + with open(f"inference_times_stats_{batch_size}.txt", "w") as f: + f.write("Average inference time: {}\n".format(avg_inference_time)) + f.write("Max inference time: {}\n".format(max_inference_time)) + f.write("Min inference time: {}\n".format(min_inference_time)) + f.write("Standard deviation inference time: {}\n".format(std_inference_time)) + f.write("Median inference time: {}\n".format(median_inference_time)) + + # Gather the predicted class, the probability of that class and other relevant information required to block the attack + output_messages = [] + for i, request in enumerate(requests): + output_messages.append({ + "confidence": None, + "timestamp": datetime.now().strftime("%d/%m/%Y %H:%M:%S"), + "ip_o": request.connection_metadata.ip_o, + "ip_d": request.connection_metadata.ip_d, + "tag_name": None, + "tag": None, + "flow_id": request.connection_metadata.flow_id, + "protocol": request.connection_metadata.protocol, + "port_o": request.connection_metadata.port_o, + "port_d": request.connection_metadata.port_d, + "ml_id": self.cryptomining_detector_file_name, + "service_id": request.connection_metadata.service_id, + "endpoint_id": request.connection_metadata.endpoint_id, + "time_start": request.connection_metadata.time_start, + "time_end": request.connection_metadata.time_end, + }) + + if predictions[i][1] >= self.CLASSIFICATION_THRESHOLD: + output_messages[i]["confidence"] = predictions[i][1] + output_messages[i]["tag_name"] = "Crypto" + output_messages[i]["tag"] = self.CRYPTO_CLASS + else: + output_messages[i]["confidence"] = predictions[i][0] + output_messages[i]["tag_name"] = "Normal" + output_messages[i]["tag"] = self.NORMAL_CLASS + + return output_messages + + """ + Receive features from Attack Mitigator, predict attack and communicate with Attack Mitigator + -input: + + request: L3CentralizedattackdetectorMetrics object with connection features information + -output: Empty object with a message about the execution of the function + """ + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def AnalyzeConnectionStatistics(self, request, context): + # Perform inference with the data sent in the request + self.active_requests.append(request) + + if len(self.active_requests) == BATCH_SIZE: + logging.info("Performing inference...") + + inference_time_start = time.time() + cryptomining_detector_output = self.perform_distributed_inference(self.active_requests) + inference_time_end = time.time() + + LOGGER.debug("Inference performed in {} seconds".format(inference_time_end - inference_time_start)) + logging.info("Inference performed correctly") + + self.inference_results.append({"output": cryptomining_detector_output, "timestamp": datetime.now()}) + LOGGER.debug("inference_results length: {}".format(len(self.inference_results))) + + for i, req in enumerate(self.active_requests): + service_id = req.connection_metadata.service_id + device_id = req.connection_metadata.endpoint_id.device_id + endpoint_id = req.connection_metadata.endpoint_id + + # Check if a request of a new service has been received and, if so, create the monitored KPIs for that service + if service_id not in self.service_ids: + self.create_kpis(service_id, device_id, endpoint_id) + self.service_ids.append(service_id) + + monitor_kpis_start = time.time() + self.monitor_kpis() + monitor_kpis_end = time.time() + + LOGGER.debug("Monitoring KPIs performed in {} seconds".format(monitor_kpis_end - monitor_kpis_start)) + LOGGER.debug("cryptomining_detector_output: {}".format(cryptomining_detector_output[i])) + + if DEMO_MODE: + self.analyze_prediction_accuracy(cryptomining_detector_output[i]["confidence"]) + + connection_info = ConnectionInfo( + req.connection_metadata.ip_o, + req.connection_metadata.port_o, + req.connection_metadata.ip_d, + req.connection_metadata.port_d, ) - except: - print('Couldnt find l3_attackmitigator') - return Empty( - message="Mitigator Not found" - ) - def GetOutput(self, request, context): - logging.debug("") - print("Returing inference output...") - k = np.multiply(self.inference_values, [2]) - k = np.sum(k) - return self.make_inference(k) + self.l3_non_empty_time_interval = True + if cryptomining_detector_output[i]["tag_name"] == "Crypto": + self.l3_security_status = 1 + self.l3_inferences_in_interval_counter_crypto += 1 + self.l3_ml_model_confidence_crypto = ( + self.l3_ml_model_confidence_crypto * (self.l3_inferences_in_interval_counter_crypto - 1) + + cryptomining_detector_output[i]["confidence"] + ) / self.l3_inferences_in_interval_counter_crypto - + if connection_info not in self.l3_attacks: + self.l3_attacks.append(connection_info) + self.l3_unique_attack_conns += 1 + + self.l3_unique_compromised_clients = len(set([conn.ip_o for conn in self.l3_attacks])) + self.l3_unique_attackers = len(set([conn.ip_d for conn in self.l3_attacks])) + + else: + self.l3_inferences_in_interval_counter_normal += 1 + self.l3_ml_model_confidence_normal = ( + self.l3_ml_model_confidence_normal * (self.l3_inferences_in_interval_counter_normal - 1) + + cryptomining_detector_output[i]["confidence"] + ) / self.l3_inferences_in_interval_counter_normal + + # Only notify Attack Mitigator when a cryptomining connection has been detected + if cryptomining_detector_output[i]["tag_name"] == "Crypto": + if DEMO_MODE: + self.attack_connections.append(connection_info) + + if connection_info.ip_o in ATTACK_IPS or connection_info.ip_d in ATTACK_IPS: + self.correct_attack_conns += 1 + self.correct_predictions += 1 + else: + LOGGER.debug("False positive: {}".format(connection_info)) + self.false_positives += 1 + + self.total_predictions += 1 + + # if False: + notification_time_start = time.perf_counter() + + LOGGER.debug("Crypto attack detected") + + # Notify the Attack Mitigator component about the attack + logging.info( + "Notifying the Attack Mitigator component about the attack in order to block the connection..." + ) + + try: + logging.info("Sending the connection information to the Attack Mitigator component...") + message = L3AttackmitigatorOutput(**cryptomining_detector_output[i]) + response = self.attackmitigator_client.PerformMitigation(message) + notification_time_end = time.perf_counter() + + self.am_notification_times.append(notification_time_end - notification_time_start) + + LOGGER.debug(f"am_notification_times length: {len(self.am_notification_times)}") + LOGGER.debug(f"last am_notification_time: {self.am_notification_times[-1]}") + + if len(self.am_notification_times) > 100: + am_notification_times_np_array = np.array(self.am_notification_times) + np.save("am_notification_times.npy", am_notification_times_np_array) + + avg_notification_time = np.mean(am_notification_times_np_array) + max_notification_time = np.max(am_notification_times_np_array) + min_notification_time = np.min(am_notification_times_np_array) + std_notification_time = np.std(am_notification_times_np_array) + median_notification_time = np.median(am_notification_times_np_array) + + LOGGER.debug("Average notification time: {}".format(avg_notification_time)) + LOGGER.debug("Max notification time: {}".format(max_notification_time)) + LOGGER.debug("Min notification time: {}".format(min_notification_time)) + LOGGER.debug("Std notification time: {}".format(std_notification_time)) + LOGGER.debug("Median notification time: {}".format(median_notification_time)) + + with open("am_notification_times_stats.txt", "w") as f: + f.write("Average notification time: {}\n".format(avg_notification_time)) + f.write("Max notification time: {}\n".format(max_notification_time)) + f.write("Min notification time: {}\n".format(min_notification_time)) + f.write("Std notification time: {}\n".format(std_notification_time)) + f.write("Median notification time: {}\n".format(median_notification_time)) + + # logging.info("Attack Mitigator notified and received response: ", response.message) # FIX No message received + logging.info("Attack Mitigator notified") + + #return Empty(message="OK, information received and mitigator notified abou the attack") + + except Exception as e: + logging.error("Error notifying the Attack Mitigator component about the attack: ", e) + logging.error("Couldn't find l3_attackmitigator") + + return Empty(message="Attack Mitigator not found") + else: + logging.info("No attack detected") + + if cryptomining_detector_output[i]["tag_name"] != "Crypto": + if connection_info.ip_o not in ATTACK_IPS and connection_info.ip_d not in ATTACK_IPS: + self.correct_predictions += 1 + else: + LOGGER.debug("False negative: {}".format(connection_info)) + self.false_negatives += 1 + + self.total_predictions += 1 + + # return Empty(message="Ok, information received (no attack detected)") + + self.active_requests = [] + return Empty(message="Ok, metrics processed") + + return Empty(message="Ok, information received") + + def analyze_prediction_accuracy(self, confidence): + LOGGER.info("Number of Attack Connections Correctly Classified: {}".format(self.correct_attack_conns)) + LOGGER.info("Number of Attack Connections: {}".format(len(self.attack_connections))) + + if self.total_predictions > 0: + overall_detection_acc = self.correct_predictions / self.total_predictions + else: + overall_detection_acc = 0 + + LOGGER.info("Overall Detection Accuracy: {}\n".format(overall_detection_acc)) + + if len(self.attack_connections) > 0: + cryptomining_attack_detection_acc = self.correct_attack_conns / len(self.attack_connections) + else: + cryptomining_attack_detection_acc = 0 + + LOGGER.info("Cryptomining Attack Detection Accuracy: {}".format(cryptomining_attack_detection_acc)) + LOGGER.info("Cryptomining Detector Confidence: {}".format(confidence)) + + with open("prediction_accuracy.txt", "a") as f: + LOGGER.debug("Exporting prediction accuracy and confidence") + + f.write("Overall Detection Accuracy: {}\n".format(overall_detection_acc)) + f.write("Cryptomining Attack Detection Accuracy: {}\n".format(cryptomining_attack_detection_acc)) + f.write("Total Predictions: {}\n".format(self.total_predictions)) + f.write("Total Positives: {}\n".format(len(self.attack_connections))) + f.write("False Positives: {}\n".format(self.false_positives)) + f.write("True Negatives: {}\n".format(self.total_predictions - len(self.attack_connections))) + f.write("False Negatives: {}\n".format(self.false_negatives)) + f.write("Cryptomining Detector Confidence: {}\n\n".format(confidence)) + f.write("Timestamp: {}\n".format(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))) + f.close() + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def AnalyzeBatchConnectionStatistics(self, request, context): + batch_time_start = time.time() + + for metric in request.metrics: + self.AnalyzeConnectionStatistics(metric, context) + batch_time_end = time.time() + + with open("batch_time.txt", "a") as f: + f.write(str(len(request.metrics)) + "\n") + f.write(str(batch_time_end - batch_time_start) + "\n\n") + f.close() + + logging.debug("Metrics: " + str(len(request.metrics))) + logging.debug("Batch time: " + str(batch_time_end - batch_time_start)) + + return Empty(message="OK, information received.") + + """ + Send features allocated in the metadata of the onnx file to the DAD + -output: ONNX metadata as a list of integers + """ + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetFeaturesIds(self, request: Empty, context): + features = AutoFeatures() + + for feature in self.cryptomining_detector_features_metadata: + features.auto_features.append(feature) + + return features diff --git a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl_old.py b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl_old.py new file mode 100644 index 0000000000000000000000000000000000000000..1fdc955557f189d2f5aded162052743b3e762036 --- /dev/null +++ b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl_old.py @@ -0,0 +1,791 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 __future__ import print_function +from datetime import datetime +from datetime import timedelta + +import os +import numpy as np +import onnxruntime as rt +import logging +import time + +from common.proto.l3_centralizedattackdetector_pb2 import Empty, AutoFeatures +from common.proto.l3_centralizedattackdetector_pb2_grpc import L3CentralizedattackdetectorServicer + +from common.proto.l3_attackmitigator_pb2 import L3AttackmitigatorOutput + +from common.proto.monitoring_pb2 import KpiDescriptor +from common.proto.kpi_sample_types_pb2 import KpiSampleType + +from monitoring.client.MonitoringClient import MonitoringClient +from common.proto.monitoring_pb2 import Kpi + +from common.tools.timestamp.Converters import timestamp_utcnow_to_float +from common.proto.context_pb2 import Timestamp, SliceId, ConnectionId + +from l3_attackmitigator.client.l3_attackmitigatorClient import l3_attackmitigatorClient + +import uuid + + +LOGGER = logging.getLogger(__name__) +# ML directory (ml_model/cryptomining_detector/cryptomining_detector.onnx) +current_dir = os.path.dirname(os.path.abspath(__file__)) + +# Demo constants +DEMO_MODE = True +ATTACK_IPS = ["37.187.95.110", "91.121.140.167", "94.23.23.52", "94.23.247.226", "149.202.83.171"] + + +class ConnectionInfo: + def __init__(self, ip_o, port_o, ip_d, port_d): + self.ip_o = ip_o + self.port_o = port_o + self.ip_d = ip_d + self.port_d = port_d + + def __eq__(self, other): + return ( + self.ip_o == other.ip_o + and self.port_o == other.port_o + and self.ip_d == other.ip_d + and self.port_d == other.port_d + ) + + def __str__(self): + return "ip_o: " + self.ip_o + "\nport_o: " + self.port_o + "\nip_d: " + self.ip_d + "\nport_d: " + self.port_d + + +class l3_centralizedattackdetectorServiceServicerImpl(L3CentralizedattackdetectorServicer): + + """ + Initialize variables, prediction model and clients of components used by CAD + """ + + def __init__(self): + LOGGER.info("Creating Centralized Attack Detector Service") + + self.inference_values = [] + self.inference_results = [] + self.cryptomining_detector_path = os.path.join(current_dir, "ml_model/cryptomining_detector/") + self.cryptomining_detector_file_name = os.listdir(self.cryptomining_detector_path)[0] + self.cryptomining_detector_model_path = os.path.join( + self.cryptomining_detector_path, self.cryptomining_detector_file_name + ) + self.cryptomining_detector_model = rt.InferenceSession(self.cryptomining_detector_model_path) + + # Load cryptomining detector features metadata from ONNX file + self.cryptomining_detector_features_metadata = list( + self.cryptomining_detector_model.get_modelmeta().custom_metadata_map.values() + ) + self.cryptomining_detector_features_metadata = [float(x) for x in self.cryptomining_detector_features_metadata] + self.cryptomining_detector_features_metadata.sort() + LOGGER.info("Cryptomining Detector Features: " + str(self.cryptomining_detector_features_metadata)) + + self.input_name = self.cryptomining_detector_model.get_inputs()[0].name + self.label_name = self.cryptomining_detector_model.get_outputs()[0].name + self.prob_name = self.cryptomining_detector_model.get_outputs()[1].name + + self.monitoring_client = MonitoringClient() + self.service_ids = [] + self.monitored_kpis = { + "l3_security_status": { + "kpi_id": None, + "description": "L3 - Confidence of the cryptomining detector in the security status in the last time interval of the service {service_id}", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_SECURITY_STATUS_CRYPTO, + "service_ids": [], + }, + "l3_ml_model_confidence": { + "kpi_id": None, + "description": "L3 - Security status of the service in a time interval of the service {service_id} (“0” if no attack has been detected on the service and “1” if a cryptomining attack has been detected)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_ML_CONFIDENCE, + "service_ids": [], + }, + "l3_unique_attack_conns": { + "kpi_id": None, + "description": "L3 - Number of attack connections detected in a time interval of the service {service_id} (attacks of the same connection [origin IP, origin port, destination IP and destination port] are only considered once)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_UNIQUE_ATTACK_CONNS, + "service_ids": [], + }, + "l3_unique_compromised_clients": { + "kpi_id": None, + "description": "L3 - Number of unique compromised clients of the service in a time interval of the service {service_id} (attacks from the same origin IP are only considered once)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_UNIQUE_COMPROMISED_CLIENTS, + "service_ids": [], + }, + "l3_unique_attackers": { + "kpi_id": None, + "description": "L3 - number of unique attackers of the service in a time interval of the service {service_id} (attacks from the same destination IP are only considered once)", + "kpi_sample_type": KpiSampleType.KPISAMPLETYPE_L3_UNIQUE_ATTACKERS, + "service_ids": [], + }, + } + self.attackmitigator_client = l3_attackmitigatorClient() + + # Environment variables + self.CLASSIFICATION_THRESHOLD = os.getenv("CAD_CLASSIFICATION_THRESHOLD", 0.5) + self.MONITORED_KPIS_TIME_INTERVAL_AGG = os.getenv("MONITORED_KPIS_TIME_INTERVAL_AGG", 60) + + # Constants + self.NORMAL_CLASS = 0 + self.CRYPTO_CLASS = 1 + + self.kpi_test = None + self.time_interval_start = None + self.time_interval_end = None + + # CAD evaluation tests + self.cad_inference_times = [] + self.cad_num_inference_measurements = 100 + + # AM evaluation tests + self.am_notification_times = [] + + # List of attack connections + self.attack_connections = [] + + self.correct_attack_conns = 0 + self.correct_predictions = 0 + self.total_predictions = 0 + self.false_positives = 0 + self.false_negatives = 0 + + """ + Create a monitored KPI for a specific service and add it to the Monitoring Client + -input: + + service_id: service ID where the KPI will be monitored + + kpi_name: name of the KPI + + kpi_description: description of the KPI + + kpi_sample_type: KPI sample type of the KPI (it must be defined in the kpi_sample_types.proto file) + -output: KPI identifier representing the KPI + """ + + def create_kpi( + self, + service_id, + kpi_name, + kpi_description, + kpi_sample_type, + ): + kpidescriptor = KpiDescriptor() + kpidescriptor.kpi_description = kpi_description + kpidescriptor.service_id.service_uuid.uuid = service_id.service_uuid.uuid + kpidescriptor.kpi_sample_type = kpi_sample_type + new_kpi = self.monitoring_client.SetKpi(kpidescriptor) + + LOGGER.info("Created KPI {}".format(kpi_name)) + + return new_kpi + + """ + Create the monitored KPIs for a specific service, add them to the Monitoring Client and store their identifiers in the monitored_kpis dictionary + -input: + + service_id: service ID where the KPIs will be monitored + -output: None + """ + + def create_kpis(self, service_id, device_id, endpoint_id): + LOGGER.info("Creating KPIs for service {}".format(service_id)) + + # for now, all the KPIs are created for all the services from which requests are received + for kpi in self.monitored_kpis: + # generate random slice_id + slice_id = SliceId() + slice_id.slice_uuid.uuid = str(uuid.uuid4()) + + # generate random connection_id + connection_id = ConnectionId() + connection_id.connection_uuid.uuid = str(uuid.uuid4()) + + created_kpi = self.create_kpi( + service_id, + kpi, + self.monitored_kpis[kpi]["description"].format(service_id=service_id.service_uuid.uuid), + self.monitored_kpis[kpi]["kpi_sample_type"], + ) + self.monitored_kpis[kpi]["kpi_id"] = created_kpi.kpi_id + self.monitored_kpis[kpi]["service_ids"].append(service_id.service_uuid.uuid) + + LOGGER.info("Created KPIs for service {}".format(service_id)) + + def monitor_kpis(self): + monitor_inference_results = self.inference_results + monitor_service_ids = self.service_ids + + LOGGER.debug("monitor_inference_results: {}".format(len(monitor_inference_results))) + LOGGER.debug("monitor_service_ids: {}".format(len(monitor_service_ids))) + + self.assign_timestamp(monitor_inference_results) + + self.delete_older_inference_results(monitor_inference_results) + + non_empty_time_interval = self.check_inference_time_interval(monitor_inference_results) + + if non_empty_time_interval: + # start = time.time() + for service_id in monitor_service_ids: + LOGGER.debug("service_id: {}".format(service_id)) + + self.monitor_compute_l3_kpi(service_id, monitor_inference_results) + + # Demo mode inference results are erased + """if DEMO_MODE: + # Delete fist half of the inference results + LOGGER.debug("inference_results len: {}".format(len(self.inference_results))) + self.inference_results = self.inference_results[len(self.inference_results)//2:] + LOGGER.debug("inference_results len after erase: {}".format(len(self.inference_results)))""" + # end = time.time() + # LOGGER.debug("Time to process inference results with erase: {}".format(end - start)) + LOGGER.debug("KPIs sent to monitoring server") + else: + LOGGER.debug("No KPIs sent to monitoring server") + + def assign_timestamp(self, monitor_inference_results): + time_interval = self.MONITORED_KPIS_TIME_INTERVAL_AGG + + # assign the timestamp of the first inference result to the time_interval_start + if self.time_interval_start is None: + self.time_interval_start = monitor_inference_results[0]["timestamp"] + LOGGER.debug("self.time_interval_start: {}".format(self.time_interval_start)) + + # add time_interval to the current time to get the time interval end + LOGGER.debug("time_interval: {}".format(time_interval)) + LOGGER.debug(timedelta(seconds=time_interval)) + self.time_interval_end = self.time_interval_start + timedelta(seconds=time_interval) + + current_time = datetime.utcnow() + + LOGGER.debug("current_time: {}".format(current_time)) + + if current_time >= self.time_interval_end: + self.time_interval_start = self.time_interval_end + self.time_interval_end = self.time_interval_start + timedelta(seconds=time_interval) + + LOGGER.debug("time_interval_start: {}".format(self.time_interval_start)) + LOGGER.debug("time_interval_end: {}".format(self.time_interval_end)) + + def delete_older_inference_results(self, monitor_inference_results): + # delete all inference results that are older than the time_interval_start + delete_inference_results = [] + + for i in range(len(monitor_inference_results)): + inference_result_timestamp = monitor_inference_results[i]["timestamp"] + + if inference_result_timestamp < self.time_interval_start: + delete_inference_results.append(monitor_inference_results[i]) + + if len(delete_inference_results) > 0: + monitor_inference_results = [ + inference_result + for inference_result in monitor_inference_results + if inference_result not in delete_inference_results + ] + if DEMO_MODE: + LOGGER.debug("inference_results len: {}".format(len(self.inference_results))) + self.inference_results = monitor_inference_results + LOGGER.debug("inference_results len after erase: {}".format(len(self.inference_results))) + LOGGER.debug(f"Cleaned inference results. {len(delete_inference_results)} inference results deleted") + + def check_inference_time_interval(self, monitor_inference_results): + # check if there is at least one inference result in monitor_inference_results in the current time_interval + num_inference_results_in_time_interval = 0 + for i in range(len(monitor_inference_results)): + inference_result_timestamp = monitor_inference_results[i]["timestamp"] + + if ( + inference_result_timestamp >= self.time_interval_start + and inference_result_timestamp < self.time_interval_end + ): + num_inference_results_in_time_interval += 1 + + if num_inference_results_in_time_interval > 0: + non_empty_time_interval = True + LOGGER.debug( + f"Current time interval is not empty (there are {num_inference_results_in_time_interval} inference results" + ) + else: + non_empty_time_interval = False + LOGGER.debug("Current time interval is empty. No KPIs will be reported.") + + return non_empty_time_interval + + def monitor_compute_l3_kpi(self, service_id, monitor_inference_results): + # L3 security status + kpi_security_status = Kpi() + kpi_security_status.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_security_status"]["kpi_id"]) + kpi_security_status.kpi_value.int32Val = self.monitor_security_status(service_id, monitor_inference_results) + + # L3 ML model confidence + kpi_conf = Kpi() + kpi_conf.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_ml_model_confidence"]["kpi_id"]) + kpi_conf.kpi_value.floatVal = self.monitor_ml_model_confidence( + service_id, monitor_inference_results, kpi_security_status + ) + + # L3 unique attack connections + kpi_unique_attack_conns = Kpi() + kpi_unique_attack_conns.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_unique_attack_conns"]["kpi_id"]) + kpi_unique_attack_conns.kpi_value.int32Val = self.monitor_unique_attack_conns( + service_id, monitor_inference_results + ) + + # L3 unique compromised clients + kpi_unique_compromised_clients = Kpi() + kpi_unique_compromised_clients.kpi_id.kpi_id.CopyFrom( + self.monitored_kpis["l3_unique_compromised_clients"]["kpi_id"] + ) + kpi_unique_compromised_clients.kpi_value.int32Val = self.monitor_unique_compromised_clients( + service_id, monitor_inference_results + ) + + # L3 unique attackers + kpi_unique_attackers = Kpi() + kpi_unique_attackers.kpi_id.kpi_id.CopyFrom(self.monitored_kpis["l3_unique_attackers"]["kpi_id"]) + kpi_unique_attackers.kpi_value.int32Val = self.monitor_unique_attackers(service_id, monitor_inference_results) + + timestamp = Timestamp() + timestamp.timestamp = timestamp_utcnow_to_float() + + kpi_security_status.timestamp.CopyFrom(timestamp) + kpi_conf.timestamp.CopyFrom(timestamp) + kpi_unique_attack_conns.timestamp.CopyFrom(timestamp) + kpi_unique_compromised_clients.timestamp.CopyFrom(timestamp) + kpi_unique_attackers.timestamp.CopyFrom(timestamp) + + LOGGER.debug("Sending KPIs to monitoring server") + + LOGGER.debug("kpi_security_status: {}".format(kpi_security_status)) + LOGGER.debug("kpi_conf: {}".format(kpi_conf)) + LOGGER.debug("kpi_unique_attack_conns: {}".format(kpi_unique_attack_conns)) + LOGGER.debug("kpi_unique_compromised_clients: {}".format(kpi_unique_compromised_clients)) + LOGGER.debug("kpi_unique_attackers: {}".format(kpi_unique_attackers)) + + try: + self.monitoring_client.IncludeKpi(kpi_security_status) + self.monitoring_client.IncludeKpi(kpi_conf) + self.monitoring_client.IncludeKpi(kpi_unique_attack_conns) + self.monitoring_client.IncludeKpi(kpi_unique_compromised_clients) + self.monitoring_client.IncludeKpi(kpi_unique_attackers) + except Exception as e: + LOGGER.debug("Error sending KPIs to monitoring server: {}".format(e)) + + def monitor_security_status(self, service_id, monitor_inference_results): + # get the output.tag of the ML model of the last aggregation time interval as indicated by the self.MONITORED_KPIS_TIME_INTERVAL_AGG variable + outputs_last_time_interval = [] + + for i in range(len(monitor_inference_results)): + if ( + monitor_inference_results[i]["timestamp"] >= self.time_interval_start + and monitor_inference_results[i]["timestamp"] < self.time_interval_end + and monitor_inference_results[i]["output"]["service_id"] == service_id + and service_id.service_uuid.uuid in self.monitored_kpis["l3_security_status"]["service_ids"] + ): + outputs_last_time_interval.append(monitor_inference_results[i]["output"]["tag"]) + + LOGGER.debug("outputs_last_time_interval: {}".format(outputs_last_time_interval)) + + # check if all outputs are 0 + all_outputs_zero = True + for output in outputs_last_time_interval: + if output != self.NORMAL_CLASS: + all_outputs_zero = False + break + + if all_outputs_zero: + return 0 + return 1 + + def monitor_ml_model_confidence(self, service_id, monitor_inference_results, kpi_security_status): + # get the output.confidence of the ML model of the last aggregation time interval as indicated by the self.MONITORED_KPIS_TIME_INTERVAL_AGG variable + confidences_normal_last_time_interval = [] + confidences_crypto_last_time_interval = [] + + for i in range(len(monitor_inference_results)): + LOGGER.debug("monitor_inference_results[i]: {}".format(monitor_inference_results[i])) + + if ( + monitor_inference_results[i]["timestamp"] >= self.time_interval_start + and monitor_inference_results[i]["timestamp"] < self.time_interval_end + and monitor_inference_results[i]["output"]["service_id"] == service_id + and service_id.service_uuid.uuid in self.monitored_kpis["l3_ml_model_confidence"]["service_ids"] + ): + if monitor_inference_results[i]["output"]["tag"] == self.NORMAL_CLASS: + confidences_normal_last_time_interval.append(monitor_inference_results[i]["output"]["confidence"]) + elif monitor_inference_results[i]["output"]["tag"] == self.CRYPTO_CLASS: + confidences_crypto_last_time_interval.append(monitor_inference_results[i]["output"]["confidence"]) + else: + LOGGER.debug("Unknown tag: {}".format(monitor_inference_results[i]["output"]["tag"])) + + LOGGER.debug("confidences_normal_last_time_interval: {}".format(confidences_normal_last_time_interval)) + LOGGER.debug("confidences_crypto_last_time_interval: {}".format(confidences_crypto_last_time_interval)) + + if kpi_security_status.kpi_value.int32Val == 0: + return np.mean(confidences_normal_last_time_interval) + + return np.mean(confidences_crypto_last_time_interval) + + def monitor_unique_attack_conns(self, service_id, monitor_inference_results): + # get the number of unique attack connections (grouping by origin IP, origin port, destination IP, destination port) of the last aggregation time interval as indicated by the self.MONITORED_KPIS_TIME_INTERVAL_AGG variable + num_unique_attack_conns_last_time_interval = 0 + unique_attack_conns_last_time_interval = [] + + for i in range(len(monitor_inference_results)): + if ( + monitor_inference_results[i]["timestamp"] >= self.time_interval_start + and monitor_inference_results[i]["timestamp"] < self.time_interval_end + and monitor_inference_results[i]["output"]["service_id"] == service_id + and service_id.service_uuid.uuid in self.monitored_kpis["l3_unique_attack_conns"]["service_ids"] + ): + if monitor_inference_results[i]["output"]["tag"] == self.CRYPTO_CLASS: + current_attack_conn = { + "ip_o": monitor_inference_results[i]["output"]["ip_o"], + "port_o": monitor_inference_results[i]["output"]["port_o"], + "ip_d": monitor_inference_results[i]["output"]["ip_d"], + "port_d": monitor_inference_results[i]["output"]["port_d"], + } + + is_unique_attack_conn = True + + for j in range(len(unique_attack_conns_last_time_interval)): + if current_attack_conn == unique_attack_conns_last_time_interval[j]: + is_unique_attack_conn = False + + if is_unique_attack_conn: + num_unique_attack_conns_last_time_interval += 1 + unique_attack_conns_last_time_interval.append(current_attack_conn) + + return num_unique_attack_conns_last_time_interval + + def monitor_unique_compromised_clients(self, service_id, monitor_inference_results): + # get the number of unique compromised clients (grouping by origin IP) of the last aggregation time interval as indicated by the self.MONITORED_KPIS_TIME_INTERVAL_AGG variable + num_unique_compromised_clients_last_time_interval = 0 + unique_compromised_clients_last_time_interval = [] + + for i in range(len(monitor_inference_results)): + if ( + monitor_inference_results[i]["timestamp"] >= self.time_interval_start + and monitor_inference_results[i]["timestamp"] < self.time_interval_end + and monitor_inference_results[i]["output"]["service_id"] == service_id + and service_id.service_uuid.uuid in self.monitored_kpis["l3_unique_compromised_clients"]["service_ids"] + ): + if monitor_inference_results[i]["output"]["tag"] == self.CRYPTO_CLASS: + if ( + monitor_inference_results[i]["output"]["ip_o"] + not in unique_compromised_clients_last_time_interval + ): + unique_compromised_clients_last_time_interval.append( + monitor_inference_results[i]["output"]["ip_o"] + ) + num_unique_compromised_clients_last_time_interval += 1 + + return num_unique_compromised_clients_last_time_interval + + def monitor_unique_attackers(self, service_id, monitor_inference_results): + # get the number of unique attackers (grouping by destination ip) of the last aggregation time interval as indicated by the self.MONITORED_KPIS_TIME_INTERVAL_AGG variable + num_unique_attackers_last_time_interval = 0 + unique_attackers_last_time_interval = [] + + for i in range(len(monitor_inference_results)): + if ( + monitor_inference_results[i]["timestamp"] >= self.time_interval_start + and monitor_inference_results[i]["timestamp"] < self.time_interval_end + and monitor_inference_results[i]["output"]["service_id"] == service_id + and service_id.service_uuid.uuid in self.monitored_kpis["l3_unique_attackers"]["service_ids"] + ): + if monitor_inference_results[i]["output"]["tag"] == self.CRYPTO_CLASS: + if monitor_inference_results[i]["output"]["ip_d"] not in unique_attackers_last_time_interval: + unique_attackers_last_time_interval.append(monitor_inference_results[i]["output"]["ip_d"]) + num_unique_attackers_last_time_interval += 1 + + return num_unique_attackers_last_time_interval + + """ + Classify connection as standard traffic or cryptomining attack and return results + -input: + + request: L3CentralizedattackdetectorMetrics object with connection features information + -output: L3AttackmitigatorOutput object with information about the assigned class and prediction confidence + """ + + def perform_inference(self, request): + x_data = np.array([[feature.feature for feature in request.features]]) + + # Print input data shape + LOGGER.debug("x_data.shape: {}".format(x_data.shape)) + + # Get batch size + batch_size = x_data.shape[0] + + # Print batch size + LOGGER.debug("batch_size: {}".format(batch_size)) + LOGGER.debug("x_data.shape: {}".format(x_data.shape)) + + inference_time_start = time.perf_counter() + + # Perform inference + predictions = self.cryptomining_detector_model.run( + [self.prob_name], {self.input_name: x_data.astype(np.float32)} + )[0] + + inference_time_end = time.perf_counter() + + # Measure inference time + inference_time = inference_time_end - inference_time_start + self.cad_inference_times.append(inference_time) + + if len(self.cad_inference_times) > self.cad_num_inference_measurements: + inference_times_np_array = np.array(self.cad_inference_times) + np.save(f"inference_times_{batch_size}.npy", inference_times_np_array) + + avg_inference_time = np.mean(inference_times_np_array) + max_inference_time = np.max(inference_times_np_array) + min_inference_time = np.min(inference_times_np_array) + std_inference_time = np.std(inference_times_np_array) + median_inference_time = np.median(inference_times_np_array) + + LOGGER.debug("Average inference time: {}".format(avg_inference_time)) + LOGGER.debug("Max inference time: {}".format(max_inference_time)) + LOGGER.debug("Min inference time: {}".format(min_inference_time)) + LOGGER.debug("Standard deviation inference time: {}".format(std_inference_time)) + LOGGER.debug("Median inference time: {}".format(median_inference_time)) + + with open(f"inference_times_stats_{batch_size}.txt", "w") as f: + f.write("Average inference time: {}\n".format(avg_inference_time)) + f.write("Max inference time: {}\n".format(max_inference_time)) + f.write("Min inference time: {}\n".format(min_inference_time)) + f.write("Standard deviation inference time: {}\n".format(std_inference_time)) + f.write("Median inference time: {}\n".format(median_inference_time)) + + # Gather the predicted class, the probability of that class and other relevant information required to block the attack + output_message = { + "confidence": None, + "timestamp": datetime.now().strftime("%d/%m/%Y %H:%M:%S"), + "ip_o": request.connection_metadata.ip_o, + "ip_d": request.connection_metadata.ip_d, + "tag_name": None, + "tag": None, + "flow_id": request.connection_metadata.flow_id, + "protocol": request.connection_metadata.protocol, + "port_o": request.connection_metadata.port_o, + "port_d": request.connection_metadata.port_d, + "ml_id": self.cryptomining_detector_file_name, + "service_id": request.connection_metadata.service_id, + "endpoint_id": request.connection_metadata.endpoint_id, + "time_start": request.connection_metadata.time_start, + "time_end": request.connection_metadata.time_end, + } + + if predictions[0][1] >= self.CLASSIFICATION_THRESHOLD: + output_message["confidence"] = predictions[0][1] + output_message["tag_name"] = "Crypto" + output_message["tag"] = self.CRYPTO_CLASS + else: + output_message["confidence"] = predictions[0][0] + output_message["tag_name"] = "Normal" + output_message["tag"] = self.NORMAL_CLASS + + return output_message + + """ + Receive features from Attack Mitigator, predict attack and communicate with Attack Mitigator + -input: + + request: L3CentralizedattackdetectorMetrics object with connection features information + -output: Empty object with a message about the execution of the function + """ + + def AnalyzeConnectionStatistics(self, request, context): + # Perform inference with the data sent in the request + logging.info("Performing inference...") + start = time.time() + cryptomining_detector_output = self.perform_inference(request) + end = time.time() + LOGGER.debug("Inference performed in {} seconds".format(end - start)) + logging.info("Inference performed correctly") + + self.inference_results.append({"output": cryptomining_detector_output, "timestamp": datetime.now()}) + LOGGER.debug("inference_results length: {}".format(len(self.inference_results))) + + service_id = request.connection_metadata.service_id + device_id = request.connection_metadata.endpoint_id.device_id + endpoint_id = request.connection_metadata.endpoint_id + + # Check if a request of a new service has been received and, if so, create the monitored KPIs for that service + if service_id not in self.service_ids: + self.create_kpis(service_id, device_id, endpoint_id) + self.service_ids.append(service_id) + + start = time.time() + self.monitor_kpis() + end = time.time() + + LOGGER.debug("Monitoring KPIs performed in {} seconds".format(end - start)) + LOGGER.debug("cryptomining_detector_output: {}".format(cryptomining_detector_output)) + + if DEMO_MODE: + self.analyze_prediction_accuracy(cryptomining_detector_output["confidence"]) + + connection_info = ConnectionInfo( + request.connection_metadata.ip_o, + request.connection_metadata.port_o, + request.connection_metadata.ip_d, + request.connection_metadata.port_d, + ) + + if cryptomining_detector_output["tag_name"] == "Crypto": + LOGGER.debug("Crypto found") + LOGGER.debug(connection_info) + + # Only notify Attack Mitigator when a cryptomining connection has been detected + if cryptomining_detector_output["tag_name"] == "Crypto" and connection_info not in self.attack_connections: + self.attack_connections.append(connection_info) + + if connection_info.ip_o in ATTACK_IPS or connection_info.ip_d in ATTACK_IPS: + self.correct_attack_conns += 1 + self.correct_predictions += 1 + else: + LOGGER.debug("False positive: {}".format(connection_info)) + self.false_positives += 1 + + self.total_predictions += 1 + + # if False: + notification_time_start = time.perf_counter() + + LOGGER.debug("Crypto attack detected") + + # Notify the Attack Mitigator component about the attack + logging.info( + "Notifying the Attack Mitigator component about the attack in order to block the connection..." + ) + + try: + logging.info("Sending the connection information to the Attack Mitigator component...") + message = L3AttackmitigatorOutput(**cryptomining_detector_output) + response = self.attackmitigator_client.PerformMitigation(message) + notification_time_end = time.perf_counter() + + self.am_notification_times.append(notification_time_end - notification_time_start) + + LOGGER.debug(f"am_notification_times length: {len(self.am_notification_times)}") + LOGGER.debug(f"last am_notification_time: {self.am_notification_times[-1]}") + + if len(self.am_notification_times) > 100: + am_notification_times_np_array = np.array(self.am_notification_times) + np.save("am_notification_times.npy", am_notification_times_np_array) + + avg_notification_time = np.mean(am_notification_times_np_array) + max_notification_time = np.max(am_notification_times_np_array) + min_notification_time = np.min(am_notification_times_np_array) + std_notification_time = np.std(am_notification_times_np_array) + median_notification_time = np.median(am_notification_times_np_array) + + LOGGER.debug("Average notification time: {}".format(avg_notification_time)) + LOGGER.debug("Max notification time: {}".format(max_notification_time)) + LOGGER.debug("Min notification time: {}".format(min_notification_time)) + LOGGER.debug("Std notification time: {}".format(std_notification_time)) + LOGGER.debug("Median notification time: {}".format(median_notification_time)) + + with open("am_notification_times_stats.txt", "w") as f: + f.write("Average notification time: {}\n".format(avg_notification_time)) + f.write("Max notification time: {}\n".format(max_notification_time)) + f.write("Min notification time: {}\n".format(min_notification_time)) + f.write("Std notification time: {}\n".format(std_notification_time)) + f.write("Median notification time: {}\n".format(median_notification_time)) + + # logging.info("Attack Mitigator notified and received response: ", response.message) # FIX No message received + logging.info("Attack Mitigator notified") + + return Empty(message="OK, information received and mitigator notified abou the attack") + except Exception as e: + logging.error("Error notifying the Attack Mitigator component about the attack: ", e) + logging.error("Couldn't find l3_attackmitigator") + + return Empty(message="Attack Mitigator not found") + else: + logging.info("No attack detected") + + if cryptomining_detector_output["tag_name"] != "Crypto": + if connection_info.ip_o not in ATTACK_IPS and connection_info.ip_d not in ATTACK_IPS: + self.correct_predictions += 1 + else: + LOGGER.debug("False negative: {}".format(connection_info)) + self.false_negatives += 1 + + self.total_predictions += 1 + + return Empty(message="Ok, information received (no attack detected)") + + def analyze_prediction_accuracy(self, confidence): + LOGGER.info("Number of Attack Connections Correctly Classified: {}".format(self.correct_attack_conns)) + LOGGER.info("Number of Attack Connections: {}".format(len(self.attack_connections))) + + if self.total_predictions > 0: + overall_detection_acc = self.correct_predictions / self.total_predictions + else: + overall_detection_acc = 0 + + LOGGER.info("Overall Detection Accuracy: {}\n".format(overall_detection_acc)) + + if len(self.attack_connections) > 0: + cryptomining_attack_detection_acc = self.correct_attack_conns / len(self.attack_connections) + else: + cryptomining_attack_detection_acc = 0 + + LOGGER.info("Cryptomining Attack Detection Accuracy: {}".format(cryptomining_attack_detection_acc)) + LOGGER.info("Cryptomining Detector Confidence: {}".format(confidence)) + + with open("prediction_accuracy.txt", "a") as f: + LOGGER.debug("Exporting prediction accuracy and confidence") + + f.write("Overall Detection Accuracy: {}\n".format(overall_detection_acc)) + f.write("Cryptomining Attack Detection Accuracy: {}\n".format(cryptomining_attack_detection_acc)) + f.write("Total Predictions: {}\n".format(self.total_predictions)) + f.write("Total Positives: {}\n".format(len(self.attack_connections))) + f.write("False Positives: {}\n".format(self.false_positives)) + f.write("True Negatives: {}\n".format(self.total_predictions - len(self.attack_connections))) + f.write("False Negatives: {}\n".format(self.false_negatives)) + f.write("Cryptomining Detector Confidence: {}\n\n".format(confidence)) + f.write("Timestamp: {}\n".format(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))) + f.close() + + def AnalyzeBatchConnectionStatistics(self, request, context): + start = time.time() + + for metric in request.metrics: + self.AnalyzeConnectionStatistics(metric, context) + end = time.time() + + with open("batch_time.txt", "a") as f: + f.write(str(len(request.metrics)) + "\n") + f.write(str(end - start) + "\n\n") + f.close() + + logging.debug("Metrics: " + str(len(request.metrics))) + logging.debug("Batch time: " + str(end - start)) + + return Empty(message="OK, information received.") + + """ + Send features allocated in the metadata of the onnx file to the DAD + -output: ONNX metadata as a list of integers + """ + + def GetFeaturesIds(self, request: Empty, context): + features = AutoFeatures() + + for feature in self.cryptomining_detector_features_metadata: + features.auto_features.append(feature) + + return features diff --git a/src/l3_centralizedattackdetector/service/ml_model/cryptomining_detector/crypto_5g_rf_spider_features.onnx b/src/l3_centralizedattackdetector/service/ml_model/cryptomining_detector/crypto_5g_rf_spider_features.onnx new file mode 100644 index 0000000000000000000000000000000000000000..731724b29f3a1c22d50de8adbf291193a352ab33 Binary files /dev/null and b/src/l3_centralizedattackdetector/service/ml_model/cryptomining_detector/crypto_5g_rf_spider_features.onnx differ diff --git a/src/l3_centralizedattackdetector/service/ml_model/teraflow_rf.onnx b/src/l3_centralizedattackdetector/service/ml_model/teraflow_rf.onnx deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/load_generator/command/__main__.py b/src/load_generator/command/__main__.py index 550b88084da0cf95ffc27e36743663b592041a7e..555f1dd4fb12e86eaeda1658a97164b52a7bf1ba 100644 --- a/src/load_generator/command/__main__.py +++ b/src/load_generator/command/__main__.py @@ -34,8 +34,14 @@ def main(): #RequestType.SLICE_L2NM, #RequestType.SLICE_L3NM, ], + device_regex=r'.+', + endpoint_regex=r'.+', offered_load = 50, holding_time = 10, + availability_ranges = [[0.0, 99.9999]], + capacity_gbps_ranges = [[0.1, 100.00]], + e2e_latency_ms_ranges = [[5.0, 100.00]], + max_workers = 10, dry_mode = False, # in dry mode, no request is sent to TeraFlowSDN record_to_dlt = False, # if record_to_dlt, changes in device/link/service/slice are uploaded to DLT dlt_domain_id = 'dlt-perf-eval', # domain used to uploaded entities, ignored when record_to_dlt = False diff --git a/src/load_generator/load_gen/Constants.py b/src/load_generator/load_gen/Constants.py index 9ae3cdc1216891ca4dfcf01c1bd49d27bf4ef6f6..09cdecab124a776d3f71f66554db0934eaf1bb1c 100644 --- a/src/load_generator/load_gen/Constants.py +++ b/src/load_generator/load_gen/Constants.py @@ -27,4 +27,8 @@ ENDPOINT_COMPATIBILITY = { 'PHOTONIC_MEDIA:DWDM:G_50GHZ:INPUT' : 'PHOTONIC_MEDIA:DWDM:G_50GHZ:OUTPUT', } -MAX_WORKER_THREADS = 10 \ No newline at end of file +DEFAULT_AVAILABILITY_RANGES = [[0.0, 99.9999]] +DEFAULT_CAPACITY_GBPS_RANGES = [[0.1, 100.00]] +DEFAULT_E2E_LATENCY_MS_RANGES = [[5.0, 100.00]] + +DEFAULT_MAX_WORKERS = 10 diff --git a/src/load_generator/load_gen/Parameters.py b/src/load_generator/load_gen/Parameters.py index f0de3ea1aa268c520fd214f7f621953289ac5bc9..5bb7a9b725f955a4186a21201e439f9cfaa71324 100644 --- a/src/load_generator/load_gen/Parameters.py +++ b/src/load_generator/load_gen/Parameters.py @@ -13,18 +13,41 @@ # limitations under the License. from typing import List, Optional +from load_generator.load_gen.Constants import ( + DEFAULT_AVAILABILITY_RANGES, DEFAULT_CAPACITY_GBPS_RANGES, DEFAULT_E2E_LATENCY_MS_RANGES, DEFAULT_MAX_WORKERS) +from load_generator.tools.ListScalarRange import Type_ListScalarRange + class Parameters: def __init__( - self, num_requests : int, request_types : List[str], offered_load : Optional[float] = None, - inter_arrival_time : Optional[float] = None, holding_time : Optional[float] = None, do_teardown : bool = True, - dry_mode : bool = False, record_to_dlt : bool = False, dlt_domain_id : Optional[str] = None + self, + num_requests : int, + request_types : List[str], + device_regex : Optional[str] = None, + endpoint_regex : Optional[str] = None, + offered_load : Optional[float] = None, + inter_arrival_time : Optional[float] = None, + holding_time : Optional[float] = None, + availability_ranges : Type_ListScalarRange = DEFAULT_AVAILABILITY_RANGES, + capacity_gbps_ranges : Type_ListScalarRange = DEFAULT_CAPACITY_GBPS_RANGES, + e2e_latency_ms_ranges : Type_ListScalarRange = DEFAULT_E2E_LATENCY_MS_RANGES, + max_workers : int = DEFAULT_MAX_WORKERS, + do_teardown : bool = True, + dry_mode : bool = False, + record_to_dlt : bool = False, + dlt_domain_id : Optional[str] = None ) -> None: self._num_requests = num_requests self._request_types = request_types + self._device_regex = r'.*' if (device_regex is None or len(device_regex) == 0) else device_regex + self._endpoint_regex = r'.*' if (endpoint_regex is None or len(endpoint_regex) == 0) else endpoint_regex self._offered_load = offered_load self._inter_arrival_time = inter_arrival_time self._holding_time = holding_time + self._availability_ranges = availability_ranges + self._capacity_gbps_ranges = capacity_gbps_ranges + self._e2e_latency_ms_ranges = e2e_latency_ms_ranges + self._max_workers = max_workers self._do_teardown = do_teardown self._dry_mode = dry_mode self._record_to_dlt = record_to_dlt @@ -50,6 +73,12 @@ class Parameters: @property def request_types(self): return self._request_types + @property + def device_regex(self): return self._device_regex + + @property + def endpoint_regex(self): return self._endpoint_regex + @property def offered_load(self): return self._offered_load @@ -59,6 +88,18 @@ class Parameters: @property def holding_time(self): return self._holding_time + @property + def availability_ranges(self): return self._availability_ranges + + @property + def capacity_gbps_ranges(self): return self._capacity_gbps_ranges + + @property + def e2e_latency_ms_ranges(self): return self._e2e_latency_ms_ranges + + @property + def max_workers(self): return self._max_workers + @property def do_teardown(self): return self._do_teardown diff --git a/src/load_generator/load_gen/RequestGenerator.py b/src/load_generator/load_gen/RequestGenerator.py index aa95f49424b797b2d2bc6908fbcfea9d981d4026..149c2568bf2cc08b351d9af31ecbe512faf3e796 100644 --- a/src/load_generator/load_gen/RequestGenerator.py +++ b/src/load_generator/load_gen/RequestGenerator.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, json, random, threading +import logging, json, random, re, threading, uuid from typing import Dict, Optional, Set, Tuple from common.proto.context_pb2 import Empty, IsolationLevelEnum, TopologyId from common.tools.grpc.Tools import grpc_message_to_json @@ -28,6 +28,7 @@ from common.tools.object_factory.Slice import json_slice from common.tools.object_factory.Topology import json_topology_id from context.client.ContextClient import ContextClient from dlt.connector.client.DltConnectorClient import DltConnectorClient +from load_generator.tools.ListScalarRange import generate_value from .Constants import ENDPOINT_COMPATIBILITY, RequestType from .DltTools import record_device_to_dlt, record_link_to_dlt from .Parameters import Parameters @@ -38,14 +39,6 @@ ROUTER_ID = { 'R149': '5.5.5.5', 'R155': '5.5.5.1', 'R199': '5.5.5.6', - -} - -VIRTUAL_CIRCUIT = { - 'R149': '5.5.5.5', - 'R155': '5.5.5.1', - 'R199': '5.5.5.6', - } class RequestGenerator: @@ -53,6 +46,7 @@ class RequestGenerator: self._parameters = parameters self._lock = threading.Lock() self._num_generated = 0 + self._num_released = 0 self._available_device_endpoints : Dict[str, Set[str]] = dict() self._used_device_endpoints : Dict[str, Dict[str, str]] = dict() self._endpoint_ids_to_types : Dict[Tuple[str, str], str] = dict() @@ -64,6 +58,9 @@ class RequestGenerator: @property def num_generated(self): return self._num_generated + @property + def num_released(self): return self._num_released + @property def infinite_loop(self): return self._parameters.num_requests == 0 @@ -78,13 +75,21 @@ class RequestGenerator: if self._parameters.record_to_dlt: dlt_domain_id = TopologyId(**json_topology_id('dlt-perf-eval')) + re_device = re.compile(r'^{:s}$'.format(self._parameters.device_regex)) + re_endpoint = re.compile(r'^{:s}$'.format(self._parameters.endpoint_regex)) + devices = context_client.ListDevices(Empty()) for device in devices.devices: + if self._parameters.record_to_dlt: + record_device_to_dlt(dlt_connector_client, dlt_domain_id, device.device_id) + + if re_device.match(device.name) is None: continue device_uuid = device.device_id.device_uuid.uuid self._device_data[device_uuid] = grpc_message_to_json(device) _endpoints = self._available_device_endpoints.setdefault(device_uuid, set()) for endpoint in device.device_endpoints: + if re_endpoint.match(endpoint.name) is None: continue endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid endpoints = self._device_endpoint_data.setdefault(device_uuid, dict()) endpoints[endpoint_uuid] = grpc_message_to_json(endpoint) @@ -93,12 +98,12 @@ class RequestGenerator: _endpoints.add(endpoint_uuid) self._endpoint_ids_to_types.setdefault((device_uuid, endpoint_uuid), endpoint_type) self._endpoint_types_to_ids.setdefault(endpoint_type, set()).add((device_uuid, endpoint_uuid)) - - if self._parameters.record_to_dlt: - record_device_to_dlt(dlt_connector_client, dlt_domain_id, device.device_id) links = context_client.ListLinks(Empty()) for link in links.links: + if self._parameters.record_to_dlt: + record_link_to_dlt(dlt_connector_client, dlt_domain_id, link.link_id) + for endpoint_id in link.link_endpoint_ids: device_uuid = endpoint_id.device_id.device_uuid.uuid endpoint_uuid = endpoint_id.endpoint_uuid.uuid @@ -114,9 +119,6 @@ class RequestGenerator: endpoint_key = (device_uuid, endpoint_uuid) if endpoint_key not in endpoints_for_type: continue endpoints_for_type.discard(endpoint_key) - - if self._parameters.record_to_dlt: - record_link_to_dlt(dlt_connector_client, dlt_domain_id, link.link_id) def dump_state(self) -> None: with self._lock: @@ -186,28 +188,23 @@ class RequestGenerator: self._used_device_endpoints.setdefault(device_uuid, dict()).pop(endpoint_uuid, None) self._available_device_endpoints.setdefault(device_uuid, set()).add(endpoint_uuid) - def compose_request(self) -> Tuple[bool, Optional[Dict]]: # completed, request + def compose_request(self) -> Tuple[bool, Optional[Dict], str]: # completed, request with self._lock: if not self.infinite_loop and (self._num_generated >= self._parameters.num_requests): LOGGER.info('Generation Done!') - return True, None # completed - self._num_generated += 1 - num_request = self._num_generated + return True, None, None # completed - #request_uuid = str(uuid.uuid4()) - request_uuid = 'svc_{:d}'.format(num_request) - - # choose request type + request_uuid = str(uuid.uuid4()) request_type = random.choice(self._parameters.request_types) if request_type in { RequestType.SERVICE_L2NM, RequestType.SERVICE_L3NM, RequestType.SERVICE_TAPI, RequestType.SERVICE_MW }: - return False, self._compose_service(num_request, request_uuid, request_type) + return False, self._compose_service(request_uuid, request_type), request_type elif request_type in {RequestType.SLICE_L2NM, RequestType.SLICE_L3NM}: - return False, self._compose_slice(num_request, request_uuid, request_type) + return False, self._compose_slice(request_uuid, request_type), request_type - def _compose_service(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: + def _compose_service(self, request_uuid : str, request_type : str) -> Optional[Dict]: # choose source endpoint src_endpoint_types = set(ENDPOINT_COMPATIBILITY.keys()) if request_type in {RequestType.SERVICE_TAPI} else None src = self._use_device_endpoint(request_uuid, request_type, endpoint_types=src_endpoint_types) @@ -236,6 +233,10 @@ class RequestGenerator: self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) return None + with self._lock: + self._num_generated += 1 + num_request = self._num_generated + # compose endpoints dst_device_uuid,dst_endpoint_uuid = dst endpoint_ids = [ @@ -244,9 +245,9 @@ class RequestGenerator: ] if request_type == RequestType.SERVICE_L2NM: - availability = round(random.uniform(0.0, 99.9999), ndigits=5) - capacity_gbps = round(random.uniform(0.1, 100.00), ndigits=2) - e2e_latency_ms = round(random.uniform(5.0, 100.00), ndigits=2) + availability = generate_value(self._parameters.availability_ranges, ndigits=5) + capacity_gbps = generate_value(self._parameters.capacity_gbps_ranges, ndigits=2) + e2e_latency_ms = generate_value(self._parameters.e2e_latency_ms_ranges, ndigits=2) constraints = [ json_constraint_sla_availability(1, True, availability), @@ -255,18 +256,18 @@ class RequestGenerator: json_constraint_sla_latency(e2e_latency_ms), ] - vlan_id = 300 + (num_request % 1000) + vlan_id = 300 + num_request % 1000 circuit_id = '{:03d}'.format(vlan_id) src_device_name = self._device_data[src_device_uuid]['name'] src_endpoint_name = self._device_endpoint_data[src_device_uuid][src_endpoint_uuid]['name'] + src_router_num = int(re.findall(r'^\D*(\d+)', src_device_name)[0]) src_router_id = ROUTER_ID.get(src_device_name) - src_router_num = int(src_device_name.replace('R', '')) if src_router_id is None: src_router_id = '10.0.0.{:d}'.format(src_router_num) dst_device_name = self._device_data[dst_device_uuid]['name'] dst_endpoint_name = self._device_endpoint_data[dst_device_uuid][dst_endpoint_uuid]['name'] - dst_router_num = int(dst_device_name.replace('R', '')) + dst_router_num = int(re.findall(r'^\D*(\d+)', dst_device_name)[0]) dst_router_id = ROUTER_ID.get(dst_device_name) if dst_router_id is None: dst_router_id = '10.0.0.{:d}'.format(dst_router_num) @@ -293,9 +294,9 @@ class RequestGenerator: request_uuid, endpoint_ids=endpoint_ids, constraints=constraints, config_rules=config_rules) elif request_type == RequestType.SERVICE_L3NM: - availability = round(random.uniform(0.0, 99.9999), ndigits=5) - capacity_gbps = round(random.uniform(0.1, 100.00), ndigits=2) - e2e_latency_ms = round(random.uniform(5.0, 100.00), ndigits=2) + availability = generate_value(self._parameters.availability_ranges, ndigits=5) + capacity_gbps = generate_value(self._parameters.capacity_gbps_ranges, ndigits=2) + e2e_latency_ms = generate_value(self._parameters.e2e_latency_ms_ranges, ndigits=2) constraints = [ json_constraint_sla_availability(1, True, availability), @@ -306,21 +307,21 @@ class RequestGenerator: bgp_as = 65000 + (num_request % 10000) - vlan_id = num_request % 1000 +300 + vlan_id = 300 + num_request % 1000 x = num_request % 255 y = num_request % 25 * num_request % 10 route_distinguisher = '{:5d}:{:03d}'.format(bgp_as, vlan_id) src_device_name = self._device_data[src_device_uuid]['name'] src_endpoint_name = self._device_endpoint_data[src_device_uuid][src_endpoint_uuid]['name'] + src_router_num = int(re.findall(r'^\D*(\d+)', src_device_name)[0]) src_router_id = ROUTER_ID.get(src_device_name) - src_router_num = int(src_device_name.replace('R', '')) if src_router_id is None: src_router_id = '10.0.0.{:d}'.format(src_router_num) src_address_ip = '10.{:d}.{:d}.{:d}'.format(x, y, src_router_num) dst_device_name = self._device_data[dst_device_uuid]['name'] dst_endpoint_name = self._device_endpoint_data[dst_device_uuid][dst_endpoint_uuid]['name'] - dst_router_num = int(dst_device_name.replace('R', '')) + dst_router_num = int(re.findall(r'^\D*(\d+)', dst_device_name)[0]) dst_router_id = ROUTER_ID.get(dst_device_name) if dst_router_id is None: dst_router_id = '10.0.0.{:d}'.format(dst_router_num) dst_address_ip = '10.{:d}.{:d}.{:d}'.format(y, x, dst_router_num) @@ -382,7 +383,7 @@ class RequestGenerator: return json_service_l2nm_planned( request_uuid, endpoint_ids=endpoint_ids, constraints=[], config_rules=config_rules) - def _compose_slice(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: + def _compose_slice(self, request_uuid : str, request_type : str) -> Optional[Dict]: # choose source endpoint src = self._use_device_endpoint(request_uuid, request_type) if src is None: @@ -403,6 +404,10 @@ class RequestGenerator: self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) return None + with self._lock: + self._num_generated += 1 + num_request = self._num_generated + # compose endpoints dst_device_uuid,dst_endpoint_uuid = dst endpoint_ids = [ @@ -410,9 +415,10 @@ class RequestGenerator: json_endpoint_id(json_device_id(dst_device_uuid), dst_endpoint_uuid), ] - availability = round(random.uniform(0.0, 99.9999), ndigits=5) - capacity_gbps = round(random.uniform(0.1, 100.00), ndigits=2) - e2e_latency_ms = round(random.uniform(5.0, 100.00), ndigits=2) + availability = generate_value(self._parameters.availability_ranges, ndigits=5) + capacity_gbps = generate_value(self._parameters.capacity_gbps_ranges, ndigits=2) + e2e_latency_ms = generate_value(self._parameters.e2e_latency_ms_ranges, ndigits=2) + constraints = [ json_constraint_sla_availability(1, True, availability), json_constraint_sla_capacity(capacity_gbps), @@ -421,14 +427,14 @@ class RequestGenerator: ] if request_type == RequestType.SLICE_L2NM: - vlan_id = num_request % 1000 + vlan_id = 300 + num_request % 1000 circuit_id = '{:03d}'.format(vlan_id) src_device_name = self._device_data[src_device_uuid]['name'] - src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) + src_router_id = '10.0.0.{:d}'.format(int(re.findall(r'^\D*(\d+)', src_device_name)[0])) dst_device_name = self._device_data[dst_device_uuid]['name'] - dst_router_id = '10.0.0.{:d}'.format(int(dst_device_name.replace('R', ''))) + dst_router_id = '10.0.0.{:d}'.format(int(re.findall(r'^\D*(\d+)', dst_device_name)[0])) config_rules = [ json_config_rule_set('/settings', { @@ -453,20 +459,21 @@ class RequestGenerator: ] elif request_type == RequestType.SLICE_L3NM: - vlan_id = num_request % 1000 + vlan_id = 300 + num_request % 1000 + circuit_id = '{:03d}'.format(vlan_id) bgp_as = 60000 + (num_request % 10000) bgp_route_target = '{:5d}:{:03d}'.format(bgp_as, 333) route_distinguisher = '{:5d}:{:03d}'.format(bgp_as, vlan_id) src_device_name = self._device_data[src_device_uuid]['name'] src_endpoint_name = self._device_endpoint_data[src_device_uuid][src_endpoint_uuid]['name'] - src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) - src_address_ip = '.'.join([src_device_name.replace('R', ''), '0'] + src_endpoint_name.split('/')) + src_router_id = '10.0.0.{:d}'.format(int(re.findall(r'^\D*(\d+)', src_device_name)[0])) + src_address_ip = '.'.join([re.findall(r'^\D*(\d+)', src_device_name)[0], '0'] + src_endpoint_name.split('/')) dst_device_name = self._device_data[dst_device_uuid]['name'] dst_endpoint_name = self._device_endpoint_data[dst_device_uuid][dst_endpoint_uuid]['name'] - dst_router_id = '10.0.0.{:d}'.format(int(dst_device_name.replace('R', ''))) - dst_address_ip = '.'.join([dst_device_name.replace('R', ''), '0'] + dst_endpoint_name.split('/')) + dst_router_id = '10.0.0.{:d}'.format(int(re.findall(r'^\D*(\d+)', dst_device_name)[0])) + dst_address_ip = '.'.join([re.findall(r'^\D*(\d+)', dst_device_name)[0], '0'] + dst_endpoint_name.split('/')) config_rules = [ json_config_rule_set('/settings', { @@ -503,8 +510,15 @@ class RequestGenerator: device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] self._release_device_endpoint(device_uuid, endpoint_uuid) + + with self._lock: + self._num_released += 1 + elif 'slice_id' in json_request: for endpoint_id in json_request['slice_endpoint_ids']: device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] self._release_device_endpoint(device_uuid, endpoint_uuid) + + with self._lock: + self._num_released += 1 diff --git a/src/load_generator/load_gen/RequestScheduler.py b/src/load_generator/load_gen/RequestScheduler.py index 773a37eac258f8b3c16c966464ced124d3c77c85..340a5411bacee7b0aeb495963cdf65fbb5d14389 100644 --- a/src/load_generator/load_gen/RequestScheduler.py +++ b/src/load_generator/load_gen/RequestScheduler.py @@ -18,10 +18,11 @@ from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.blocking import BlockingScheduler from datetime import datetime, timedelta from typing import Dict, Optional +from common.method_wrappers.Decorator import MetricsPool from common.proto.context_pb2 import Service, ServiceId, Slice, SliceId +from common.tools.grpc.Tools import grpc_message_to_json_string from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient -from .Constants import MAX_WORKER_THREADS from .DltTools import explore_entities_to_record, record_entities from .Parameters import Parameters from .RequestGenerator import RequestGenerator @@ -31,6 +32,10 @@ logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING) LOGGER = logging.getLogger(__name__) +METRICS_POOL = MetricsPool('LoadGen', 'Requests', labels={ + 'request_type': '' +}) + class RequestScheduler: def __init__( self, parameters : Parameters, generator : RequestGenerator, scheduler_class=BlockingScheduler @@ -38,7 +43,7 @@ class RequestScheduler: self._scheduler = scheduler_class() self._scheduler.configure( jobstores = {'default': MemoryJobStore()}, - executors = {'default': ThreadPoolExecutor(max_workers=MAX_WORKER_THREADS)}, + executors = {'default': ThreadPoolExecutor(max_workers=parameters.max_workers)}, job_defaults = { 'coalesce': False, 'max_instances': 100, @@ -52,6 +57,9 @@ class RequestScheduler: @property def num_generated(self): return min(self._generator.num_generated, self._parameters.num_requests) + @property + def num_released(self): return min(self._generator.num_released, self._parameters.num_requests) + @property def infinite_loop(self): return self._generator.infinite_loop @@ -64,11 +72,12 @@ class RequestScheduler: self._scheduler.add_job( self._request_setup, trigger='date', run_date=run_date, timezone=pytz.utc) - def _schedule_request_teardown(self, request : Dict) -> None: + def _schedule_request_teardown(self, request : Dict, request_type : str) -> None: ht = random.expovariate(1.0 / self._parameters.holding_time) run_date = datetime.utcnow() + timedelta(seconds=ht) + args = (request, request_type) self._scheduler.add_job( - self._request_teardown, args=(request,), trigger='date', run_date=run_date, timezone=pytz.utc) + self._request_teardown, args=args, trigger='date', run_date=run_date, timezone=pytz.utc) def start(self): self._running.set() @@ -80,7 +89,7 @@ class RequestScheduler: self._running.clear() def _request_setup(self) -> None: - completed,request = self._generator.compose_request() + completed, request, request_type = self._generator.compose_request() if completed: LOGGER.info('Generation Done!') #self._scheduler.shutdown() @@ -91,6 +100,9 @@ class RequestScheduler: if request is None: LOGGER.warning('No resources available to compose new request') + metrics = METRICS_POOL.get_metrics_loadgen('setup', labels={'request_type': request_type}) + _, _, _, _, counter_blocked = metrics + counter_blocked.inc() return if 'service_id' in request: @@ -101,7 +113,7 @@ class RequestScheduler: dst_endpoint_uuid = request['service_endpoint_ids'][1]['endpoint_uuid']['uuid'] LOGGER.info('Setup Service: uuid=%s src=%s:%s dst=%s:%s', service_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) - self._create_update(service=request) + self._create_update(request_type, service=request) elif 'slice_id' in request: slice_uuid = request['slice_id']['slice_uuid']['uuid'] @@ -111,12 +123,12 @@ class RequestScheduler: dst_endpoint_uuid = request['slice_endpoint_ids'][1]['endpoint_uuid']['uuid'] LOGGER.info('Setup Slice: uuid=%s src=%s:%s dst=%s:%s', slice_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) - self._create_update(slice_=request) + self._create_update(request_type, slice_=request) if self._parameters.do_teardown: - self._schedule_request_teardown(request) + self._schedule_request_teardown(request, request_type) - def _request_teardown(self, request : Dict) -> None: + def _request_teardown(self, request : Dict, request_type : str) -> None: if 'service_id' in request: service_uuid = request['service_id']['service_uuid']['uuid'] src_device_uuid = request['service_endpoint_ids'][0]['device_id']['device_uuid']['uuid'] @@ -125,7 +137,7 @@ class RequestScheduler: dst_endpoint_uuid = request['service_endpoint_ids'][1]['endpoint_uuid']['uuid'] LOGGER.info('Teardown Service: uuid=%s src=%s:%s dst=%s:%s', service_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) - self._delete(service_id=ServiceId(**(request['service_id']))) + self._delete(request_type, service_id=ServiceId(**(request['service_id']))) elif 'slice_id' in request: slice_uuid = request['slice_id']['slice_uuid']['uuid'] @@ -135,33 +147,64 @@ class RequestScheduler: dst_endpoint_uuid = request['slice_endpoint_ids'][1]['endpoint_uuid']['uuid'] LOGGER.info('Teardown Slice: uuid=%s src=%s:%s dst=%s:%s', slice_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) - self._delete(slice_id=SliceId(**(request['slice_id']))) + self._delete(request_type, slice_id=SliceId(**(request['slice_id']))) self._generator.release_request(request) - def _create_update(self, service : Optional[Dict] = None, slice_ : Optional[Dict] = None) -> None: + def _create_update( + self, request_type : str, service : Optional[Dict] = None, slice_ : Optional[Dict] = None + ) -> None: if self._parameters.dry_mode: return + metrics = METRICS_POOL.get_metrics_loadgen('setup', labels={'request_type': request_type}) + histogram_duration, counter_started, counter_completed, counter_failed, _ = metrics + service_id = None if service is not None: + service_client = ServiceClient() + service_add = copy.deepcopy(service) service_add['service_endpoint_ids'] = [] service_add['service_constraints'] = [] service_add['service_config'] = {'config_rules': []} + service_add = Service(**service_add) + service = Service(**service) + + with histogram_duration.time(): + try: + counter_started.inc() + service_id = service_client.CreateService(service_add) + service_id = service_client.UpdateService(service) + counter_completed.inc() + except: # pylint: disable=bare-except + counter_failed.inc() + MSG = 'Exception Setting Up Service {:s}' + LOGGER.exception(MSG.format(grpc_message_to_json_string(service))) - service_client = ServiceClient() - service_id = service_client.CreateService(Service(**service_add)) service_client.close() slice_id = None if slice_ is not None: + slice_client = SliceClient() + slice_add = copy.deepcopy(slice_) slice_add['slice_endpoint_ids'] = [] slice_add['slice_constraints'] = [] slice_add['slice_config'] = {'config_rules': []} + slice_add = Slice(**slice_add) + slice_ = Slice(**slice_) + + with histogram_duration.time(): + try: + counter_started.inc() + slice_id = slice_client.CreateSlice(slice_add) + slice_id = slice_client.UpdateSlice(slice_) + counter_completed.inc() + except: # pylint: disable=bare-except + counter_failed.inc() + MSG = 'Exception Setting Up Slice {:s}' + LOGGER.exception(MSG.format(grpc_message_to_json_string(slice_))) - slice_client = SliceClient() - slice_id = slice_client.CreateSlice(Slice(**slice_add)) slice_client.close() if self._parameters.record_to_dlt: @@ -171,41 +214,47 @@ class RequestScheduler: slices_to_record=slices_to_record, services_to_record=services_to_record, devices_to_record=devices_to_record, delete=False) - service_id = None - if service is not None: - service_client = ServiceClient() - service_id = service_client.UpdateService(Service(**service)) - service_client.close() + def _delete( + self, request_type : str, service_id : Optional[ServiceId] = None, slice_id : Optional[SliceId] = None + ) -> None: + if self._parameters.dry_mode: return - slice_id = None - if slice_ is not None: - slice_client = SliceClient() - slice_id = slice_client.UpdateSlice(Slice(**slice_)) - slice_client.close() + metrics = METRICS_POOL.get_metrics_loadgen('teardown', labels={'request_type': request_type}) + histogram_duration, counter_started, counter_completed, counter_failed, _ = metrics if self._parameters.record_to_dlt: entities_to_record = explore_entities_to_record(slice_id=slice_id, service_id=service_id) slices_to_record, services_to_record, devices_to_record = entities_to_record - record_entities( - slices_to_record=slices_to_record, services_to_record=services_to_record, - devices_to_record=devices_to_record, delete=False) - def _delete(self, service_id : Optional[ServiceId] = None, slice_id : Optional[SliceId] = None) -> None: - if self._parameters.dry_mode: return + if service_id is not None: + service_client = ServiceClient() - if self._parameters.record_to_dlt: - entities_to_record = explore_entities_to_record(slice_id=slice_id, service_id=service_id) - slices_to_record, services_to_record, devices_to_record = entities_to_record + with histogram_duration.time(): + try: + counter_started.inc() + service_client.DeleteService(service_id) + counter_completed.inc() + except: # pylint: disable=bare-except + counter_failed.inc() + MSG = 'Exception Tearing Down Service {:s}' + LOGGER.exception(MSG.format(grpc_message_to_json_string(service_id))) + + service_client.close() if slice_id is not None: slice_client = SliceClient() - slice_client.DeleteSlice(slice_id) - slice_client.close() - if service_id is not None: - service_client = ServiceClient() - service_client.DeleteService(service_id) - service_client.close() + with histogram_duration.time(): + try: + counter_started.inc() + slice_client.DeleteSlice(slice_id) + counter_completed.inc() + except: # pylint: disable=bare-except + counter_failed.inc() + MSG = 'Exception Tearing Down Slice {:s}' + LOGGER.exception(MSG.format(grpc_message_to_json_string(slice_id))) + + slice_client.close() if self._parameters.record_to_dlt: record_entities( diff --git a/src/load_generator/service/LoadGeneratorServiceServicerImpl.py b/src/load_generator/service/LoadGeneratorServiceServicerImpl.py index d66b0b2c10c5228e0c3d15759fc46b2c0770154d..866f9f089662598b08c8dd03d04b01fd63108f5a 100644 --- a/src/load_generator/service/LoadGeneratorServiceServicerImpl.py +++ b/src/load_generator/service/LoadGeneratorServiceServicerImpl.py @@ -21,6 +21,7 @@ from common.proto.load_generator_pb2_grpc import LoadGeneratorServiceServicer from load_generator.load_gen.Parameters import Parameters as LoadGen_Parameters from load_generator.load_gen.RequestGenerator import RequestGenerator from load_generator.load_gen.RequestScheduler import RequestScheduler +from load_generator.tools.ListScalarRange import list_scalar_range__grpc_to_list, list_scalar_range__list_to_grpc from .Constants import REQUEST_TYPE_MAP, REQUEST_TYPE_REVERSE_MAP LOGGER = logging.getLogger(__name__) @@ -34,15 +35,21 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer): def Start(self, request : Parameters, context : grpc.ServicerContext) -> Empty: self._parameters = LoadGen_Parameters( - num_requests = request.num_requests, - request_types = [REQUEST_TYPE_MAP[rt] for rt in request.request_types], - offered_load = request.offered_load if request.offered_load > 1.e-12 else None, - holding_time = request.holding_time if request.holding_time > 1.e-12 else None, - inter_arrival_time = request.inter_arrival_time if request.inter_arrival_time > 1.e-12 else None, - do_teardown = request.do_teardown, # if set, schedule tear down of requests - dry_mode = request.dry_mode, # in dry mode, no request is sent to TeraFlowSDN - record_to_dlt = request.record_to_dlt, # if set, upload changes to DLT - dlt_domain_id = request.dlt_domain_id, # domain used to uploaded entities (when record_to_dlt = True) + num_requests = request.num_requests, + request_types = [REQUEST_TYPE_MAP[rt] for rt in request.request_types], + device_regex = request.device_regex, + endpoint_regex = request.endpoint_regex, + offered_load = request.offered_load if request.offered_load > 1.e-12 else None, + holding_time = request.holding_time if request.holding_time > 1.e-12 else None, + inter_arrival_time = request.inter_arrival_time if request.inter_arrival_time > 1.e-12 else None, + availability_ranges = list_scalar_range__grpc_to_list(request.availability ), + capacity_gbps_ranges = list_scalar_range__grpc_to_list(request.capacity_gbps ), + e2e_latency_ms_ranges = list_scalar_range__grpc_to_list(request.e2e_latency_ms), + max_workers = request.max_workers, + do_teardown = request.do_teardown, # if set, schedule tear down of requests + dry_mode = request.dry_mode, # in dry mode, no request is sent to TeraFlowSDN + record_to_dlt = request.record_to_dlt, # if set, upload changes to DLT + dlt_domain_id = request.dlt_domain_id, # domain used to uploaded entities (when record_to_dlt = True) ) LOGGER.info('Initializing Generator...') @@ -68,17 +75,28 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer): status = Status() status.num_generated = self._scheduler.num_generated + status.num_released = self._scheduler.num_released status.infinite_loop = self._scheduler.infinite_loop status.running = self._scheduler.running - status.parameters.num_requests = params.num_requests # pylint: disable=no-member - status.parameters.offered_load = params.offered_load # pylint: disable=no-member - status.parameters.holding_time = params.holding_time # pylint: disable=no-member - status.parameters.inter_arrival_time = params.inter_arrival_time # pylint: disable=no-member - status.parameters.do_teardown = params.do_teardown # pylint: disable=no-member - status.parameters.dry_mode = params.dry_mode # pylint: disable=no-member - status.parameters.record_to_dlt = params.record_to_dlt # pylint: disable=no-member - status.parameters.dlt_domain_id = params.dlt_domain_id # pylint: disable=no-member - status.parameters.request_types.extend(request_types) # pylint: disable=no-member + + stat_pars = status.parameters # pylint: disable=no-member + stat_pars.num_requests = params.num_requests # pylint: disable=no-member + stat_pars.device_regex = params.device_regex # pylint: disable=no-member + stat_pars.endpoint_regex = params.endpoint_regex # pylint: disable=no-member + stat_pars.offered_load = params.offered_load # pylint: disable=no-member + stat_pars.holding_time = params.holding_time # pylint: disable=no-member + stat_pars.inter_arrival_time = params.inter_arrival_time # pylint: disable=no-member + stat_pars.max_workers = params.max_workers # pylint: disable=no-member + stat_pars.do_teardown = params.do_teardown # pylint: disable=no-member + stat_pars.dry_mode = params.dry_mode # pylint: disable=no-member + stat_pars.record_to_dlt = params.record_to_dlt # pylint: disable=no-member + stat_pars.dlt_domain_id = params.dlt_domain_id # pylint: disable=no-member + stat_pars.request_types.extend(request_types) # pylint: disable=no-member + + list_scalar_range__list_to_grpc(params.availability_ranges, stat_pars.availability ) # pylint: disable=no-member + list_scalar_range__list_to_grpc(params.capacity_gbps_ranges, stat_pars.capacity_gbps ) # pylint: disable=no-member + list_scalar_range__list_to_grpc(params.e2e_latency_ms_ranges, stat_pars.e2e_latency_ms) # pylint: disable=no-member + return status def Stop(self, request : Empty, context : grpc.ServicerContext) -> Empty: diff --git a/src/load_generator/service/__main__.py b/src/load_generator/service/__main__.py index 227099c59aa57f420c842a6210f3b8b146b23cda..5f5fa97f971223478abba2bfef1a1d6012fb6135 100644 --- a/src/load_generator/service/__main__.py +++ b/src/load_generator/service/__main__.py @@ -13,14 +13,15 @@ # 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, + ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port, wait_for_environment_variables) from .LoadGeneratorService import LoadGeneratorService -log_level = get_log_level() -logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") +LOG_LEVEL = get_log_level() +logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") LOGGER = logging.getLogger(__name__) terminate = threading.Event() @@ -39,17 +40,20 @@ def main(): get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC), ]) + LOGGER.info('Starting...') 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) # Starting load generator service grpc_service = LoadGeneratorService() grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass scheduler = grpc_service.load_generator_servicer._scheduler if scheduler is not None: scheduler.stop() diff --git a/src/load_generator/tools/ListScalarRange.py b/src/load_generator/tools/ListScalarRange.py new file mode 100644 index 0000000000000000000000000000000000000000..9a5a5f39940049adee6dfbe35befd815db9256fe --- /dev/null +++ b/src/load_generator/tools/ListScalarRange.py @@ -0,0 +1,99 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 random +from typing import List, Optional, Tuple, Union + +from common.proto.load_generator_pb2 import ScalarOrRange + +# RegEx to validate strings formatted as: '1, 2.3, 4.5 .. 6.7 , .8...9, 10., .11' +# IMPORTANT: this regex just validates data, it does not extract the pieces of data! +RE_FLOAT = r'[\ ]*[0-9]*[\.]?[0-9]*[\ ]*' +RE_RANGE = RE_FLOAT + r'(\.\.' + RE_FLOAT + r')?' +RE_SCALAR_RANGE_LIST = RE_RANGE + r'(\,' + RE_RANGE + r')*' + +Type_ListScalarRange = List[Union[float, Tuple[float, float]]] + +def parse_list_scalar_range(value : str) -> Type_ListScalarRange: + str_value = str(value).replace(' ', '') + ranges = [[float(value) for value in item.split('..')] for item in str_value.split(',')] + return ranges + +def list_scalar_range__list_to_grpc(list_scalar_range : Type_ListScalarRange, obj : List[ScalarOrRange]) -> None: + for i,scalar_or_range in enumerate(list_scalar_range): + if isinstance(scalar_or_range, (float, str)): + _scalar = obj.add() + _scalar.scalar = float(scalar_or_range) + elif isinstance(scalar_or_range, (list, tuple)): + if len(scalar_or_range) == 1: + _scalar = obj.add() + _scalar.scalar = float(scalar_or_range[0]) + elif len(scalar_or_range) == 2: + _range = obj.add() + _range.range.minimum = float(scalar_or_range[0]) + _range.range.maximum = float(scalar_or_range[1]) + else: + MSG = 'List/tuple with {:d} items in item(#{:d}, {:s})' + raise NotImplementedError(MSG.format(len(scalar_or_range), i, str(scalar_or_range))) + else: + MSG = 'Type({:s}) in item(#{:d}, {:s})' + raise NotImplementedError(MSG.format(str(type(scalar_or_range), i, str(scalar_or_range)))) + +def list_scalar_range__grpc_to_str(obj : List[ScalarOrRange]) -> str: + str_items = list() + for item in obj: + item_kind = item.WhichOneof('value') + if item_kind == 'scalar': + str_items.append(str(item.scalar)) + elif item_kind == 'range': + str_items.append('{:s}..{:s}'.format(str(item.range.minimum), str(item.range.maximum))) + else: + raise NotImplementedError('Unsupported ScalarOrRange kind({:s})'.format(str(item_kind))) + return ','.join(str_items) + +def list_scalar_range__grpc_to_list(obj : List[ScalarOrRange]) -> Type_ListScalarRange: + list_scalar_range = list() + for item in obj: + item_kind = item.WhichOneof('value') + if item_kind == 'scalar': + scalar_or_range = float(item.scalar) + elif item_kind == 'range': + scalar_or_range = (float(item.range.minimum), float(item.range.maximum)) + else: + raise NotImplementedError('Unsupported ScalarOrRange kind({:s})'.format(str(item_kind))) + list_scalar_range.append(scalar_or_range) + return list_scalar_range + +def generate_value( + list_scalar_range : Type_ListScalarRange, ndigits : Optional[int] = None +) -> float: + scalar_or_range = random.choice(list_scalar_range) + if isinstance(scalar_or_range, (float, str)): + value = float(scalar_or_range) + elif isinstance(scalar_or_range, (list, tuple)): + if len(scalar_or_range) == 1: + value = float(scalar_or_range[0]) + elif len(scalar_or_range) == 2: + minimum = float(scalar_or_range[0]) + maximum = float(scalar_or_range[1]) + value = random.uniform(minimum, maximum) + else: + MSG = 'List/tuple with {:d} items in item({:s})' + raise NotImplementedError(MSG.format(len(scalar_or_range), str(scalar_or_range))) + else: + MSG = 'Type({:s}) in item({:s})' + raise NotImplementedError(MSG.format(str(type(scalar_or_range), str(scalar_or_range)))) + + if ndigits is None: return value + return round(value, ndigits=ndigits) diff --git a/src/load_generator/tools/__init__.py b/src/load_generator/tools/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/load_generator/tools/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/monitoring/service/MetricsDBTools.py b/src/monitoring/service/MetricsDBTools.py index 6b98255411aa88ac18bd01474830b3bf268d3483..11574e8f6577db0bab4add96da8157496d40e6f5 100644 --- a/src/monitoring/service/MetricsDBTools.py +++ b/src/monitoring/service/MetricsDBTools.py @@ -13,6 +13,7 @@ # limitations under the License. import time +import math from random import random from questdb.ingress import Sender, IngressError @@ -264,69 +265,66 @@ class MetricsDB(): for kpi in kpi_list: alarm = False kpi_value = kpi[2] + kpiMinIsNone = ((kpiMinValue is None) or math.isnan(kpiMinValue)) + kpiMaxIsNone = ((kpiMaxValue is None) or math.isnan(kpiMaxValue)) if (kpiMinValue == kpi_value and kpiMaxValue == kpi_value and inRange): alarm = True - elif ( - inRange and kpiMinValue is not None and kpiMaxValue is not None and includeMinValue and includeMaxValue): + elif (inRange and not kpiMinIsNone and not kpiMaxIsNone and includeMinValue and includeMaxValue): if (kpi_value >= kpiMinValue and kpi_value <= kpiMaxValue): alarm = True - elif ( - inRange and kpiMinValue is not None and kpiMaxValue is not None and includeMinValue and not includeMaxValue): + elif (inRange and not kpiMinIsNone and not kpiMaxIsNone and includeMinValue and not includeMaxValue): if (kpi_value >= kpiMinValue and kpi_value < kpiMaxValue): alarm = True - elif ( - inRange and kpiMinValue is not None and kpiMaxValue is not None and not includeMinValue and includeMaxValue): + elif (inRange and not kpiMinIsNone and not kpiMaxIsNone and not includeMinValue and includeMaxValue): if (kpi_value > kpiMinValue and kpi_value <= kpiMaxValue): alarm = True - elif ( - inRange and kpiMinValue is not None and kpiMaxValue is not None and not includeMinValue and not includeMaxValue): + elif (inRange and not kpiMinIsNone and not kpiMaxIsNone and not includeMinValue and not includeMaxValue): if (kpi_value > kpiMinValue and kpi_value < kpiMaxValue): alarm = True - elif ( - not inRange and kpiMinValue is not None and kpiMaxValue is not None and includeMinValue and includeMaxValue): + elif (not inRange and not kpiMinIsNone and not kpiMaxIsNone and includeMinValue and includeMaxValue): if (kpi_value <= kpiMinValue or kpi_value >= kpiMaxValue): alarm = True - elif ( - not inRange and kpiMinValue is not None and kpiMaxValue is not None and includeMinValue and not includeMaxValue): + elif (not inRange and not kpiMinIsNone and not kpiMaxIsNone and includeMinValue and not includeMaxValue): if (kpi_value <= kpiMinValue or kpi_value > kpiMaxValue): alarm = True - elif ( - not inRange and kpiMinValue is not None and kpiMaxValue is not None and not includeMinValue and includeMaxValue): + elif (not inRange and not kpiMinIsNone and not kpiMaxIsNone and not includeMinValue and includeMaxValue): if (kpi_value < kpiMinValue or kpi_value >= kpiMaxValue): alarm = True - elif ( - not inRange and kpiMinValue is not None and kpiMaxValue is not None and not includeMinValue and not includeMaxValue): + elif (not inRange and not kpiMinIsNone and not kpiMaxIsNone and not includeMinValue and not includeMaxValue): if (kpi_value < kpiMinValue or kpi_value > kpiMaxValue): alarm = True - elif (inRange and kpiMinValue is not None and kpiMaxValue is None and includeMinValue): + elif (inRange and not kpiMinIsNone and kpiMaxIsNone and includeMinValue): if (kpi_value >= kpiMinValue): alarm = True - elif (inRange and kpiMinValue is not None and kpiMaxValue is None and not includeMinValue): + elif (inRange and not kpiMinIsNone and kpiMaxIsNone and not includeMinValue): if (kpi_value > kpiMinValue): alarm = True - elif (not inRange and kpiMinValue is not None and kpiMaxValue is None and not includeMinValue): + elif (not inRange and not kpiMinIsNone and kpiMaxIsNone and includeMinValue): if (kpi_value <= kpiMinValue): alarm = True - elif (not inRange and kpiMinValue is not None and kpiMaxValue is None and not includeMinValue): - if (kpi_value <= kpiMinValue): + elif (not inRange and not kpiMinIsNone and kpiMaxIsNone and not includeMinValue): + if (kpi_value < kpiMinValue): alarm = True - elif (inRange and kpiMinValue is None and kpiMaxValue is not None and includeMaxValue): + elif (inRange and kpiMinIsNone and not kpiMaxIsNone and includeMaxValue): if (kpi_value <= kpiMaxValue): alarm = True - elif (inRange and kpiMinValue is None and kpiMaxValue is not None and not includeMaxValue): + elif (inRange and kpiMinIsNone and not kpiMaxIsNone and not includeMaxValue): if (kpi_value < kpiMaxValue): alarm = True - elif (not inRange and kpiMinValue is None and kpiMaxValue is not None and not includeMaxValue): + elif (not inRange and kpiMinIsNone and not kpiMaxIsNone and includeMaxValue): if (kpi_value >= kpiMaxValue): alarm = True - elif (not inRange and kpiMinValue is None and kpiMaxValue is not None and not includeMaxValue): - if (kpi_value >= kpiMaxValue): + elif (not inRange and kpiMinIsNone and not kpiMaxIsNone and not includeMaxValue): + if (kpi_value > kpiMaxValue): alarm = True if alarm: valid_kpi_list.append(kpi) - alarm_queue.put_nowait(valid_kpi_list) - LOGGER.debug(f"Alarm of KPI {kpi_id} triggered -> kpi_value:{kpi[2]}, timestamp:{kpi[1]}") + if valid_kpi_list: + alarm_queue.put_nowait(valid_kpi_list) + LOGGER.debug(f"Alarm of KPI {kpi_id} triggered -> kpi_value:{kpi[2]}, timestamp:{kpi[1]}") + else: + LOGGER.debug(f"No new alarms triggered for the alarm of KPI {kpi_id}") else: LOGGER.debug(f"No new data for the alarm of KPI {kpi_id}") except (Exception) as e: - LOGGER.debug(f"Alarm data cannot be retrieved. {e}") \ No newline at end of file + LOGGER.debug(f"Alarm data cannot be retrieved. {e}") diff --git a/src/monitoring/service/MonitoringServiceServicerImpl.py b/src/monitoring/service/MonitoringServiceServicerImpl.py index f408734df40c1bc5c16b7e108e3ce5a211165f71..3bfef65ff0c52f110b9a091e96b6f6b97dfa79cf 100644 --- a/src/monitoring/service/MonitoringServiceServicerImpl.py +++ b/src/monitoring/service/MonitoringServiceServicerImpl.py @@ -12,12 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, grpc +import logging, os, grpc from queue import Queue - from typing import Iterator - -from common.logger import getJSONLogger +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.context_pb2 import Empty from common.proto.device_pb2 import MonitoringSettings from common.proto.kpi_sample_types_pb2 import KpiSampleType @@ -25,30 +23,22 @@ from common.proto.monitoring_pb2_grpc import MonitoringServiceServicer from common.proto.monitoring_pb2 import AlarmResponse, AlarmDescriptor, AlarmList, SubsList, KpiId, \ KpiDescriptor, KpiList, KpiQuery, SubsDescriptor, SubscriptionID, AlarmID, KpiDescriptorList, \ MonitorKpiRequest, Kpi, AlarmSubscription, SubsResponse, RawKpiTable, RawKpi, RawKpiList -from common.method_wrappers.ServiceExceptions import ServiceException from common.tools.timestamp.Converters import timestamp_string_to_float, timestamp_utcnow_to_float - -from monitoring.service import ManagementDBTools, MetricsDBTools from device.client.DeviceClient import DeviceClient - -from prometheus_client import Counter, Summary - +from monitoring.service import ManagementDBTools, MetricsDBTools from monitoring.service.AlarmManager import AlarmManager from monitoring.service.NameMapping import NameMapping from monitoring.service.SubscriptionManager import SubscriptionManager -LOGGER = getJSONLogger('monitoringservice-server') -LOGGER.setLevel('DEBUG') - -MONITORING_GETINSTANTKPI_REQUEST_TIME = Summary( - 'monitoring_getinstantkpi_processing_seconds', 'Time spent processing monitoring instant kpi request') -MONITORING_INCLUDEKPI_COUNTER = Counter('monitoring_includekpi_counter', 'Monitoring include kpi request counter') +LOGGER = logging.getLogger(__name__) METRICSDB_HOSTNAME = os.environ.get("METRICSDB_HOSTNAME") METRICSDB_ILP_PORT = os.environ.get("METRICSDB_ILP_PORT") METRICSDB_REST_PORT = os.environ.get("METRICSDB_REST_PORT") METRICSDB_TABLE_MONITORING_KPIS = os.environ.get("METRICSDB_TABLE_MONITORING_KPIS") +METRICS_POOL = MetricsPool('Monitoring', 'RPC') + class MonitoringServiceServicerImpl(MonitoringServiceServicer): def __init__(self, name_mapping : NameMapping): LOGGER.info('Init monitoringService') @@ -63,514 +53,363 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer): LOGGER.info('MetricsDB initialized') # SetKpi (SetKpiRequest) returns (KpiId) {} + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetKpi( self, request: KpiDescriptor, grpc_context: grpc.ServicerContext ) -> KpiId: - # CREATEKPI_COUNTER_STARTED.inc() - LOGGER.info('SetKpi') - try: - # Here the code to create a sqlite query to crete a KPI and return a KpiID - response = KpiId() - - kpi_description = request.kpi_description - kpi_sample_type = request.kpi_sample_type - kpi_device_id = request.device_id.device_uuid.uuid - kpi_endpoint_id = request.endpoint_id.endpoint_uuid.uuid - kpi_service_id = request.service_id.service_uuid.uuid - kpi_slice_id = request.slice_id.slice_uuid.uuid - kpi_connection_id = request.connection_id.connection_uuid.uuid - - - if request.kpi_id.kpi_id.uuid != "": - response.kpi_id.uuid = request.kpi_id.kpi_id.uuid - # Here the code to modify an existing kpi - else: - data = self.management_db.insert_KPI( - kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id, kpi_slice_id, kpi_connection_id) - response.kpi_id.uuid = str(data) - - return response - except ServiceException as e: - LOGGER.exception('SetKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('SetKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) + response = KpiId() + kpi_description = request.kpi_description + kpi_sample_type = request.kpi_sample_type + kpi_device_id = request.device_id.device_uuid.uuid + kpi_endpoint_id = request.endpoint_id.endpoint_uuid.uuid + kpi_service_id = request.service_id.service_uuid.uuid + kpi_slice_id = request.slice_id.slice_uuid.uuid + kpi_connection_id = request.connection_id.connection_uuid.uuid + if request.kpi_id.kpi_id.uuid != "": + response.kpi_id.uuid = request.kpi_id.kpi_id.uuid + # Here the code to modify an existing kpi + else: + data = self.management_db.insert_KPI( + kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id, kpi_slice_id, + kpi_connection_id) + response.kpi_id.uuid = str(data) + return response + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def DeleteKpi(self, request: KpiId, grpc_context: grpc.ServicerContext) -> Empty: + kpi_id = int(request.kpi_id.uuid) + kpi = self.management_db.get_KPI(kpi_id) + if kpi: + self.management_db.delete_KPI(kpi_id) + else: + LOGGER.info('DeleteKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) + return Empty() - LOGGER.info('DeleteKpi') - try: - LOGGER.debug(f'DeleteKpi with KpiID: {request.kpi_id.uuid}') - kpi_id = int(request.kpi_id.uuid) - kpi = self.management_db.get_KPI(kpi_id) - if kpi: - self.management_db.delete_KPI(kpi_id) - else: - LOGGER.info('DeleteKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) - return Empty() - except ServiceException as e: - LOGGER.exception('DeleteKpi exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('DeleteKpi exception') - + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetKpiDescriptor(self, request: KpiId, grpc_context: grpc.ServicerContext) -> KpiDescriptor: - LOGGER.info('getting Kpi by KpiID') - try: - kpi_id = request.kpi_id.uuid - kpi_db = self.management_db.get_KPI(int(kpi_id)) - kpiDescriptor = KpiDescriptor() - if kpi_db is None: - LOGGER.info('GetKpiDescriptor error: KpiID({:s}): not found in database'.format(str(kpi_id))) - else: - kpiDescriptor.kpi_description = kpi_db[1] - kpiDescriptor.kpi_sample_type = kpi_db[2] - kpiDescriptor.device_id.device_uuid.uuid = str(kpi_db[3]) - kpiDescriptor.endpoint_id.endpoint_uuid.uuid = str(kpi_db[4]) - kpiDescriptor.service_id.service_uuid.uuid = str(kpi_db[5]) - kpiDescriptor.slice_id.slice_uuid.uuid = str(kpi_db[6]) - kpiDescriptor.connection_id.connection_uuid.uuid = str(kpi_db[7]) - return kpiDescriptor - except ServiceException as e: - LOGGER.exception('GetKpiDescriptor exception') - grpc_context.abort(e.code, e.details) - except Exception: # pragma: no cover - LOGGER.exception('GetKpiDescriptor exception') - + kpi_id = request.kpi_id.uuid + kpi_db = self.management_db.get_KPI(int(kpi_id)) + kpiDescriptor = KpiDescriptor() + if kpi_db is None: + LOGGER.info('GetKpiDescriptor error: KpiID({:s}): not found in database'.format(str(kpi_id))) + else: + kpiDescriptor.kpi_description = kpi_db[1] + kpiDescriptor.kpi_sample_type = kpi_db[2] + kpiDescriptor.device_id.device_uuid.uuid = str(kpi_db[3]) + kpiDescriptor.endpoint_id.endpoint_uuid.uuid = str(kpi_db[4]) + kpiDescriptor.service_id.service_uuid.uuid = str(kpi_db[5]) + kpiDescriptor.slice_id.slice_uuid.uuid = str(kpi_db[6]) + kpiDescriptor.connection_id.connection_uuid.uuid = str(kpi_db[7]) + return kpiDescriptor + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetKpiDescriptorList(self, request: Empty, grpc_context: grpc.ServicerContext) -> KpiDescriptorList: - - LOGGER.info('GetKpiDescriptorList') - try: - kpi_descriptor_list = KpiDescriptorList() - - data = self.management_db.get_KPIS() - LOGGER.debug(f"data: {data}") - - for item in data: - kpi_descriptor = KpiDescriptor() - kpi_descriptor.kpi_id.kpi_id.uuid = str(item[0]) - kpi_descriptor.kpi_description = item[1] - kpi_descriptor.kpi_sample_type = item[2] - kpi_descriptor.device_id.device_uuid.uuid = str(item[3]) - kpi_descriptor.endpoint_id.endpoint_uuid.uuid = str(item[4]) - kpi_descriptor.service_id.service_uuid.uuid = str(item[5]) - kpi_descriptor.slice_id.slice_uuid.uuid = str(item[6]) - kpi_descriptor.connection_id.connection_uuid.uuid = str(item[7]) - - kpi_descriptor_list.kpi_descriptor_list.append(kpi_descriptor) - - return kpi_descriptor_list - except ServiceException as e: - LOGGER.exception('GetKpiDescriptorList exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetKpiDescriptorList exception') - + kpi_descriptor_list = KpiDescriptorList() + data = self.management_db.get_KPIS() + LOGGER.debug(f"data: {data}") + for item in data: + kpi_descriptor = KpiDescriptor() + kpi_descriptor.kpi_id.kpi_id.uuid = str(item[0]) + kpi_descriptor.kpi_description = item[1] + kpi_descriptor.kpi_sample_type = item[2] + kpi_descriptor.device_id.device_uuid.uuid = str(item[3]) + kpi_descriptor.endpoint_id.endpoint_uuid.uuid = str(item[4]) + kpi_descriptor.service_id.service_uuid.uuid = str(item[5]) + kpi_descriptor.slice_id.slice_uuid.uuid = str(item[6]) + kpi_descriptor.connection_id.connection_uuid.uuid = str(item[7]) + kpi_descriptor_list.kpi_descriptor_list.append(kpi_descriptor) + return kpi_descriptor_list + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def IncludeKpi(self, request: Kpi, grpc_context: grpc.ServicerContext) -> Empty: + kpi_id = request.kpi_id.kpi_id.uuid + kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context) - LOGGER.info('IncludeKpi') - - try: - kpi_id = request.kpi_id.kpi_id.uuid + if kpiDescriptor is None: + LOGGER.info('IncludeKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) + else: + kpiSampleType = KpiSampleType.Name(kpiDescriptor.kpi_sample_type).upper().replace('KPISAMPLETYPE_', '') + kpiId = kpi_id + deviceId = kpiDescriptor.device_id.device_uuid.uuid + endpointId = kpiDescriptor.endpoint_id.endpoint_uuid.uuid + serviceId = kpiDescriptor.service_id.service_uuid.uuid + sliceId = kpiDescriptor.slice_id.slice_uuid.uuid + connectionId = kpiDescriptor.connection_id.connection_uuid.uuid + time_stamp = request.timestamp.timestamp + kpi_value = getattr(request.kpi_value, request.kpi_value.WhichOneof('value')) + + # Build the structure to be included as point in the MetricsDB + self.metrics_db.write_KPI(time_stamp, kpiId, kpiSampleType, deviceId, endpointId, serviceId, sliceId, connectionId, kpi_value) + return Empty() + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def MonitorKpi(self, request: MonitorKpiRequest, grpc_context: grpc.ServicerContext) -> Empty: + kpi_id = int(request.kpi_id.kpi_id.uuid) + kpi = self.management_db.get_KPI(kpi_id) + response = Empty() + if kpi: + # Sets the request to send to the device service + monitor_device_request = MonitoringSettings() kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context) + monitor_device_request.kpi_descriptor.CopyFrom(kpiDescriptor) + monitor_device_request.kpi_id.kpi_id.uuid = request.kpi_id.kpi_id.uuid + monitor_device_request.sampling_duration_s = request.monitoring_window_s + monitor_device_request.sampling_interval_s = request.sampling_rate_s + if not self.management_db.check_monitoring_flag(kpi_id): + device_client = DeviceClient() + device_client.MonitorDeviceKpi(monitor_device_request) + self.management_db.set_monitoring_flag(kpi_id,True) + self.management_db.check_monitoring_flag(kpi_id) + else: + LOGGER.warning('MonitorKpi warning: KpiID({:s}) is currently being monitored'.format(str(kpi_id))) + else: + LOGGER.info('MonitorKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) + return response + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def QueryKpiData(self, request: KpiQuery, grpc_context: grpc.ServicerContext) -> RawKpiTable: + raw_kpi_table = RawKpiTable() + kpi_id_list = request.kpi_ids + monitoring_window_s = request.monitoring_window_s + last_n_samples = request.last_n_samples + start_timestamp = request.start_timestamp.timestamp + end_timestamp = request.end_timestamp.timestamp + + # Check if all the Kpi_ids exist + for item in kpi_id_list: + kpi_id = item.kpi_id.uuid + kpiDescriptor = self.GetKpiDescriptor(item, grpc_context) if kpiDescriptor is None: - LOGGER.info('IncludeKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) + LOGGER.info('QueryKpiData error: KpiID({:s}): not found in database'.format(str(kpi_id))) + break else: - kpiSampleType = KpiSampleType.Name(kpiDescriptor.kpi_sample_type).upper().replace('KPISAMPLETYPE_', '') - kpiId = kpi_id - deviceId = kpiDescriptor.device_id.device_uuid.uuid - endpointId = kpiDescriptor.endpoint_id.endpoint_uuid.uuid - serviceId = kpiDescriptor.service_id.service_uuid.uuid - sliceId = kpiDescriptor.slice_id.slice_uuid.uuid - connectionId = kpiDescriptor.connection_id.connection_uuid.uuid - time_stamp = request.timestamp.timestamp - kpi_value = getattr(request.kpi_value, request.kpi_value.WhichOneof('value')) - - # Build the structure to be included as point in the MetricsDB - self.metrics_db.write_KPI(time_stamp, kpiId, kpiSampleType, deviceId, endpointId, serviceId, sliceId, connectionId, kpi_value) - - return Empty() - except ServiceException as e: - LOGGER.exception('IncludeKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - grpc_context.abort(e.code, e.details) - except Exception: # pragma: no cover - LOGGER.exception('IncludeKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - - def MonitorKpi(self, request: MonitorKpiRequest, grpc_context: grpc.ServicerContext) -> Empty: - - LOGGER.info('MonitorKpi') - try: - kpi_id = int(request.kpi_id.kpi_id.uuid) - kpi = self.management_db.get_KPI(kpi_id) - response = Empty() - - if kpi: - # Sets the request to send to the device service - monitor_device_request = MonitoringSettings() - - kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context) + # Execute query per Kpi_id and introduce their kpi_list in the table + kpi_list = self.metrics_db.get_raw_kpi_list(kpi_id,monitoring_window_s,last_n_samples,start_timestamp,end_timestamp) + raw_kpi_list = RawKpiList() + raw_kpi_list.kpi_id.kpi_id.uuid = kpi_id - monitor_device_request.kpi_descriptor.CopyFrom(kpiDescriptor) - monitor_device_request.kpi_id.kpi_id.uuid = request.kpi_id.kpi_id.uuid - monitor_device_request.sampling_duration_s = request.monitoring_window_s - monitor_device_request.sampling_interval_s = request.sampling_rate_s + LOGGER.debug(str(kpi_list)) - if not self.management_db.check_monitoring_flag(kpi_id): - device_client = DeviceClient() - device_client.MonitorDeviceKpi(monitor_device_request) - self.management_db.set_monitoring_flag(kpi_id,True) - self.management_db.check_monitoring_flag(kpi_id) + if kpi_list is None: + LOGGER.info('QueryKpiData error: KpiID({:s}): points not found in metrics database'.format(str(kpi_id))) else: - LOGGER.warning('MonitorKpi warning: KpiID({:s}) is currently being monitored'.format(str(kpi_id))) - else: - LOGGER.info('MonitorKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) - return response - except ServiceException as e: - LOGGER.exception('MonitorKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('MonitorKpi exception') - grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) - # CREATEKPI_COUNTER_FAILED.inc() + for item in kpi_list: + raw_kpi = RawKpi() + raw_kpi.timestamp.timestamp = timestamp_string_to_float(item[0]) + raw_kpi.kpi_value.floatVal = item[1] + raw_kpi_list.raw_kpis.append(raw_kpi) - def QueryKpiData(self, request: KpiQuery, grpc_context: grpc.ServicerContext) -> RawKpiTable: + raw_kpi_table.raw_kpi_lists.append(raw_kpi_list) + return raw_kpi_table - LOGGER.info('QueryKpiData') - try: - raw_kpi_table = RawKpiTable() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SetKpiSubscription(self, request: SubsDescriptor, grpc_context: grpc.ServicerContext) -> SubsResponse: + subs_queue = Queue() + + kpi_id = request.kpi_id.kpi_id.uuid + sampling_duration_s = request.sampling_duration_s + sampling_interval_s = request.sampling_interval_s + start_timestamp = request.start_timestamp.timestamp + end_timestamp = request.end_timestamp.timestamp + + subscriber = "localhost" # Investigate how to get info from the requester + + subs_id = self.management_db.insert_subscription(kpi_id, subscriber, sampling_duration_s, + sampling_interval_s, start_timestamp, end_timestamp) + self.subs_manager.create_subscription(subs_queue, subs_id, kpi_id, sampling_interval_s, sampling_duration_s, + start_timestamp, end_timestamp) + + # parse queue to append kpis into the list + while True: + while not subs_queue.empty(): + subs_response = SubsResponse() + list = subs_queue.get_nowait() + for item in list: + kpi = Kpi() + kpi.kpi_id.kpi_id.uuid = str(item[0]) + kpi.timestamp.timestamp = timestamp_string_to_float(item[1]) + kpi.kpi_value.floatVal = item[2] # This must be improved + subs_response.kpi_list.kpi.append(kpi) + subs_response.subs_id.subs_id.uuid = str(subs_id) + yield subs_response + if timestamp_utcnow_to_float() > end_timestamp: + break + # yield subs_response + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetSubsDescriptor(self, request: SubscriptionID, grpc_context: grpc.ServicerContext) -> SubsDescriptor: + subs_id = request.subs_id.uuid + subs_db = self.management_db.get_subscription(int(request.subs_id.uuid)) + response = SubsDescriptor() + if subs_db is None: + LOGGER.info('GetSubsDescriptor error: SubsID({:s}): not found in database'.format(str(subs_id))) + else: + LOGGER.debug(subs_db) + response.subs_id.subs_id.uuid = str(subs_db[0]) + response.kpi_id.kpi_id.uuid = str(subs_db[1]) + response.sampling_duration_s = subs_db[3] + response.sampling_interval_s = subs_db[4] + response.start_timestamp.timestamp = subs_db[5] + response.end_timestamp.timestamp = subs_db[6] + return response + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetSubscriptions(self, request: Empty, grpc_context: grpc.ServicerContext) -> SubsList: + response = SubsList() + data = self.management_db.get_subscriptions() + for subs_db in data: + subs_descriptor = SubsDescriptor() + subs_descriptor.subs_id.subs_id.uuid = str(subs_db[0]) + subs_descriptor.kpi_id.kpi_id.uuid = str(subs_db[1]) + subs_descriptor.sampling_duration_s = subs_db[3] + subs_descriptor.sampling_interval_s = subs_db[4] + subs_descriptor.start_timestamp.timestamp = subs_db[5] + subs_descriptor.end_timestamp.timestamp = subs_db[6] + response.subs_descriptor.append(subs_descriptor) + return response + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def DeleteSubscription(self, request: SubscriptionID, grpc_context: grpc.ServicerContext) -> Empty: + subs_id = int(request.subs_id.uuid) + subs_db = self.management_db.get_subscription(int(request.subs_id.uuid)) + if subs_db: + self.management_db.delete_subscription(subs_id) + else: + LOGGER.info('DeleteSubscription error: SubsID({:s}): not found in database'.format(str(subs_id))) + return Empty() - LOGGER.debug(str(request)) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SetKpiAlarm(self, request: AlarmDescriptor, grpc_context: grpc.ServicerContext) -> AlarmResponse: + response = AlarmID() + alarm_description = request.alarm_description + alarm_name = request.name + kpi_id = request.kpi_id.kpi_id.uuid + kpi_min_value = float(request.kpi_value_range.kpiMinValue.floatVal) + kpi_max_value = float(request.kpi_value_range.kpiMaxValue.floatVal) + in_range = request.kpi_value_range.inRange + include_min_value = request.kpi_value_range.includeMinValue + include_max_value = request.kpi_value_range.includeMaxValue + timestamp = request.timestamp.timestamp + LOGGER.debug(f"request.AlarmID: {request.alarm_id.alarm_id.uuid}") + if request.alarm_id.alarm_id.uuid != "": + alarm_id = request.alarm_id.alarm_id.uuid + # Here the code to modify an existing alarm + else: + alarm_id = self.management_db.insert_alarm(alarm_description, alarm_name, kpi_id, kpi_min_value, + kpi_max_value, + in_range, include_min_value, include_max_value) + LOGGER.debug(f"AlarmID: {alarm_id}") + response.alarm_id.uuid = str(alarm_id) + return response + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetAlarms(self, request: Empty, grpc_context: grpc.ServicerContext) -> AlarmList: + response = AlarmList() + data = self.management_db.get_alarms() - kpi_id_list = request.kpi_ids - monitoring_window_s = request.monitoring_window_s - last_n_samples = request.last_n_samples - start_timestamp = request.start_timestamp.timestamp - end_timestamp = request.end_timestamp.timestamp + for alarm in data: + alarm_descriptor = AlarmDescriptor() - # Check if all the Kpi_ids exist - for item in kpi_id_list: - kpi_id = item.kpi_id.uuid + alarm_descriptor.alarm_id.alarm_id.uuid = str(alarm[0]) + alarm_descriptor.alarm_description = alarm[1] + alarm_descriptor.name = alarm[2] + alarm_descriptor.kpi_id.kpi_id.uuid = str(alarm[3]) + alarm_descriptor.kpi_value_range.kpiMinValue.floatVal = alarm[4] + alarm_descriptor.kpi_value_range.kpiMaxValue.floatVal = alarm[5] + alarm_descriptor.kpi_value_range.inRange = bool(alarm[6]) + alarm_descriptor.kpi_value_range.includeMinValue = bool(alarm[7]) + alarm_descriptor.kpi_value_range.includeMaxValue = bool(alarm[8]) - kpiDescriptor = self.GetKpiDescriptor(item, grpc_context) - if kpiDescriptor is None: - LOGGER.info('QueryKpiData error: KpiID({:s}): not found in database'.format(str(kpi_id))) - break - else: - # Execute query per Kpi_id and introduce their kpi_list in the table - kpi_list = self.metrics_db.get_raw_kpi_list(kpi_id,monitoring_window_s,last_n_samples,start_timestamp,end_timestamp) - raw_kpi_list = RawKpiList() - raw_kpi_list.kpi_id.kpi_id.uuid = kpi_id - - LOGGER.debug(str(kpi_list)) - - if kpi_list is None: - LOGGER.info('QueryKpiData error: KpiID({:s}): points not found in metrics database'.format(str(kpi_id))) - else: - for item in kpi_list: - raw_kpi = RawKpi() - raw_kpi.timestamp.timestamp = timestamp_string_to_float(item[0]) - raw_kpi.kpi_value.floatVal = item[1] - raw_kpi_list.raw_kpis.append(raw_kpi) - - raw_kpi_table.raw_kpi_lists.append(raw_kpi_list) - - return raw_kpi_table - except ServiceException as e: - LOGGER.exception('QueryKpiData exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('QueryKpiData exception') + response.alarm_descriptor.append(alarm_descriptor) - def SetKpiSubscription(self, request: SubsDescriptor, grpc_context: grpc.ServicerContext) -> SubsResponse: + return response - LOGGER.info('SubscribeKpi') - try: - subs_queue = Queue() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetAlarmDescriptor(self, request: AlarmID, grpc_context: grpc.ServicerContext) -> AlarmDescriptor: + alarm_id = request.alarm_id.uuid + LOGGER.debug(alarm_id) + alarm = self.management_db.get_alarm(alarm_id) + response = AlarmDescriptor() + + if alarm: + LOGGER.debug(f"{alarm}") + response.alarm_id.alarm_id.uuid = str(alarm_id) + response.alarm_description = alarm[1] + response.name = alarm[2] + response.kpi_id.kpi_id.uuid = str(alarm[3]) + response.kpi_value_range.kpiMinValue.floatVal = alarm[4] + response.kpi_value_range.kpiMaxValue.floatVal = alarm[5] + response.kpi_value_range.inRange = bool(alarm[6]) + response.kpi_value_range.includeMinValue = bool(alarm[7]) + response.kpi_value_range.includeMaxValue = bool(alarm[8]) + else: + LOGGER.info('GetAlarmDescriptor error: AlarmID({:s}): not found in database'.format(str(alarm_id))) + response.alarm_id.alarm_id.uuid = "NoID" + return response + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetAlarmResponseStream( + self, request: AlarmSubscription, grpc_context: grpc.ServicerContext + ) -> Iterator[AlarmResponse]: + alarm_id = request.alarm_id.alarm_id.uuid + alarm_data = self.management_db.get_alarm(alarm_id) + real_start_time = timestamp_utcnow_to_float() + + if alarm_data: + LOGGER.debug(f"{alarm_data}") + alarm_queue = Queue() - kpi_id = request.kpi_id.kpi_id.uuid - sampling_duration_s = request.sampling_duration_s - sampling_interval_s = request.sampling_interval_s - start_timestamp = request.start_timestamp.timestamp - end_timestamp = request.end_timestamp.timestamp + alarm_id = request.alarm_id.alarm_id.uuid + kpi_id = alarm_data[3] + kpiMinValue = alarm_data[4] + kpiMaxValue = alarm_data[5] + inRange = alarm_data[6] + includeMinValue = alarm_data[7] + includeMaxValue = alarm_data[8] + subscription_frequency_ms = request.subscription_frequency_ms + subscription_timeout_s = request.subscription_timeout_s - subscriber = "localhost" # Investigate how to get info from the requester + end_timestamp = real_start_time + subscription_timeout_s - subs_id = self.management_db.insert_subscription(kpi_id, subscriber, sampling_duration_s, - sampling_interval_s, start_timestamp, end_timestamp) - self.subs_manager.create_subscription(subs_queue, subs_id, kpi_id, sampling_interval_s, sampling_duration_s, - start_timestamp, end_timestamp) + self.alarm_manager.create_alarm(alarm_queue, alarm_id, kpi_id, kpiMinValue, kpiMaxValue, inRange, + includeMinValue, includeMaxValue, subscription_frequency_ms, + subscription_timeout_s) - # parse queue to append kpis into the list while True: - while not subs_queue.empty(): - subs_response = SubsResponse() - list = subs_queue.get_nowait() + while not alarm_queue.empty(): + alarm_response = AlarmResponse() + list = alarm_queue.get_nowait() + size = len(list) for item in list: kpi = Kpi() kpi.kpi_id.kpi_id.uuid = str(item[0]) kpi.timestamp.timestamp = timestamp_string_to_float(item[1]) kpi.kpi_value.floatVal = item[2] # This must be improved - subs_response.kpi_list.kpi.append(kpi) - subs_response.subs_id.subs_id.uuid = str(subs_id) - yield subs_response + alarm_response.kpi_list.kpi.append(kpi) + alarm_response.alarm_id.alarm_id.uuid = alarm_id + yield alarm_response if timestamp_utcnow_to_float() > end_timestamp: break - # yield subs_response - except ServiceException as e: - LOGGER.exception('SubscribeKpi exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('SubscribeKpi exception') - - def GetSubsDescriptor(self, request: SubscriptionID, grpc_context: grpc.ServicerContext) -> SubsDescriptor: - - LOGGER.info('GetSubsDescriptor') - try: - subs_id = request.subs_id.uuid - subs_db = self.management_db.get_subscription(int(request.subs_id.uuid)) - response = SubsDescriptor() - if subs_db is None: - LOGGER.info('GetSubsDescriptor error: SubsID({:s}): not found in database'.format(str(subs_id))) - else: - LOGGER.debug(subs_db) - response.subs_id.subs_id.uuid = str(subs_db[0]) - response.kpi_id.kpi_id.uuid = str(subs_db[1]) - response.sampling_duration_s = subs_db[3] - response.sampling_interval_s = subs_db[4] - response.start_timestamp.timestamp = subs_db[5] - response.end_timestamp.timestamp = subs_db[6] - - return response - except ServiceException as e: - LOGGER.exception('GetSubsDescriptor exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetSubsDescriptor exception') - - def GetSubscriptions(self, request: Empty, grpc_context: grpc.ServicerContext) -> SubsList: - - LOGGER.info('GetSubscriptions') - try: - response = SubsList() - data = self.management_db.get_subscriptions() - - for subs_db in data: - subs_descriptor = SubsDescriptor() - - subs_descriptor.subs_id.subs_id.uuid = str(subs_db[0]) - subs_descriptor.kpi_id.kpi_id.uuid = str(subs_db[1]) - subs_descriptor.sampling_duration_s = subs_db[3] - subs_descriptor.sampling_interval_s = subs_db[4] - subs_descriptor.start_timestamp.timestamp = subs_db[5] - subs_descriptor.end_timestamp.timestamp = subs_db[6] - - response.subs_descriptor.append(subs_descriptor) - - return response - except ServiceException as e: - LOGGER.exception('GetSubscriptions exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetSubscriptions exception') - - def DeleteSubscription(self, request: SubscriptionID, grpc_context: grpc.ServicerContext) -> Empty: - - LOGGER.info('DeleteSubscription') - try: - LOGGER.debug(f'DeleteSubscription with SubsID: {request.subs_id.uuid}') - subs_id = int(request.subs_id.uuid) - subs_db = self.management_db.get_subscription(int(request.subs_id.uuid)) - if subs_db: - self.management_db.delete_subscription(subs_id) - else: - LOGGER.info('DeleteSubscription error: SubsID({:s}): not found in database'.format(str(subs_id))) - return Empty() - except ServiceException as e: - LOGGER.exception('DeleteSubscription exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('DeleteSubscription exception') - - def SetKpiAlarm(self, request: AlarmDescriptor, grpc_context: grpc.ServicerContext) -> AlarmResponse: - - LOGGER.info('SetKpiAlarm') - try: - response = AlarmID() - - alarm_description = request.alarm_description - alarm_name = request.name - kpi_id = request.kpi_id.kpi_id.uuid - kpi_min_value = request.kpi_value_range.kpiMinValue.floatVal - kpi_max_value = request.kpi_value_range.kpiMaxValue.floatVal - in_range = request.kpi_value_range.inRange - include_min_value = request.kpi_value_range.includeMinValue - include_max_value = request.kpi_value_range.includeMaxValue - timestamp = request.timestamp.timestamp - - LOGGER.debug(f"request.AlarmID: {request.alarm_id.alarm_id.uuid}") - - if request.alarm_id.alarm_id.uuid != "": - alarm_id = request.alarm_id.alarm_id.uuid - # Here the code to modify an existing alarm - else: - alarm_id = self.management_db.insert_alarm(alarm_description, alarm_name, kpi_id, kpi_min_value, - kpi_max_value, - in_range, include_min_value, include_max_value) - LOGGER.debug(f"AlarmID: {alarm_id}") - response.alarm_id.uuid = str(alarm_id) - - return response - except ServiceException as e: - LOGGER.exception('SetKpiAlarm exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('SetKpiAlarm exception') - - def GetAlarms(self, request: Empty, grpc_context: grpc.ServicerContext) -> AlarmList: - - LOGGER.info('GetAlarms') - try: - response = AlarmList() - data = self.management_db.get_alarms() - - for alarm in data: - alarm_descriptor = AlarmDescriptor() - - alarm_descriptor.alarm_id.alarm_id.uuid = str(alarm[0]) - alarm_descriptor.alarm_description = alarm[1] - alarm_descriptor.name = alarm[2] - alarm_descriptor.kpi_id.kpi_id.uuid = str(alarm[3]) - alarm_descriptor.kpi_value_range.kpiMinValue.floatVal = alarm[4] - alarm_descriptor.kpi_value_range.kpiMaxValue.floatVal = alarm[5] - alarm_descriptor.kpi_value_range.inRange = bool(alarm[6]) - alarm_descriptor.kpi_value_range.includeMinValue = bool(alarm[7]) - alarm_descriptor.kpi_value_range.includeMaxValue = bool(alarm[8]) - - response.alarm_descriptor.append(alarm_descriptor) - - return response - except ServiceException as e: - LOGGER.exception('GetAlarms exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetAlarms exception') - - def GetAlarmDescriptor(self, request: AlarmID, grpc_context: grpc.ServicerContext) -> AlarmDescriptor: - - LOGGER.info('GetAlarmDescriptor') - try: - alarm_id = request.alarm_id.uuid - LOGGER.debug(alarm_id) - alarm = self.management_db.get_alarm(alarm_id) - response = AlarmDescriptor() - - if alarm: - LOGGER.debug(f"{alarm}") - response.alarm_id.alarm_id.uuid = str(alarm_id) - response.alarm_description = alarm[1] - response.name = alarm[2] - response.kpi_id.kpi_id.uuid = str(alarm[3]) - response.kpi_value_range.kpiMinValue.floatVal = alarm[4] - response.kpi_value_range.kpiMaxValue.floatVal = alarm[5] - response.kpi_value_range.inRange = bool(alarm[6]) - response.kpi_value_range.includeMinValue = bool(alarm[7]) - response.kpi_value_range.includeMaxValue = bool(alarm[8]) - else: - LOGGER.info('GetAlarmDescriptor error: AlarmID({:s}): not found in database'.format(str(alarm_id))) - response.alarm_id.alarm_id.uuid = "NoID" - return response - except ServiceException as e: - LOGGER.exception('GetAlarmDescriptor exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetAlarmDescriptor exception') - - def GetAlarmResponseStream(self, request: AlarmSubscription, grpc_context: grpc.ServicerContext) -> Iterator[ - AlarmResponse]: - - LOGGER.info('GetAlarmResponseStream') - try: - alarm_id = request.alarm_id.alarm_id.uuid - alarm_data = self.management_db.get_alarm(alarm_id) - real_start_time = timestamp_utcnow_to_float() - - if alarm_data: - LOGGER.debug(f"{alarm_data}") - alarm_queue = Queue() - - alarm_id = request.alarm_id.alarm_id.uuid - kpi_id = alarm_data[3] - kpiMinValue = alarm_data[4] - kpiMaxValue = alarm_data[5] - inRange = alarm_data[6] - includeMinValue = alarm_data[7] - includeMaxValue = alarm_data[8] - subscription_frequency_ms = request.subscription_frequency_ms - subscription_timeout_s = request.subscription_timeout_s - - end_timestamp = real_start_time + subscription_timeout_s - - self.alarm_manager.create_alarm(alarm_queue, alarm_id, kpi_id, kpiMinValue, kpiMaxValue, inRange, - includeMinValue, includeMaxValue, subscription_frequency_ms, - subscription_timeout_s) - - while True: - while not alarm_queue.empty(): - alarm_response = AlarmResponse() - list = alarm_queue.get_nowait() - size = len(list) - for item in list: - kpi = Kpi() - kpi.kpi_id.kpi_id.uuid = str(item[0]) - kpi.timestamp.timestamp = timestamp_string_to_float(item[1]) - kpi.kpi_value.floatVal = item[2] # This must be improved - alarm_response.kpi_list.kpi.append(kpi) - alarm_response.alarm_id.alarm_id.uuid = alarm_id - yield alarm_response - if timestamp_utcnow_to_float() > end_timestamp: - break - else: - LOGGER.info('GetAlarmResponseStream error: AlarmID({:s}): not found in database'.format(str(alarm_id))) - alarm_response = AlarmResponse() - alarm_response.alarm_id.alarm_id.uuid = "NoID" - return alarm_response - except ServiceException as e: - LOGGER.exception('GetAlarmResponseStream exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetAlarmResponseStream exception') + else: + LOGGER.info('GetAlarmResponseStream error: AlarmID({:s}): not found in database'.format(str(alarm_id))) + alarm_response = AlarmResponse() + alarm_response.alarm_id.alarm_id.uuid = "NoID" + return alarm_response + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def DeleteAlarm(self, request: AlarmID, grpc_context: grpc.ServicerContext) -> Empty: + alarm_id = int(request.alarm_id.uuid) + alarm = self.management_db.get_alarm(alarm_id) + response = Empty() + if alarm: + self.alarm_manager.delete_alarm(alarm_id) + self.management_db.delete_alarm(alarm_id) + else: + LOGGER.info('DeleteAlarm error: AlarmID({:s}): not found in database'.format(str(alarm_id))) + return response - LOGGER.info('DeleteAlarm') - try: - LOGGER.debug(f'DeleteAlarm with AlarmID: {request.alarm_id.uuid}') - alarm_id = int(request.alarm_id.uuid) - alarm = self.management_db.get_alarm(alarm_id) - response = Empty() - if alarm: - self.alarm_manager.delete_alarm(alarm_id) - self.management_db.delete_alarm(alarm_id) - else: - LOGGER.info('DeleteAlarm error: AlarmID({:s}): not found in database'.format(str(alarm_id))) - return response - except ServiceException as e: - LOGGER.exception('DeleteAlarm exception') - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('DeleteAlarm exception') - + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetStreamKpi(self, request: KpiId, grpc_context: grpc.ServicerContext) -> Iterator[Kpi]: - - LOGGER.info('GetStreamKpi') - kpi_id = request.kpi_id.uuid kpi_db = self.management_db.get_KPI(int(kpi_id)) response = Kpi() @@ -581,36 +420,23 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer): else: yield response - @MONITORING_GETINSTANTKPI_REQUEST_TIME.time() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetInstantKpi(self, request: KpiId, grpc_context: grpc.ServicerContext) -> Kpi: - - LOGGER.info('GetInstantKpi') - try: - kpi_id = request.kpi_id.uuid - response = Kpi() - if kpi_id == "": - LOGGER.info('GetInstantKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) - response.kpi_id.kpi_id.uuid = "NoID" + kpi_id = request.kpi_id.uuid + response = Kpi() + if kpi_id == "": + LOGGER.info('GetInstantKpi error: KpiID({:s}): not found in database'.format(str(kpi_id))) + response.kpi_id.kpi_id.uuid = "NoID" + else: + query = f"SELECT kpi_id, timestamp, kpi_value FROM {METRICSDB_TABLE_MONITORING_KPIS} " \ + f"WHERE kpi_id = '{kpi_id}' LATEST ON timestamp PARTITION BY kpi_id" + data = self.metrics_db.run_query(query) + LOGGER.debug(data) + if len(data) == 0: + response.kpi_id.kpi_id.uuid = request.kpi_id.uuid else: - query = f"SELECT kpi_id, timestamp, kpi_value FROM {METRICSDB_TABLE_MONITORING_KPIS} " \ - f"WHERE kpi_id = '{kpi_id}' LATEST ON timestamp PARTITION BY kpi_id" - data = self.metrics_db.run_query(query) - LOGGER.debug(data) - if len(data) == 0: - response.kpi_id.kpi_id.uuid = request.kpi_id.uuid - else: - _data = data[0] - response.kpi_id.kpi_id.uuid = str(_data[0]) - response.timestamp.timestamp = timestamp_string_to_float(_data[1]) - response.kpi_value.floatVal = _data[2] - - return response - except ServiceException as e: - LOGGER.exception('GetInstantKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - grpc_context.abort(e.code, e.details) - except Exception as e: # pragma: no cover - LOGGER.exception('GetInstantKpi exception') - # CREATEKPI_COUNTER_FAILED.inc() - grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) - + _data = data[0] + response.kpi_id.kpi_id.uuid = str(_data[0]) + response.timestamp.timestamp = timestamp_string_to_float(_data[1]) + response.kpi_value.floatVal = _data[2] + return response diff --git a/src/monitoring/service/__main__.py b/src/monitoring/service/__main__.py index 14f5609602c90eb9f54462e423af100997cf00d2..d0a132c70bed2c56bc9159ec3ad284120c0eb623 100644 --- a/src/monitoring/service/__main__.py +++ b/src/monitoring/service/__main__.py @@ -91,7 +91,7 @@ def main(): start_monitoring(name_mapping) # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py index c883f9d141fc28645761641b0ccd10294b538bd2..4e84431a5438e1536c92ca644bd5005deba545a4 100644 --- a/src/monitoring/tests/test_unitary.py +++ b/src/monitoring/tests/test_unitary.py @@ -25,7 +25,6 @@ from grpc._channel import _MultiThreadedRendezvous from common.Constants import ServiceNameEnum from common.Settings import ( ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc) -#from common.logger import getJSONLogger from common.proto.context_pb2 import DeviceOperationalStatusEnum, EventTypeEnum, DeviceEvent, Device, Empty from common.proto.context_pb2_grpc import add_ContextServiceServicer_to_server from common.proto.kpi_sample_types_pb2 import KpiSampleType diff --git a/src/opticalattackdetector/.gitlab-ci.yml b/src/opticalattackdetector/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..b06725852a573a41b0cf97dd0bdfa527847fe6fc --- /dev/null +++ b/src/opticalattackdetector/.gitlab-ci.yml @@ -0,0 +1,103 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 registry +build opticalattackdetector: + variables: + IMAGE_NAME: 'opticalattackdetector' # 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 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/$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 + +# apply unit test to the opticalattackdetector component +unit_test opticalattackdetector: + variables: + IMAGE_NAME: 'opticalattackdetector' # name of the microservice + IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) + stage: unit_test + needs: + - build opticalattackdetector + 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 10006:10006 --env-file "$PWD/src/$IMAGE_NAME/.env" -v "$PWD/src/$IMAGE_NAME/tests:/home/${IMAGE_NAME}/results" --network=teraflowbridge --rm $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 -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/home/${IMAGE_NAME}/results/${IMAGE_NAME}_report.xml; coverage xml -o /home/${IMAGE_NAME}/results/${IMAGE_NAME}_coverage.xml; 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/$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 opticalattackdetector service in Kubernetes Cluster +# deploy opticalattackdetector: +# variables: +# IMAGE_NAME: 'opticalattackdetector' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test opticalattackdetector +# # - 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 \ No newline at end of file diff --git a/src/opticalattackdetector/Config.py b/src/opticalattackdetector/Config.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackdetector/Config.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackdetector/Dockerfile b/src/opticalattackdetector/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..fd903a616395617fbbe312b5fca8303966fc6053 --- /dev/null +++ b/src/opticalattackdetector/Dockerfile @@ -0,0 +1,88 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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++ && \ + rm -rf /var/lib/apt/lists/* + +# Set Python to show logs as they occur +ENV PYTHONUNBUFFERED=0 +ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + +# Download the gRPC health probe +RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ + wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ + chmod +x /bin/grpc_health_probe + +# Creating a user for security reasons +RUN groupadd -r teraflow && useradd -u 1001 --no-log-init -r -m -g teraflow teraflow +USER teraflow + +# set working directory +RUN mkdir -p /home/teraflow/controller/common/ +WORKDIR /home/teraflow/controller + +# Get Python packages per module +ENV VIRTUAL_ENV=/home/teraflow/venv +RUN python3 -m venv ${VIRTUAL_ENV} +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" + +# 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 +COPY --chown=teraflow:teraflow 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 /home/teraflow/controller/common +COPY --chown=teraflow:teraflow src/common/. ./ +RUN rm -rf proto + +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /home/teraflow/controller/common/proto +WORKDIR /home/teraflow/controller/common/proto +RUN touch __init__.py +COPY --chown=teraflow:teraflow 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 module sub-folders +RUN mkdir -p /home/teraflow/controller/opticalattackdetector +WORKDIR /home/teraflow/controller + +# Get Python packages per module +COPY --chown=teraflow:teraflow ./src/opticalattackdetector/requirements.in opticalattackdetector/requirements.in +# consider common and specific requirements to avoid inconsistencies with dependencies +RUN pip-compile --quiet --output-file=opticalattackdetector/requirements.txt opticalattackdetector/requirements.in common_requirements.in +RUN python3 -m pip install -r opticalattackdetector/requirements.txt + +# Add component files into working directory +COPY --chown=teraflow:teraflow ./src/context/. context +COPY --chown=teraflow:teraflow ./src/service/. service +COPY --chown=teraflow:teraflow ./src/monitoring/. monitoring +COPY --chown=teraflow:teraflow ./src/dbscanserving/. dbscanserving +COPY --chown=teraflow:teraflow ./src/opticalattackmitigator/. opticalattackmitigator +COPY --chown=teraflow:teraflow ./src/opticalattackdetector/. opticalattackdetector + +# Start the service +ENTRYPOINT ["python", "-m", "opticalattackdetector.service"] diff --git a/src/opticalattackdetector/__init__.py b/src/opticalattackdetector/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackdetector/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackdetector/client/OpticalAttackDetectorClient.py b/src/opticalattackdetector/client/OpticalAttackDetectorClient.py new file mode 100644 index 0000000000000000000000000000000000000000..3b95227ade65cdfb4a47830dee461c57bfc7dbfb --- /dev/null +++ b/src/opticalattackdetector/client/OpticalAttackDetectorClient.py @@ -0,0 +1,69 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 + +import grpc + +from common.Constants import ServiceNameEnum +from common.proto.context_pb2 import Empty +from common.proto.optical_attack_detector_pb2_grpc import \ + OpticalAttackDetectorServiceStub +from common.Settings import get_service_host, get_service_port_grpc +from common.tools.client.RetryDecorator import delay_exponential, retry +from common.tools.grpc.Tools import grpc_message_to_json + +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 OpticalAttackDetectorClient: + def __init__(self, host=None, port=None): + if not host: + host = get_service_host(ServiceNameEnum.OPTICALATTACKDETECTOR) + if not port: + port = get_service_port_grpc(ServiceNameEnum.OPTICALATTACKDETECTOR) + 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.connect() + LOGGER.debug("Channel created") + + def connect(self): + self.channel = grpc.insecure_channel(self.endpoint) + self.stub = OpticalAttackDetectorServiceStub(self.channel) + + def close(self): + if self.channel is not None: + self.channel.close() + self.channel = None + self.stub = None + + @RETRY_DECORATOR + def DetectAttack(self, request: Empty) -> Empty: + LOGGER.debug( + "DetectAttack request: {:s}".format(str(grpc_message_to_json(request))) + ) + response = self.stub.DetectAttack(request) + LOGGER.debug( + "DetectAttack result: {:s}".format(str(grpc_message_to_json(response))) + ) + return response diff --git a/src/opticalattackdetector/client/__init__.py b/src/opticalattackdetector/client/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackdetector/client/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalcentralizedattackdetector/requirements.in b/src/opticalattackdetector/requirements.in similarity index 81% rename from src/opticalcentralizedattackdetector/requirements.in rename to src/opticalattackdetector/requirements.in index 378e9a10a70f6a41a264c6a76f47239d7515989a..b69d4dd786500686fef4e04fd5b6096d5648cfc6 100644 --- a/src/opticalcentralizedattackdetector/requirements.in +++ b/src/opticalattackdetector/requirements.in @@ -12,13 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -grpcio-health-checking -grpcio -prometheus-client -pytest -pytest-benchmark +numpy redis -# from the monitoring component -influxdb -python-json-logger -coverage diff --git a/src/opticalattackdetector/service/OpticalAttackDetectorService.py b/src/opticalattackdetector/service/OpticalAttackDetectorService.py new file mode 100644 index 0000000000000000000000000000000000000000..2128d79b4dcdaf4fa0f12cd1fd96ba56669d48f9 --- /dev/null +++ b/src/opticalattackdetector/service/OpticalAttackDetectorService.py @@ -0,0 +1,38 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 + +from common.Constants import ServiceNameEnum +from common.proto.optical_attack_detector_pb2_grpc import \ + add_OpticalAttackDetectorServiceServicer_to_server +from common.Settings import get_service_port_grpc +from common.tools.service.GenericGrpcService import GenericGrpcService + +from opticalattackdetector.service.OpticalAttackDetectorServiceServicerImpl import \ + OpticalAttackDetectorServiceServicerImpl + +LOGGER = logging.getLogger(__name__) + + +class OpticalAttackDetectorService(GenericGrpcService): + def __init__(self, cls_name: str = __name__): + port = get_service_port_grpc(ServiceNameEnum.OPTICALATTACKDETECTOR) + super().__init__(port, cls_name=cls_name) + self.opticalattackdetector_servicer = OpticalAttackDetectorServiceServicerImpl() + + def install_servicers(self): + add_OpticalAttackDetectorServiceServicer_to_server( + self.opticalattackdetector_servicer, self.server + ) diff --git a/src/opticalattackdetector/service/OpticalAttackDetectorServiceServicerImpl.py b/src/opticalattackdetector/service/OpticalAttackDetectorServiceServicerImpl.py new file mode 100644 index 0000000000000000000000000000000000000000..11016037ee36f3b63726f7cc9fe398609c4f451b --- /dev/null +++ b/src/opticalattackdetector/service/OpticalAttackDetectorServiceServicerImpl.py @@ -0,0 +1,232 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 +import pickle +import random + +import grpc +import numpy as np +import redis +from prometheus_client import Histogram + +from common.Constants import ServiceNameEnum +from common.method_wrappers.Decorator import (MetricsPool, MetricTypeEnum, + safe_and_metered_rpc_method) +from common.proto import dbscanserving_pb2 as dbscan +from common.proto import optical_attack_detector_pb2 as oad +from common.proto.context_pb2 import Empty +from common.proto.monitoring_pb2 import Kpi +from common.proto.optical_attack_detector_pb2_grpc import \ + OpticalAttackDetectorServiceServicer +from common.proto.optical_attack_mitigator_pb2 import (AttackDescription, + AttackResponse) +from common.Settings import get_service_host, get_setting +from common.tools.timestamp.Converters import timestamp_utcnow_to_float +from dbscanserving.client.DbscanServingClient import DbscanServingClient +from monitoring.client.MonitoringClient import MonitoringClient +from opticalattackmitigator.client.OpticalAttackMitigatorClient import \ + OpticalAttackMitigatorClient + +LOGGER = logging.getLogger(__name__) + +METRICS_POOL = MetricsPool("OpticalAttackDetector", "RPC") + +METRICS_POOL_DETAILS = MetricsPool( + "OpticalAttackDetector", + "execution", + labels={ + "operation": "", + "step": "", + }, +) + +METRIC_LABELS = dict(operation="detect") +HISTOGRAM_DURATION: Histogram = METRICS_POOL_DETAILS.get_or_create( + "details", MetricTypeEnum.HISTOGRAM_DURATION +) + +monitoring_client: MonitoringClient = MonitoringClient() +dbscanserving_client: DbscanServingClient = DbscanServingClient() +attack_mitigator_client: OpticalAttackMitigatorClient = OpticalAttackMitigatorClient() + +redis_host = get_service_host(ServiceNameEnum.CACHING) +r = None +if redis_host is not None: + redis_port = int(get_setting("CACHINGSERVICE_SERVICE_PORT_REDIS", default=6379)) + redis_password = get_setting("REDIS_PASSWORD") + + r = redis.Redis(host=redis_host, port=redis_port, password=redis_password) + r.ping() + +# detecting preloading of the stats +path = get_setting("PATH_OPM_INFORMATION_SUMMARY", default=None) +if path is not None and len(path) > 0: + with open(path, "rb") as file: + opm_information_stats = pickle.load(file) + LOGGER.info("Using provided dataset: {}".format(path)) +else: + opm_information_stats = None + +WAD_WINDOW = 20 +WAD_SAMPLES = 9 + + +class OpticalAttackDetectorServiceServicerImpl(OpticalAttackDetectorServiceServicer): + def __init__(self): + LOGGER.debug("Creating Servicer...") + LOGGER.debug("Servicer Created") + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def DetectAttack( + self, request: oad.DetectionRequest, context: grpc.ServicerContext + ) -> Empty: + + s_uuid = request.service_id.service_uuid.uuid + + # detect if specific configuration is required + # to set the variable on the fly, try: + # https://stackoverflow.com/questions/45050050/can-i-modify-containers-environment-variables-without-restarting-pod-using-kube + _temp = r.get("CLASS_SERVICE_{}".format(s_uuid.replace("-", "_"))) + if _temp is not None and len(_temp) > 0: + _class = int(_temp) + else: # if not, assume no attack is present + _class = 0 + LOGGER.debug("Using class {} for service {}".format(_class, s_uuid)) + + _temp = r.get("PREVIOUS_CLASS_SERVICE_{}".format(s_uuid.replace("-", "_"))) + if _temp is not None and int(_temp) != 0 and _class == 0: + # if value changed to no-attack + # reset the experiment + r.delete("opm_{}".format(s_uuid.replace("-", "_"))) + r.set("PREVIOUS_CLASS_SERVICE_{}".format(s_uuid.replace("-", "_")), _class) + + # code used to validate resiliency against failures and timeouts + # if random.random() > 0.5: + # time.sleep(10) + + # run attack detection for every service + detection_request: dbscan.DetectionRequest = dbscan.DetectionRequest() + detection_request.num_samples = 310 + detection_request.num_features = 11 + + # checking if we have enough samples already for this service + length = r.llen("opm_{}".format(s_uuid.replace("-", "_"))) + if length < detection_request.num_samples: + # if the number of samples is not sufficient, + # we insert new samples + for _ in range(detection_request.num_samples - length): + detection_sample = [] + if opm_information_stats is not None: + for col in range(1, len(opm_information_stats.columns), 2): + name = opm_information_stats.columns[col][0] + # [result.columns[x][0] for x in range(1, len(result.columns), 2)] + detection_sample.append( + np.random.normal( + loc=opm_information_stats[name]["mean"][_class], + scale=opm_information_stats[name]["std"][_class], + ) + ) + else: + for __ in range(detection_request.num_features): + detection_sample.append(random.uniform(0.0, 10.0)) + # push the sample into the list + r.rpush( + "opm_{}".format(s_uuid.replace("-", "_")), + pickle.dumps(tuple(detection_sample)), + ) + + # remove the oldest sample from the list + r.lpop("opm_{}".format(s_uuid.replace("-", "_"))) + + # generate the latest sample + detection_sample = [] + if opm_information_stats is not None: + + for col in range(1, len(opm_information_stats.columns), 2): + name = opm_information_stats.columns[col][0] + # [result.columns[x][0] for x in range(1, len(result.columns), 2)] + detection_sample.append( + np.random.normal( + loc=opm_information_stats[name]["mean"][_class], + scale=opm_information_stats[name]["std"][_class], + ) + ) + + # generate data based on the stats based on the configuration of + # https://dx.doi.org/10.1109/JLT.2020.2987032 + detection_request.eps = 1.0 + detection_request.min_samples = 5 + else: + detection_request.eps = 100.5 + detection_request.min_samples = 5 + + if _class == 0: + for __ in range(detection_request.num_features): + detection_sample.append(random.uniform(0.0, 10.0)) + else: # if not, assume no attack is present + for __ in range(detection_request.num_features): + detection_sample.append(random.uniform(5000.0, 6000.0)) + + # adding the sample to the cache and recovering the cache + with HISTOGRAM_DURATION.labels(step="cachefetch", **METRIC_LABELS).time(): + r.rpush( + "opm_{}".format(s_uuid.replace("-", "_")), + pickle.dumps(tuple(detection_sample)), + ) + cached_samples = r.lrange("opm_{}".format(s_uuid.replace("-", "_")), 0, -1) + LOGGER.info( + "Recovered {} samples from the cache".format(len(cached_samples)) + ) + + for raw_sample in cached_samples: + sample = pickle.loads(raw_sample) + detection_sample = dbscan.Sample() + for feature in sample: + detection_sample.features.append(feature) + detection_request.samples.append(detection_sample) + + with HISTOGRAM_DURATION.labels(step="uldetection", **METRIC_LABELS).time(): + response: dbscan.DetectionResponse = dbscanserving_client.Detect( + detection_request + ) + + # including KPI + kpi = Kpi() + kpi.kpi_id.kpi_id.uuid = request.kpi_id.kpi_id.uuid + kpi.timestamp.timestamp = timestamp_utcnow_to_float() + # implementing WAD from https://ieeexplore.ieee.org/abstract/document/9064530 + if response.cluster_indices[-WAD_WINDOW:].count(-1) >= WAD_SAMPLES: + kpi.kpi_value.int32Val = 1 + LOGGER.info( + "Attack detected for service {}".format( + request.service_id.service_uuid.uuid + ) + ) + else: + kpi.kpi_value.int32Val = 0 + + with HISTOGRAM_DURATION.labels(step="includekpi", **METRIC_LABELS).time(): + monitoring_client.IncludeKpi(kpi) + + # if -1 in response.cluster_indices: # attack detected + if kpi.kpi_value.int32Val == -1: + attack = AttackDescription() + attack.cs_id.uuid = request.service_id.service_uuid.uuid + with HISTOGRAM_DURATION.labels(step="mitigation", **METRIC_LABELS).time(): + # with MITIGATION_RESPONSE_TIME.time(): + response: AttackResponse = attack_mitigator_client.NotifyAttack(attack) + + # if attack is detected, run the attack mitigator + return Empty() diff --git a/src/opticalattackdetector/service/__init__.py b/src/opticalattackdetector/service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackdetector/service/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackdetector/service/__main__.py b/src/opticalattackdetector/service/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..27706fce44d9635fcdaf1cc64a2dfb6292fc7833 --- /dev/null +++ b/src/opticalattackdetector/service/__main__.py @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 +import signal +import sys +import 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 opticalattackdetector.client.OpticalAttackDetectorClient import \ + OpticalAttackDetectorClient +from opticalattackdetector.service.OpticalAttackDetectorService import \ + OpticalAttackDetectorService + +terminate = threading.Event() +LOGGER = None + +client: OpticalAttackDetectorClient = 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) + LOGGER = logging.getLogger(__name__) + + wait_for_environment_variables( + [ + get_env_var_name(ServiceNameEnum.DBSCANSERVING, ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name( + ServiceNameEnum.DBSCANSERVING, ENVVAR_SUFIX_SERVICE_PORT_GRPC + ), + get_env_var_name( + ServiceNameEnum.OPTICALATTACKMITIGATOR, ENVVAR_SUFIX_SERVICE_HOST + ), + get_env_var_name( + ServiceNameEnum.OPTICALATTACKMITIGATOR, 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) + + # Starting CentralizedCybersecurity service + grpc_service = OpticalAttackDetectorService() + grpc_service.start() + + # Wait for Ctrl+C or termination signal + while not terminate.wait(timeout=1): + pass + + LOGGER.info("Terminating...") + grpc_service.stop() + + LOGGER.info("Bye") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/opticalattackdetector/tests/__init__.py b/src/opticalattackdetector/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackdetector/tests/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackdetector/tests/example_objects.py b/src/opticalattackdetector/tests/example_objects.py new file mode 100644 index 0000000000000000000000000000000000000000..aa9b7b82c5e4d9d4d4158bd0a01e6843cfe88872 --- /dev/null +++ b/src/opticalattackdetector/tests/example_objects.py @@ -0,0 +1,247 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 copy import deepcopy + +from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.proto.context_pb2 import (ConfigActionEnum, DeviceDriverEnum, + DeviceOperationalStatusEnum, + ServiceStatusEnum, ServiceTypeEnum) + +# Some example objects to be used by the tests + +# Helper methods +def config_rule(action, resource_value): + return {"action": action, "resource_value": resource_value} + + +def endpoint_id(topology_id, device_id, endpoint_uuid): + return { + "topology_id": deepcopy(topology_id), + "device_id": deepcopy(device_id), + "endpoint_uuid": {"uuid": endpoint_uuid}, + } + + +def endpoint(topology_id, device_id, endpoint_uuid, endpoint_type): + return { + "endpoint_id": endpoint_id(topology_id, device_id, endpoint_uuid), + "endpoint_type": endpoint_type, + } + + +# use "deepcopy" to prevent propagating forced changes during tests +CONTEXT_ID = {"context_uuid": {"uuid": DEFAULT_CONTEXT_UUID}} +CONTEXT = { + "context_id": deepcopy(CONTEXT_ID), + "topology_ids": [], + "service_ids": [], +} + +CONTEXT_ID_2 = {"context_uuid": {"uuid": "test"}} +CONTEXT_2 = { + "context_id": deepcopy(CONTEXT_ID_2), + "topology_ids": [], + "service_ids": [], +} + +TOPOLOGY_ID = { + "context_id": deepcopy(CONTEXT_ID), + "topology_uuid": {"uuid": DEFAULT_TOPOLOGY_UUID}, +} +TOPOLOGY = { + "topology_id": deepcopy(TOPOLOGY_ID), + "device_ids": [], + "link_ids": [], +} + +DEVICE1_UUID = "DEV1" +DEVICE1_ID = {"device_uuid": {"uuid": DEVICE1_UUID}} +DEVICE1 = { + "device_id": deepcopy(DEVICE1_ID), + "device_type": "packet-router", + "device_config": { + "config_rules": [ + config_rule(ConfigActionEnum.CONFIGACTION_SET, "value1"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "value2"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "value3"), + ] + }, + "device_operational_status": DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, + "device_drivers": [ + DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, + DeviceDriverEnum.DEVICEDRIVER_P4, + ], + "device_endpoints": [ + endpoint(TOPOLOGY_ID, DEVICE1_ID, "EP2", "port-packet-100G"), + endpoint(TOPOLOGY_ID, DEVICE1_ID, "EP3", "port-packet-100G"), + endpoint(TOPOLOGY_ID, DEVICE1_ID, "EP100", "port-packet-10G"), + ], +} + +DEVICE2_UUID = "DEV2" +DEVICE2_ID = {"device_uuid": {"uuid": DEVICE2_UUID}} +DEVICE2 = { + "device_id": deepcopy(DEVICE2_ID), + "device_type": "packet-router", + "device_config": { + "config_rules": [ + config_rule(ConfigActionEnum.CONFIGACTION_SET, "dev/rsrc1/value", "value4"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "dev/rsrc2/value", "value5"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "dev/rsrc3/value", "value6"), + ] + }, + "device_operational_status": DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, + "device_drivers": [ + DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, + DeviceDriverEnum.DEVICEDRIVER_P4, + ], + "device_endpoints": [ + endpoint(TOPOLOGY_ID, DEVICE2_ID, "EP1", "port-packet-100G"), + endpoint(TOPOLOGY_ID, DEVICE2_ID, "EP3", "port-packet-100G"), + endpoint(TOPOLOGY_ID, DEVICE2_ID, "EP100", "port-packet-10G"), + ], +} + +DEVICE3_UUID = "DEV3" +DEVICE3_ID = {"device_uuid": {"uuid": DEVICE3_UUID}} +DEVICE3 = { + "device_id": deepcopy(DEVICE3_ID), + "device_type": "packet-router", + "device_config": { + "config_rules": [ + config_rule(ConfigActionEnum.CONFIGACTION_SET, "dev/rsrc1/value", "value4"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "dev/rsrc2/value", "value5"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "dev/rsrc3/value", "value6"), + ] + }, + "device_operational_status": DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, + "device_drivers": [ + DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, + DeviceDriverEnum.DEVICEDRIVER_P4, + ], + "device_endpoints": [ + endpoint(TOPOLOGY_ID, DEVICE3_ID, "EP1", "port-packet-100G"), + endpoint(TOPOLOGY_ID, DEVICE3_ID, "EP2", "port-packet-100G"), + endpoint(TOPOLOGY_ID, DEVICE3_ID, "EP100", "port-packet-10G"), + ], +} + +LINK_DEV1_DEV2_UUID = "DEV1/EP2 ==> DEV2/EP1" +LINK_DEV1_DEV2_ID = {"link_uuid": {"uuid": LINK_DEV1_DEV2_UUID}} +LINK_DEV1_DEV2 = { + "link_id": deepcopy(LINK_DEV1_DEV2_ID), + "link_endpoint_ids": [ + endpoint_id(TOPOLOGY_ID, DEVICE1_ID, "EP2"), + endpoint_id(TOPOLOGY_ID, DEVICE2_ID, "EP1"), + ], +} + +LINK_DEV2_DEV3_UUID = "DEV2/EP3 ==> DEV3/EP2" +LINK_DEV2_DEV3_ID = {"link_uuid": {"uuid": LINK_DEV2_DEV3_UUID}} +LINK_DEV2_DEV3 = { + "link_id": deepcopy(LINK_DEV2_DEV3_ID), + "link_endpoint_ids": [ + endpoint_id(TOPOLOGY_ID, DEVICE2_ID, "EP3"), + endpoint_id(TOPOLOGY_ID, DEVICE3_ID, "EP2"), + ], +} + +LINK_DEV1_DEV3_UUID = "DEV1/EP3 ==> DEV3/EP1" +LINK_DEV1_DEV3_ID = {"link_uuid": {"uuid": LINK_DEV1_DEV3_UUID}} +LINK_DEV1_DEV3 = { + "link_id": deepcopy(LINK_DEV1_DEV3_ID), + "link_endpoint_ids": [ + endpoint_id(TOPOLOGY_ID, DEVICE1_ID, "EP3"), + endpoint_id(TOPOLOGY_ID, DEVICE3_ID, "EP1"), + ], +} + +SERVICE_DEV1_DEV2_UUID = "SVC:DEV1/EP100-DEV2/EP100" +SERVICE_DEV1_DEV2_ID = { + "context_id": deepcopy(CONTEXT_ID), + "service_uuid": {"uuid": SERVICE_DEV1_DEV2_UUID}, +} +SERVICE_DEV1_DEV2 = { + "service_id": deepcopy(SERVICE_DEV1_DEV2_ID), + "service_type": ServiceTypeEnum.SERVICETYPE_L3NM, + "service_endpoint_ids": [ + endpoint_id(TOPOLOGY_ID, DEVICE1_ID, "EP100"), + endpoint_id(TOPOLOGY_ID, DEVICE2_ID, "EP100"), + ], + # 'service_constraints': [ + # {'constraint_type': 'latency_ms', 'constraint_value': '15.2'}, + # {'constraint_type': 'jitter_us', 'constraint_value': '1.2'}, + # ], + "service_status": {"service_status": ServiceStatusEnum.SERVICESTATUS_ACTIVE}, + "service_config": { + "config_rules": [ + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc1/value", "value7"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc2/value", "value8"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc3/value", "value9"), + ] + }, +} + +SERVICE_DEV1_DEV3_UUID = "SVC:DEV1/EP100-DEV3/EP100" +SERVICE_DEV1_DEV3_ID = { + "context_id": deepcopy(CONTEXT_ID), + "service_uuid": {"uuid": SERVICE_DEV1_DEV3_UUID}, +} +SERVICE_DEV1_DEV3 = { + "service_id": deepcopy(SERVICE_DEV1_DEV3_ID), + "service_type": ServiceTypeEnum.SERVICETYPE_L3NM, + "service_endpoint_ids": [ + endpoint_id(TOPOLOGY_ID, DEVICE1_ID, "EP100"), + endpoint_id(TOPOLOGY_ID, DEVICE3_ID, "EP100"), + ], + # 'service_constraints': [ + # {'constraint_type': 'latency_ms', 'constraint_value': '5.8'}, + # {'constraint_type': 'jitter_us', 'constraint_value': '0.1'}, + # ], + "service_status": {"service_status": ServiceStatusEnum.SERVICESTATUS_ACTIVE}, + "service_config": { + "config_rules": [ + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc1/value", "value7"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc2/value", "value8"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc3/value", "value9"), + ] + }, +} + +SERVICE_DEV2_DEV3_UUID = "SVC:DEV2/EP100-DEV3/EP100" +SERVICE_DEV2_DEV3_ID = { + "context_id": deepcopy(CONTEXT_ID), + "service_uuid": {"uuid": SERVICE_DEV2_DEV3_UUID}, +} +SERVICE_DEV2_DEV3 = { + "service_id": deepcopy(SERVICE_DEV2_DEV3_ID), + "service_type": ServiceTypeEnum.SERVICETYPE_L3NM, + "service_endpoint_ids": [ + endpoint_id(TOPOLOGY_ID, DEVICE2_ID, "EP100"), + endpoint_id(TOPOLOGY_ID, DEVICE3_ID, "EP100"), + ], + # 'service_constraints': [ + # {'constraint_type': 'latency_ms', 'constraint_value': '23.1'}, + # {'constraint_type': 'jitter_us', 'constraint_value': '3.4'}, + # ], + "service_status": {"service_status": ServiceStatusEnum.SERVICESTATUS_ACTIVE}, + "service_config": { + "config_rules": [ + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc1/value", "value7"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc2/value", "value8"), + config_rule(ConfigActionEnum.CONFIGACTION_SET, "svc/rsrc3/value", "value9"), + ] + }, +} diff --git a/src/opticalattackdetector/tests/test_unitary.py b/src/opticalattackdetector/tests/test_unitary.py new file mode 100644 index 0000000000000000000000000000000000000000..72e3a4ac124bd034a76461baee316ab0f1139ed9 --- /dev/null +++ b/src/opticalattackdetector/tests/test_unitary.py @@ -0,0 +1,100 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 +import os +from unittest.mock import patch + +import pytest +from common.Constants import (DEFAULT_GRPC_GRACE_PERIOD, + DEFAULT_GRPC_MAX_WORKERS) +from common.proto import dbscanserving_pb2 as dbscan +from common.proto.optical_attack_detector_pb2 import DetectionRequest + +from opticalattackdetector.client.OpticalAttackDetectorClient import \ + OpticalAttackDetectorClient +from opticalattackdetector.Config import GRPC_SERVICE_PORT +from opticalattackdetector.service.OpticalAttackDetectorService import \ + OpticalAttackDetectorService + +# from .example_objects import CONTEXT_ID, CONTEXT_ID_2, SERVICE_DEV1_DEV2 + +port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + + +@pytest.fixture(scope="session") +def optical_attack_detector_service(): + with patch.dict( + os.environ, + { + "OPTICALATTACKDETECTORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKDETECTORSERVICE_SERVICE_PORT_GRPC": str(port), + "DBSCANSERVINGSERVICE_SERVICE_HOST": "127.0.0.1", + "DBSCANSERVINGSERVICE_SERVICE_PORT_GRPC": str(port), + }, + clear=True, + ): + _service = OpticalAttackDetectorService( + port=port, + max_workers=DEFAULT_GRPC_MAX_WORKERS, + grace_period=DEFAULT_GRPC_GRACE_PERIOD, + ) + _service.start() + yield _service + _service.stop() + + +@pytest.fixture(scope="session") +def optical_attack_detector_client(optical_attack_detector_service): + with patch.dict( + os.environ, + { + "OPTICALATTACKDETECTORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKDETECTORSERVICE_SERVICE_PORT_GRPC": str(port), + "DBSCANSERVINGSERVICE_SERVICE_HOST": "127.0.0.1", + "DBSCANSERVINGSERVICE_SERVICE_PORT_GRPC": str(port), + }, + clear=True, + ): + _client = OpticalAttackDetectorClient() + yield _client + _client.close() + + +def test_detect_attack( + optical_attack_detector_client: OpticalAttackDetectorClient, +): + message = dbscan.DetectionResponse() + message.cluster_indices.extend([0, 1, -1, -1, -1]) + with patch( + "opticalattackdetector.service.OpticalAttackDetectorServiceServicerImpl.attack_mitigator_client" + ) as mitigator, patch( + "opticalattackdetector.service.OpticalAttackDetectorServiceServicerImpl.monitoring_client" + ) as monitoring, patch( + "opticalattackdetector.service.OpticalAttackDetectorServiceServicerImpl.dbscanserving_client.Detect", + # TODO: return dumb object with "cluster_indices" attribute + # idea: create new response object + return_value=message, + ) as dbscanserving: + request: DetectionRequest = DetectionRequest() + request.service_id.context_id.context_uuid.uuid = "" + request.service_id.service_uuid.uuid = str("") + request.kpi_id.kpi_id.uuid = "" + optical_attack_detector_client.DetectAttack(request) + mitigator.NotifyAttack.assert_called_once() + monitoring.IncludeKpi.assert_called_once() + dbscanserving.assert_called_once() diff --git a/src/opticalcentralizedattackdetector/.gitlab-ci.yml b/src/opticalattackmanager/.gitlab-ci.yml similarity index 62% rename from src/opticalcentralizedattackdetector/.gitlab-ci.yml rename to src/opticalattackmanager/.gitlab-ci.yml index 3db4de3f177cfb1478bc306067564e9a293e0737..08136e4900d184d4923d9690322b76f7f2ef9fcc 100644 --- a/src/opticalcentralizedattackdetector/.gitlab-ci.yml +++ b/src/opticalattackmanager/.gitlab-ci.yml @@ -12,49 +12,50 @@ # See the License for the specific language governing permissions and # limitations under the License. -# build, tag and push the Docker image to the gitlab registry -build opticalcentralizedattackdetector: +# Build, tag, and push the Docker image to the GitLab Docker registry +build opticalattackmanager: variables: - IMAGE_NAME: 'opticalcentralizedattackdetector' # name of the microservice + IMAGE_NAME: 'opticalattackmanager' # 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 build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/ + - docker 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"' + - 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 -# apply unit test to the opticalcentralizedattackdetector component -unit test opticalcentralizedattackdetector: +# Apply unit test to the component +unit_test opticalattackmanager: variables: - IMAGE_NAME: 'opticalcentralizedattackdetector' # name of the microservice + IMAGE_NAME: 'opticalattackmanager' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) stage: unit_test needs: - - build opticalcentralizedattackdetector + - build opticalattackmanager 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 10005:10005 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge --rm $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG - - sleep 5 + - docker run --name $IMAGE_NAME -d -p 10005:10005 -v "$PWD/src/$IMAGE_NAME/tests:/home/teraflow/$IMAGE_NAME/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG - docker ps -a - - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml" + - docker logs $IMAGE_NAME + - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/home/teraflow/$IMAGE_NAME/results/${IMAGE_NAME}_report.xml" - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing" coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' after_script: @@ -62,42 +63,43 @@ unit test opticalcentralizedattackdetector: - 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"' + - 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_NAMEservice.yaml + - manifests/${IMAGE_NAME}service.yaml - .gitlab-ci.yml artifacts: - when: always - reports: - junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml - + when: always + reports: + junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml -# Deployment of the opticalcentralizedattackdetector service in Kubernetes Cluster -deploy opticalcentralizedattackdetector: - variables: - IMAGE_NAME: 'opticalcentralizedattackdetector' # name of the microservice - IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) - stage: deploy - needs: - - unit test opticalcentralizedattackdetector - # - 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 \ No newline at end of file +# Deployment of the service in Kubernetes Cluster +# deploy opticalattackmanager: +# variables: +# IMAGE_NAME: 'opticalattackmanager' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test opticalattackmanager +# # - 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/opticalattackmanager/Config.py b/src/opticalattackmanager/Config.py new file mode 100644 index 0000000000000000000000000000000000000000..7cbb8423de9118b5e79e96b535e3831aa469b7b2 --- /dev/null +++ b/src/opticalattackmanager/Config.py @@ -0,0 +1,15 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +MONITORING_INTERVAL = 10 # monitoring interval in seconds diff --git a/src/opticalattackmanager/Dockerfile b/src/opticalattackmanager/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..9920d6cefbb4ffc87558ae562cfb4fcee365930f --- /dev/null +++ b/src/opticalattackmanager/Dockerfile @@ -0,0 +1,92 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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++ && \ + rm -rf /var/lib/apt/lists/* + +# Set Python to show logs as they occur +ENV PYTHONUNBUFFERED=0 +ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + +# Download the gRPC health probe +RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ + wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ + chmod +x /bin/grpc_health_probe + +# Creating a user for security reasons +RUN groupadd -r teraflow && useradd -u 1001 --no-log-init -r -m -g teraflow teraflow +USER teraflow + +# set working directory +RUN mkdir -p /home/teraflow/controller/common/ +WORKDIR /home/teraflow/controller + +# Get Python packages per module +ENV VIRTUAL_ENV=/home/teraflow/venv +RUN python3 -m venv ${VIRTUAL_ENV} +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" + +# 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 +COPY --chown=teraflow:teraflow common_requirements.in common_requirements.in +COPY --chown=teraflow:teraflow src/opticalattackmanager/requirements.in opticalattackmanager/requirements.in +RUN sed -i '/protobuf/d' common_requirements.in && sed -i '/grpc/d' common_requirements.in +RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in opticalattackmanager/requirements.in +RUN python3 -m pip install -r common_requirements.txt + +# Get Python packages per module +# COPY --chown=opticalattackmanager:opticalattackmanager src/opticalattackmanager/requirements.in opticalattackmanager/requirements.in +# RUN pip-compile --quiet --output-file=opticalattackmanager/requirements.txt opticalattackmanager/requirements.in +# RUN python3 -m pip install -r opticalattackmanager/requirements.txt + +# Add common files into working directory +WORKDIR /home/teraflow/controller/common +COPY --chown=teraflow:teraflow src/common/. ./ +RUN rm -rf proto + +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /home/teraflow/controller/common/proto/asyncio +WORKDIR /home/teraflow/controller/common/proto +RUN touch __init__.py +RUN touch asyncio/__init__.py +COPY --chown=teraflow:teraflow proto/*.proto ./ +RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto +# new line added to generate protobuf for the `grpclib` library +RUN python3 -m grpc_tools.protoc -I=./ --python_out=./asyncio --grpclib_python_out=./asyncio *.proto +RUN rm *.proto +RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \; + +# Create module sub-folders +RUN mkdir -p /home/teraflow/controller/opticalattackmanager +WORKDIR /home/teraflow/controller + +# Add component files into working directory +COPY --chown=teraflow:teraflow ./src/context/. context +COPY --chown=teraflow:teraflow ./src/monitoring/. monitoring +COPY --chown=teraflow:teraflow ./src/dbscanserving/. dbscanserving +COPY --chown=teraflow:teraflow ./src/opticalattackdetector/. opticalattackdetector +COPY --chown=teraflow:teraflow ./src/opticalattackmitigator/. opticalattackmitigator +COPY --chown=teraflow:teraflow ./src/opticalattackmanager/. opticalattackmanager + +# Start the service +ENTRYPOINT ["python", "-m", "opticalattackmanager.service"] diff --git a/src/opticalattackmanager/__init__.py b/src/opticalattackmanager/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackmanager/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackmanager/requirements.in b/src/opticalattackmanager/requirements.in new file mode 100644 index 0000000000000000000000000000000000000000..6f2b2b7d36ddab234f6d1f874ad3eb86173ce654 --- /dev/null +++ b/src/opticalattackmanager/requirements.in @@ -0,0 +1,19 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +grpcio==1.49.* +grpcio-health-checking==1.49.* +grpcio-tools==1.49.* +grpclib[protobuf] +redis diff --git a/src/opticalattackmanager/service/__init__.py b/src/opticalattackmanager/service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackmanager/service/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackmanager/service/__main__.py b/src/opticalattackmanager/service/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..af38e02a0c4a3098ce9684822654a2494611661d --- /dev/null +++ b/src/opticalattackmanager/service/__main__.py @@ -0,0 +1,559 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 asyncio +import logging +import math +import pickle +import signal +import sys +import time +from concurrent.futures import ProcessPoolExecutor +from multiprocessing import Event, Manager, Process +from typing import Dict, List + +import redis +from prometheus_client import Counter, Gauge, Histogram, start_http_server + +from common.Constants import ServiceNameEnum +from common.proto.context_pb2 import ( + ContextIdList, + Empty, + EventTypeEnum, + Service, + ServiceIdList, + ServiceTypeEnum, +) +from common.proto.kpi_sample_types_pb2 import KpiSampleType +from common.proto.monitoring_pb2 import KpiDescriptor +from common.Settings import ( + ENVVAR_SUFIX_SERVICE_HOST, + ENVVAR_SUFIX_SERVICE_PORT_GRPC, + get_env_var_name, + get_log_level, + get_metrics_port, + get_service_host, + get_service_port_grpc, + get_setting, + wait_for_environment_variables, +) +from common.tools.grpc.Tools import grpc_message_to_json_string +from context.client.ContextClient import ContextClient +from context.client.EventsCollector import EventsCollector +from monitoring.client.MonitoringClient import MonitoringClient +from opticalattackmanager.Config import MONITORING_INTERVAL +from opticalattackmanager.utils.monitor import delegate_services + +terminate = Event() +LOGGER = None + +# SERVICE_LIST_MODE: +# 1 => use Redis +LIST_REDIS_MODE = 1 +# 2 => use shared list +LIST_SHARED_MODE = 2 +SERVICE_LIST_MODE = int( + get_setting("OPTICALATTACKMANAGER_SERVICE_LIST_MODE", default=1) +) +SERVICE_LIST_KEY = get_setting( + "OPTICALATTACKMANAGER_SERVICE_LIST_KEY", default="opt-sec:active-services" +) +MIN_NUMBER_WORKERS = int( + get_setting("OPTICALATTACKMANAGERSERVICE_LOOP_MIN_WORKERS", default=2) +) +MAX_NUMBER_WORKERS = int( + get_setting("OPTICALATTACKMANAGERSERVICE_LOOP_MAX_WORKERS", default=10) +) + +# Create a metric to track time spent and requests made. +# TODO: adjust histogram buckets to more realistic values +LOOP_TIME = Histogram( + "tfs_opticalattackmanager_loop_seconds", + "Time taken by each security loop", + buckets=( + 1.0, 2.5, 5.0, 7.5, 10.0, 12.5, + 15.0, 17.5, 20.0, 22.5, 25.0, 27.5, + 30.0, 32.5, 35.0, 37.5, 40.0, + 42.5, 45.0, 47.5, + 50.0, 52.5, 55.0, 57.5, + 60.0, 70.0, 80.0, 90.0, 100.0, + float("inf"), + ), +) + +CURRENT_SERVICES = Gauge( + "tfs_opticalattackmanager_active_services", + "Active optical services currently in the network", +) + +NUMBER_WORKERS = Gauge( + "tfs_opticalattackmanager_number_workers", + "Number of workers being used by the loop", +) + +DESIRED_MONITORING_INTERVAL = Gauge( + "tfs_opticalattackmanager_desired_monitoring_interval", + "Desired loop monitoring interval", +) + +DROP_COUNTER = Counter( + "tfs_opticalattackmanager_dropped_assessments", + "Dropped assessments due to detector timeout", +) + +global service_list +global cache + + +def append_service( + info: Dict[str, str], service_list: List = None, cache: redis.Redis = None +) -> None: + if SERVICE_LIST_MODE == LIST_REDIS_MODE: + cache.lpush(SERVICE_LIST_KEY, pickle.dumps(info)) + elif SERVICE_LIST_MODE == LIST_SHARED_MODE: + service_list.append(info) + + +def delete_service( + info: Dict[str, str], service_list: List = None, cache: redis.Redis = None +) -> None: + # here we need to test if the service exists in the list because it has been + # already deleted and there is not way of knowing if it is optical or not + if SERVICE_LIST_MODE == LIST_REDIS_MODE: + service_list = cache.lrange(SERVICE_LIST_KEY, 0, -1) + for encoded in service_list: + service = pickle.loads(encoded) + if ( + service["service"] == info["service"] + and service["context"] == info["context"] + ): + cache.lrem(SERVICE_LIST_KEY, 1, encoded) + break + elif SERVICE_LIST_MODE == LIST_SHARED_MODE: + # find service and remove it from the list of currently monitored + for service in service_list: + if ( + service["service"] == info["service"] + and service["context"] == info["context"] + ): + service_list.remove(service) + break + + +def signal_handler(signal, frame): # pylint: disable=redefined-outer-name + LOGGER.warning("Terminate signal received") + terminate.set() + + +def create_kpi(client: MonitoringClient, service_id): + # create kpi + kpi_description: KpiDescriptor = KpiDescriptor() + kpi_description.kpi_description = "Security status of service {}".format(service_id) + kpi_description.service_id.service_uuid.uuid = service_id + kpi_description.kpi_sample_type = KpiSampleType.KPISAMPLETYPE_UNKNOWN + new_kpi = client.SetKpi(kpi_description) + LOGGER.debug("Created KPI {}: ".format(grpc_message_to_json_string(new_kpi))) + return new_kpi + + +def get_context_updates(terminate, service_list, cache): + # to make sure we are thread safe... + LOGGER.info("Connecting with context and monitoring components...") + context_client: ContextClient = ContextClient() + monitoring_client: MonitoringClient = MonitoringClient() + + events_collector: EventsCollector = EventsCollector( + context_client, + log_events_received=True, + activate_connection_collector=False, + activate_context_collector=False, + activate_device_collector=False, + activate_link_collector=False, + activate_slice_collector=False, + activate_topology_collector=False, + activate_service_collector=True, + ) + events_collector.start() + + LOGGER.info("Connected with components successfully... Waiting for events...") + + time.sleep(20) + + while not terminate.wait(timeout=5): + event = events_collector.get_event(block=True, timeout=1) + if event is None: + LOGGER.debug("No event received") + continue # no event received + LOGGER.debug("Event received: {}".format(grpc_message_to_json_string(event))) + if event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE: + service: Service = context_client.GetService(event.service_id) + # only add if service is of type TAPI + if ( + service.service_type + == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE + ): + LOGGER.info( + "Service created: {}".format( + grpc_message_to_json_string(event.service_id) + ) + ) + kpi_id = create_kpi( + monitoring_client, event.service_id.service_uuid.uuid + ) + + append_service( + { + "context": event.service_id.context_id.context_uuid.uuid, + "service": event.service_id.service_uuid.uuid, + "kpi": kpi_id.kpi_id.uuid, + }, + service_list=service_list, + cache=cache, + ) + + elif event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE: + # cannot fetch service details because it does not exist anymore + LOGGER.info( + "Service removed: {}".format( + grpc_message_to_json_string(event.service_id) + ) + ) + delete_service( + { + "service": event.service_id.service_uuid.uuid, + "context": event.service_id.context_id.context_uuid.uuid, + }, + service_list=service_list, + cache=cache, + ) + + events_collector.stop() + + +def get_number_workers( + cur_value: int, cur_duration: float, desired_duration: float +) -> int: + factor = cur_duration / desired_duration + desired_number = cur_value * factor + new_value = min( + MAX_NUMBER_WORKERS, max(MIN_NUMBER_WORKERS, math.ceil(desired_number)) + ) + return new_value + + +async def monitor_services(terminate, service_list=None, cache=None): + + host = get_service_host(ServiceNameEnum.OPTICALATTACKDETECTOR) + port = get_service_port_grpc(ServiceNameEnum.OPTICALATTACKDETECTOR) + + cur_number_workers = MIN_NUMBER_WORKERS + desired_monitoring_interval = 30 # defaults to 30 seconds + DESIRED_MONITORING_INTERVAL.set(desired_monitoring_interval) + + event_loop = asyncio.get_running_loop() + + LOGGER.info("Starting execution of the async loop") + + while not terminate.is_set(): + # we account the entire set of procedures as the loop time + start_time = time.time() + + # obtain desired monitoring interval + temp = cache.get("MONITORING_INTERVAL") + if temp is not None: + new_desired_monitoring_interval = int(temp) + else: + # if not set in Redis, fallback to the environment variable + new_desired_monitoring_interval = int( + get_setting("MONITORING_INTERVAL", default=MONITORING_INTERVAL) + ) + cache.set("MONITORING_INTERVAL", new_desired_monitoring_interval) + + # only reports when changes happen + if desired_monitoring_interval != new_desired_monitoring_interval: + LOGGER.info( + "Changing monitoring interval from {} [sec.] to {} [sec.]".format( + desired_monitoring_interval, new_desired_monitoring_interval + ) + ) + desired_monitoring_interval = new_desired_monitoring_interval + DESIRED_MONITORING_INTERVAL.set(desired_monitoring_interval) + + pool_executor = ProcessPoolExecutor(max_workers=cur_number_workers) + NUMBER_WORKERS.set(cur_number_workers) + + current_list = [] + if SERVICE_LIST_MODE == LIST_REDIS_MODE: + current_list.extend( + [ + pickle.loads(service) + for service in cache.lrange(SERVICE_LIST_KEY, 0, -1) + ] + ) + elif SERVICE_LIST_MODE == LIST_SHARED_MODE: + current_list.extend(service_list) + + CURRENT_SERVICES.set(len(current_list)) + + if len(current_list) == 0: + LOGGER.info( + f"No services to monitor... {desired_monitoring_interval} [sec.] / {cur_number_workers} workers" + ) + + duration = time.time() - start_time + + # calculate new number of workers + cur_number_workers = get_number_workers( + cur_number_workers, duration, desired_monitoring_interval + ) + + LOOP_TIME.observe(0) # ignore internal procedure time + time.sleep(desired_monitoring_interval - duration) + continue + + LOGGER.info( + "Starting new monitoring cycle for {} sec. with {} for {} " + "services with {} workers...".format( + desired_monitoring_interval, + "REDIS" if SERVICE_LIST_MODE == 1 else "local", + len(current_list), + cur_number_workers, + ) + ) + + # start standard implementation + # tasks = [] + # for service in current_list: + # aw = detect_attack( + # host, + # port, + # service["context"], + # service["service"], + # service["kpi"], + # # allow at most 90% of the monitoring interval to succeed + # monitoring_interval * 0.9, + # ) + # tasks.append(aw) + # [await aw for aw in tasks] + # end standard implementation + + # start pool implementation + if len(current_list) == 0: # guard clause to re-check if services still there + LOGGER.info( + f"No services to monitor... " + f"{desired_monitoring_interval} / {cur_number_workers}" + ) + + duration = time.time() - start_time + + # calculate new number of workers + cur_number_workers = get_number_workers( + cur_number_workers, duration, desired_monitoring_interval + ) + + LOOP_TIME.observe(0) + time.sleep(desired_monitoring_interval - duration) + continue + + # process to get (close to) equal slices: + # https://stackoverflow.com/questions/2130016/splitting-a-list-into-n-parts-of-approximately-equal-length + k, m = divmod(len(current_list), cur_number_workers) + if k == 0: # happens when a single process is working + k = m + m = 0 + # dividing async work across multiple processes: + # https://stackoverflow.com/questions/69729488/how-to-run-multiple-asyncio-loops-inside-syncrhonous-sub-processes-inside-a-main + # https://stackoverflow.com/questions/65557258/typeerror-cant-pickle-coroutine-objects-when-i-am-using-asyncio-loop-run-in-ex + # https://stackoverflow.com/questions/69741177/run-multiple-async-loops-in-separate-processes-within-a-main-async-app + tasks = [ + event_loop.run_in_executor( + pool_executor, + delegate_services, + current_list, + i * k + min(i, m), # first index + (i + 1) * k + min(i + 1, m), # last index + host, + port, + DROP_COUNTER, + desired_monitoring_interval * 0.9, + ) + for i in range(cur_number_workers) + ] + # await for all tasks to finish + await asyncio.gather(*tasks) + + end_time = time.time() + + duration = end_time - start_time + LOOP_TIME.observe(duration) + LOGGER.info( + "Monitoring loop with {} services took {:.3f} seconds ({:.2f}%)... " + "Waiting for {:.2f} seconds...".format( + len(current_list), + duration, + (duration / desired_monitoring_interval) * 100, + desired_monitoring_interval - duration, + ) + ) + + # calculate new number of workers + cur_number_workers = get_number_workers( + cur_number_workers, duration, desired_monitoring_interval * 0.9 + ) + LOGGER.info(f"New number of workers: {cur_number_workers}") + + if duration / desired_monitoring_interval > 0.9: + LOGGER.warning( + "Monitoring loop is taking {} % of the desired time " + "({} seconds)".format( + (duration / desired_monitoring_interval) * 100, + desired_monitoring_interval, + ) + ) + if desired_monitoring_interval - duration > 0: + time.sleep(desired_monitoring_interval - duration) + + +def main(): + global LOGGER # pylint: disable=global-statement + + log_level = get_log_level() + logging.basicConfig(level=log_level) + LOGGER = logging.getLogger(__name__) + + logging.getLogger("hpack").setLevel(logging.CRITICAL) + + 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), + get_env_var_name(ServiceNameEnum.MONITORING, ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name( + ServiceNameEnum.MONITORING, ENVVAR_SUFIX_SERVICE_PORT_GRPC + ), + get_env_var_name( + ServiceNameEnum.OPTICALATTACKDETECTOR, ENVVAR_SUFIX_SERVICE_HOST + ), + get_env_var_name( + ServiceNameEnum.OPTICALATTACKDETECTOR, 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) + + if SERVICE_LIST_MODE not in [1, 2]: + LOGGER.critical( + "Service mode has wrong configuration. Value: {}.".format(SERVICE_LIST_MODE) + ) + + redis_host = get_service_host(ServiceNameEnum.CACHING) + if redis_host is not None: + redis_port = int(get_setting("CACHINGSERVICE_SERVICE_PORT_REDIS", default=6379)) + redis_password = get_setting("REDIS_PASSWORD") + LOGGER.debug(f"Redis password: {redis_password}") + + service_list = None + cache = None + if SERVICE_LIST_MODE == LIST_REDIS_MODE: + cache = redis.Redis(host=redis_host, port=redis_port, password=redis_password) + cache.ping() + + # clean the existing list that will be populated later on in this function + cache.delete(SERVICE_LIST_KEY) + elif SERVICE_LIST_MODE == LIST_SHARED_MODE: + # creating a thread-safe list to be shared among threads + service_list = Manager().list() + + LOGGER.info("Connecting with context component...") + context_client: ContextClient = ContextClient() + monitoring_client: MonitoringClient = MonitoringClient() + LOGGER.info("Connected successfully...") + + if get_setting("TESTING", default=False): + # if testing, create dummy services + kpi_id = create_kpi(monitoring_client, "1213") + append_service( + {"context": "admin", "service": "1213", "kpi": kpi_id.kpi_id.uuid}, + service_list=service_list, + cache=cache, + ) + kpi_id = create_kpi(monitoring_client, "1456") + append_service( + {"context": "admin", "service": "1456", "kpi": kpi_id.kpi_id.uuid}, + service_list=service_list, + cache=cache, + ) + + context_ids: ContextIdList = context_client.ListContextIds(Empty()) + + # populate with initial services + for context_id in context_ids.context_ids: + context_services: ServiceIdList = context_client.ListServiceIds(context_id) + for service_id in context_services.service_ids: + service: Service = context_client.GetService(service_id) + if ( + service.service_type + == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE + ): + # in case of a service restart, monitoring component will not duplicate KPIs + # but rather return the existing KPI if that's the case + kpi_id = create_kpi(monitoring_client, service_id.service_uuid.uuid) + append_service( + { + "context": context_id.context_uuid.uuid, + "service": service_id.service_uuid.uuid, + "kpi": kpi_id.kpi_id.uuid, + }, + service_list=service_list, + cache=cache, + ) + + context_client.close() + monitoring_client.close() + + # starting background process to monitor service addition/removal + process_context = Process( + target=get_context_updates, args=(terminate, service_list, cache) + ) + process_context.start() + + time.sleep(5) # wait for the context updates to startup + + # runs the async loop in the background + loop = asyncio.get_event_loop() + loop.run_until_complete(monitor_services(terminate, service_list, cache)) + # asyncio.create_task(monitor_services(service_list)) + + # Wait for Ctrl+C or termination signal + while not terminate.wait(timeout=1): + pass + + LOGGER.info("Terminating...") + process_context.kill() + # process_security_loop.kill() + + LOGGER.info("Bye") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/opticalattackmanager/tests/__init__.py b/src/opticalattackmanager/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackmanager/tests/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackmanager/tests/test_unitary.py b/src/opticalattackmanager/tests/test_unitary.py new file mode 100644 index 0000000000000000000000000000000000000000..5d29079d7c2c2bfbe1313c974c528e5211317e8f --- /dev/null +++ b/src/opticalattackmanager/tests/test_unitary.py @@ -0,0 +1,120 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 +import os +from unittest.mock import patch + +import pytest + +from common.Constants import (DEFAULT_GRPC_GRACE_PERIOD, + DEFAULT_GRPC_MAX_WORKERS, + DEFAULT_SERVICE_GRPC_PORTS, ServiceNameEnum) +from common.proto import dbscanserving_pb2 as dbscan +from common.proto.optical_attack_detector_pb2 import DetectionRequest +from opticalattackdetector.client.OpticalAttackDetectorClient import \ + OpticalAttackDetectorClient +from opticalattackdetector.Config import GRPC_SERVICE_PORT +from opticalattackdetector.service.OpticalAttackDetectorService import \ + OpticalAttackDetectorService + +# from .example_objects import CONTEXT_ID, CONTEXT_ID_2, SERVICE_DEV1_DEV2 + +port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + + +@pytest.fixture(scope="session") +def optical_attack_detector_service(): + with patch.dict( + os.environ, + { + "OPTICALATTACKDETECTORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKDETECTORSERVICE_SERVICE_PORT_GRPC": str( + 1000 + + DEFAULT_SERVICE_GRPC_PORTS.get( + ServiceNameEnum.OPTICALATTACKDETECTOR.value + ) + ), + "OPTICALATTACKMITIGATORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKMITIGATORSERVICE_SERVICE_PORT_GRPC": str( + 1000 + + DEFAULT_SERVICE_GRPC_PORTS.get( + ServiceNameEnum.OPTICALATTACKMITIGATOR.value + ) + ), + "DBSCANSERVINGSERVICE_SERVICE_HOST": "127.0.0.1", + "DBSCANSERVINGSERVICE_SERVICE_PORT_GRPC": str( + 1000 + + DEFAULT_SERVICE_GRPC_PORTS.get(ServiceNameEnum.DBSCANSERVING.value) + ), + }, + clear=True, + ): + _service = OpticalAttackDetectorService( + port=port, + max_workers=DEFAULT_GRPC_MAX_WORKERS, + grace_period=DEFAULT_GRPC_GRACE_PERIOD, + ) + # mocker_context_client = mock.patch('opticalattackdetector.service.OpticalAttackDetectorServiceServicerImpl.context_client') + # mocker_context_client.start() + + # mocker_influx_db = mock.patch('opticalattackdetector.service.OpticalAttackDetectorServiceServicerImpl.influxdb_client') + # mocker_influx_db.start() + + _service.start() + yield _service + _service.stop() + # mocker_context_client.stop() + # mocker_influx_db.stop() + + +@pytest.fixture(scope="session") +def optical_attack_detector_client(optical_attack_detector_service): + with patch.dict( + os.environ, + { + "OPTICALATTACKDETECTORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKDETECTORSERVICE_SERVICE_PORT_GRPC": str( + 1000 + + DEFAULT_SERVICE_GRPC_PORTS.get( + ServiceNameEnum.OPTICALATTACKDETECTOR.value + ) + ), + "OPTICALATTACKMITIGATORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKMITIGATORSERVICE_SERVICE_PORT_GRPC": str( + 1000 + + DEFAULT_SERVICE_GRPC_PORTS.get( + ServiceNameEnum.OPTICALATTACKMITIGATOR.value + ) + ), + "DBSCANSERVINGSERVICE_SERVICE_HOST": "127.0.0.1", + "DBSCANSERVINGSERVICE_SERVICE_PORT_GRPC": str( + 1000 + + DEFAULT_SERVICE_GRPC_PORTS.get(ServiceNameEnum.DBSCANSERVING.value) + ), + }, + clear=True, + ): + _client = OpticalAttackDetectorClient() + yield _client + _client.close() + + +def test_detect_attack( + optical_attack_detector_client: OpticalAttackDetectorClient, +): + LOGGER.info("placeholder") diff --git a/src/opticalattackmanager/utils/__init__.py b/src/opticalattackmanager/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf --- /dev/null +++ b/src/opticalattackmanager/utils/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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/opticalattackmanager/utils/monitor.py b/src/opticalattackmanager/utils/monitor.py new file mode 100644 index 0000000000000000000000000000000000000000..0d37cd0effdbb9cb10ca5454ef75d138a3d5fb4a --- /dev/null +++ b/src/opticalattackmanager/utils/monitor.py @@ -0,0 +1,83 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 asyncio +import logging + +from grpclib.client import Channel +from prometheus_client import Counter + +from common.proto.asyncio.optical_attack_detector_grpc import \ + OpticalAttackDetectorServiceStub +from common.proto.asyncio.optical_attack_detector_pb2 import DetectionRequest + +LOGGER = logging.getLogger(__name__) + + +async def detect_attack( + host: str, + port: int, + context_id: str, + service_id: str, + kpi_id: str, + drop_counter: Counter, + timeout: float = 20.0, +) -> None: + try: + LOGGER.debug("Sending request for {}...".format(service_id)) + async with Channel(host, port) as channel: + stub = OpticalAttackDetectorServiceStub(channel) + + request: DetectionRequest = DetectionRequest() + request.service_id.context_id.context_uuid.uuid = context_id + request.service_id.service_uuid.uuid = str(service_id) + + request.kpi_id.kpi_id.uuid = kpi_id + + await stub.DetectAttack(request, timeout=timeout) + LOGGER.debug("Monitoring finished for {}/{}".format(service_id, kpi_id)) + except Exception as e: + LOGGER.warning( + "Exception while processing service_id {}/{}".format(service_id, kpi_id) + ) + # LOGGER.exception(e) + drop_counter.inc() + + +def delegate_services( + service_list, + start_index: int, + end_index: int, + host: str, + port: str, + drop_counter: Counter, + monitoring_interval: float, +): + async def run_internal_loop(): + tasks = [] + for service in service_list[start_index:end_index]: + aw = detect_attack( + host, + port, + service["context"], + service["service"], + service["kpi"], + drop_counter, + # allow at most 90% of the monitoring interval to succeed + monitoring_interval * 0.9, + ) + tasks.append(aw) + [await aw for aw in tasks] + + asyncio.run(run_internal_loop()) diff --git a/src/opticalattackmitigator/.gitlab-ci.yml b/src/opticalattackmitigator/.gitlab-ci.yml index 92968348b3f7ad9b35f39e6f6d86e5df180499ac..44f13aa20f0a19e24e3188bd0c2315f581b2e006 100644 --- a/src/opticalattackmitigator/.gitlab-ci.yml +++ b/src/opticalattackmitigator/.gitlab-ci.yml @@ -21,7 +21,7 @@ build opticalattackmitigator: before_script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY script: - - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/ + - docker 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: @@ -38,7 +38,7 @@ build opticalattackmitigator: - .gitlab-ci.yml # apply unit test to the opticalattackmitigator component -unit test opticalattackmitigator: +unit_test opticalattackmitigator: variables: IMAGE_NAME: 'opticalattackmitigator' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) @@ -51,11 +51,10 @@ unit test opticalattackmitigator: - 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 10007:10007 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge --rm $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG + - docker run --name $IMAGE_NAME -d -p 10007:10007 -v "$PWD/src/$IMAGE_NAME/tests:/home/${IMAGE_NAME}/results" --network=teraflowbridge --rm $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG - sleep 5 - docker ps -a - - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml" - - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing" + - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/home/${IMAGE_NAME}/results/${IMAGE_NAME}_report.xml; coverage xml -o /home/${IMAGE_NAME}/results/${IMAGE_NAME}_coverage.xml; coverage report --include='${IMAGE_NAME}/*' --show-missing" coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' after_script: - docker rm -f $IMAGE_NAME @@ -77,27 +76,27 @@ unit test opticalattackmitigator: # Deployment of the opticalattackmitigator service in Kubernetes Cluster -deploy opticalattackmitigator: - variables: - IMAGE_NAME: 'opticalattackmitigator' # name of the microservice - IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) - stage: deploy - needs: - - unit test opticalattackmitigator - # - 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 \ No newline at end of file +# deploy opticalattackmitigator: +# variables: +# IMAGE_NAME: 'opticalattackmitigator' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test opticalattackmitigator +# # - 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 \ No newline at end of file diff --git a/src/opticalattackmitigator/Config.py b/src/opticalattackmitigator/Config.py index 09ae554ad2e0abce66c7638144c07b2e0b740ae9..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/opticalattackmitigator/Config.py +++ b/src/opticalattackmitigator/Config.py @@ -11,16 +11,3 @@ # 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 - -# General settings -LOG_LEVEL = logging.DEBUG - -# gRPC settings -GRPC_SERVICE_PORT = 10007 -GRPC_MAX_WORKERS = 10 -GRPC_GRACE_PERIOD = 60 - -# Prometheus settings -METRICS_PORT = 9192 diff --git a/src/opticalattackmitigator/Dockerfile b/src/opticalattackmitigator/Dockerfile index e3ba175b7616c88b7208c7476195786dffaa83d1..e364cbee121c38570c8158946486ec38dcd8b12d 100644 --- a/src/opticalattackmitigator/Dockerfile +++ b/src/opticalattackmitigator/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM python:3-slim +FROM python:3.9-slim # Install dependencies RUN apt-get --yes --quiet --quiet update && \ @@ -27,23 +27,56 @@ RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ chmod +x /bin/grpc_health_probe +# Creating a user for security reasons +RUN groupadd -r teraflow && useradd -u 1001 --no-log-init -r -m -g teraflow teraflow +USER teraflow + +# set working directory +RUN mkdir -p /home/teraflow/controller/common/ +WORKDIR /home/teraflow/controller + +# Get Python packages per module +ENV VIRTUAL_ENV=/home/teraflow/venv +RUN python3 -m venv ${VIRTUAL_ENV} +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" + # Get generic Python packages -RUN python3 -m pip install --upgrade pip setuptools wheel pip-tools +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 +COPY --chown=teraflow:teraflow 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 /home/teraflow/controller/common +COPY --chown=teraflow:teraflow src/common/. ./ +RUN rm -rf proto -# Set working directory -WORKDIR /var/teraflow +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /home/teraflow/controller/common/proto +WORKDIR /home/teraflow/controller/common/proto +RUN touch __init__.py +COPY --chown=teraflow:teraflow 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 module sub-folders -RUN mkdir -p /var/teraflow/opticalattackmitigator +RUN mkdir -p /home/teraflow/controller/opticalattackmitigator +WORKDIR /home/teraflow/controller # Get Python packages per module -COPY opticalattackmitigator/requirements.in opticalattackmitigator/requirements.in -RUN pip-compile --output-file=opticalattackmitigator/requirements.txt opticalattackmitigator/requirements.in +COPY --chown=teraflow:teraflow ./src/opticalattackmitigator/requirements.in opticalattackmitigator/requirements.in +# consider common and specific requirements to avoid inconsistencies with dependencies +RUN pip-compile --quiet --output-file=opticalattackmitigator/requirements.txt opticalattackmitigator/requirements.in common_requirements.in RUN python3 -m pip install -r opticalattackmitigator/requirements.txt -# Add files into working directory -COPY common/. common -COPY opticalattackmitigator/. opticalattackmitigator +# Add component files into working directory +COPY --chown=teraflow:teraflow ./src/opticalattackmitigator/. opticalattackmitigator -# Start opticalattackmitigator service +# Start the service ENTRYPOINT ["python", "-m", "opticalattackmitigator.service"] diff --git a/src/opticalattackmitigator/__init__.py b/src/opticalattackmitigator/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/opticalattackmitigator/__init__.py +++ b/src/opticalattackmitigator/__init__.py @@ -11,4 +11,3 @@ # 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/opticalattackmitigator/client/OpticalAttackMitigatorClient.py b/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py index 9aa24c696d346f8fb9874412cc1e2e18cfd018fe..4d283202b95a840a6cbe84daf373a806f5a1f463 100644 --- a/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py +++ b/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py @@ -12,37 +12,58 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging -from common.tools.client.RetryDecorator import retry, delay_exponential -from opticalattackmitigator.proto.optical_attack_mitigator_pb2 import AttackDescription, AttackResponse -from opticalattackmitigator.proto.optical_attack_mitigator_pb2_grpc import AttackMitigatorStub +import logging + +import grpc + +from common.Constants import ServiceNameEnum +from common.proto.optical_attack_mitigator_pb2 import (AttackDescription, + AttackResponse) +from common.proto.optical_attack_mitigator_pb2_grpc import AttackMitigatorStub +from common.Settings import get_service_host, get_service_port_grpc +from common.tools.client.RetryDecorator import delay_exponential, retry +from common.tools.grpc.Tools import grpc_message_to_json 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') +RETRY_DECORATOR = retry( + max_retries=MAX_RETRIES, + delay_function=DELAY_FUNCTION, + prepare_method_name="connect", +) + class OpticalAttackMitigatorClient: - def __init__(self, address, port): - self.endpoint = '{:s}:{:s}'.format(str(address), str(port)) - LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint))) + def __init__(self, host=None, port=None): + if not host: + host = get_service_host(ServiceNameEnum.OPTICALATTACKMITIGATOR) + if not port: + port = get_service_port_grpc(ServiceNameEnum.OPTICALATTACKMITIGATOR) + 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.connect() - LOGGER.debug('Channel created') + LOGGER.debug("Channel created") def connect(self): self.channel = grpc.insecure_channel(self.endpoint) self.stub = AttackMitigatorStub(self.channel) def close(self): - if(self.channel is not None): self.channel.close() + if self.channel is not None: + self.channel.close() self.channel = None self.stub = None @RETRY_DECORATOR - def NotifyAttack(self, request : AttackDescription) -> AttackResponse: - LOGGER.debug('NotifyAttack request: {:s}'.format(str(request))) + def NotifyAttack(self, request: AttackDescription) -> AttackResponse: + LOGGER.debug( + "NotifyAttack request: {:s}".format(str(grpc_message_to_json(request))) + ) response = self.stub.NotifyAttack(request) - LOGGER.debug('NotifyAttack result: {:s}'.format(str(response))) + LOGGER.debug( + "NotifyAttack result: {:s}".format(str(grpc_message_to_json(response))) + ) return response diff --git a/src/opticalattackmitigator/client/__init__.py b/src/opticalattackmitigator/client/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/opticalattackmitigator/client/__init__.py +++ b/src/opticalattackmitigator/client/__init__.py @@ -11,4 +11,3 @@ # 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/opticalattackmitigator/genproto.sh b/src/opticalattackmitigator/genproto.sh deleted file mode 100755 index 4cb0103b2428605c32cebc142c39dcdc764a3551..0000000000000000000000000000000000000000 --- a/src/opticalattackmitigator/genproto.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -# Make folder containing the script the root folder for its execution -cd $(dirname $0) - -rm -rf proto/*.py -rm -rf proto/__pycache__ -tee proto/__init__.py << EOF > /dev/null -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -EOF - -# building protos of services used -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto - -rm proto/context_pb2_grpc.py -rm proto/kpi_sample_types_pb2_grpc.py - -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py - -# building current service protos -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto optical_attack_mitigator.proto - -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/optical_attack_mitigator_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/optical_attack_mitigator_pb2_grpc.py diff --git a/src/opticalattackmitigator/proto/context_pb2.py b/src/opticalattackmitigator/proto/context_pb2.py deleted file mode 100644 index 50d501d3ac053ad644554331af26e3c40cd426a1..0000000000000000000000000000000000000000 --- a/src/opticalattackmitigator/proto/context_pb2.py +++ /dev/null @@ -1,3071 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: context.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='context.proto', - package='context', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3' - , - dependencies=[kpi__sample__types__pb2.DESCRIPTOR,]) - -_EVENTTYPEENUM = _descriptor.EnumDescriptor( - name='EventTypeEnum', - full_name='context.EventTypeEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_CREATE', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_UPDATE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_REMOVE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4310, - serialized_end=4416, -) -_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM) - -EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM) -_DEVICEDRIVERENUM = _descriptor.EnumDescriptor( - name='DeviceDriverEnum', - full_name='context.DeviceDriverEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_OPENCONFIG', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_P4', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_ONF_TR_352', index=5, number=5, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4419, - serialized_end=4616, -) -_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM) - -DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM) -_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor( - name='DeviceOperationalStatusEnum', - full_name='context.DeviceOperationalStatusEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4619, - serialized_end=4762, -) -_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM) - -DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM) -_SERVICETYPEENUM = _descriptor.EnumDescriptor( - name='ServiceTypeEnum', - full_name='context.ServiceTypeEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_L3NM', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_L2NM', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4765, - serialized_end=4894, -) -_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM) - -ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM) -_SERVICESTATUSENUM = _descriptor.EnumDescriptor( - name='ServiceStatusEnum', - full_name='context.ServiceStatusEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_PLANNED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_ACTIVE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4897, - serialized_end=5033, -) -_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM) - -ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM) -_SLICESTATUSENUM = _descriptor.EnumDescriptor( - name='SliceStatusEnum', - full_name='context.SliceStatusEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_PLANNED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_INIT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_ACTIVE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_DEINIT', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=5036, - serialized_end=5175, -) -_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM) - -SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM) -_CONFIGACTIONENUM = _descriptor.EnumDescriptor( - name='ConfigActionEnum', - full_name='context.ConfigActionEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='CONFIGACTION_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CONFIGACTION_SET', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CONFIGACTION_DELETE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=5177, - serialized_end=5270, -) -_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM) - -ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM) -EVENTTYPE_UNDEFINED = 0 -EVENTTYPE_CREATE = 1 -EVENTTYPE_UPDATE = 2 -EVENTTYPE_REMOVE = 3 -DEVICEDRIVER_UNDEFINED = 0 -DEVICEDRIVER_OPENCONFIG = 1 -DEVICEDRIVER_TRANSPORT_API = 2 -DEVICEDRIVER_P4 = 3 -DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4 -DEVICEDRIVER_ONF_TR_352 = 5 -DEVICEOPERATIONALSTATUS_UNDEFINED = 0 -DEVICEOPERATIONALSTATUS_DISABLED = 1 -DEVICEOPERATIONALSTATUS_ENABLED = 2 -SERVICETYPE_UNKNOWN = 0 -SERVICETYPE_L3NM = 1 -SERVICETYPE_L2NM = 2 -SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3 -SERVICESTATUS_UNDEFINED = 0 -SERVICESTATUS_PLANNED = 1 -SERVICESTATUS_ACTIVE = 2 -SERVICESTATUS_PENDING_REMOVAL = 3 -SLICESTATUS_UNDEFINED = 0 -SLICESTATUS_PLANNED = 1 -SLICESTATUS_INIT = 2 -SLICESTATUS_ACTIVE = 3 -SLICESTATUS_DEINIT = 4 -CONFIGACTION_UNDEFINED = 0 -CONFIGACTION_SET = 1 -CONFIGACTION_DELETE = 2 - - - -_EMPTY = _descriptor.Descriptor( - name='Empty', - full_name='context.Empty', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=50, - serialized_end=57, -) - - -_UUID = _descriptor.Descriptor( - name='Uuid', - full_name='context.Uuid', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uuid', full_name='context.Uuid.uuid', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=59, - serialized_end=79, -) - - -_EVENT = _descriptor.Descriptor( - name='Event', - full_name='context.Event', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='context.Event.timestamp', index=0, - number=1, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='event_type', full_name='context.Event.event_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=81, - serialized_end=151, -) - - -_CONTEXTID = _descriptor.Descriptor( - name='ContextId', - full_name='context.ContextId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_uuid', full_name='context.ContextId.context_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=153, - serialized_end=201, -) - - -_CONTEXT = _descriptor.Descriptor( - name='Context', - full_name='context.Context', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.Context.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='topology_ids', full_name='context.Context.topology_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_ids', full_name='context.Context.service_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='controller', full_name='context.Context.controller', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=204, - serialized_end=386, -) - - -_CONTEXTIDLIST = _descriptor.Descriptor( - name='ContextIdList', - full_name='context.ContextIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_ids', full_name='context.ContextIdList.context_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=388, - serialized_end=444, -) - - -_CONTEXTLIST = _descriptor.Descriptor( - name='ContextList', - full_name='context.ContextList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='contexts', full_name='context.ContextList.contexts', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=446, - serialized_end=495, -) - - -_CONTEXTEVENT = _descriptor.Descriptor( - name='ContextEvent', - full_name='context.ContextEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.ContextEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='context_id', full_name='context.ContextEvent.context_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=497, - serialized_end=582, -) - - -_TOPOLOGYID = _descriptor.Descriptor( - name='TopologyId', - full_name='context.TopologyId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.TopologyId.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=584, - serialized_end=674, -) - - -_TOPOLOGY = _descriptor.Descriptor( - name='Topology', - full_name='context.Topology', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topology_id', full_name='context.Topology.topology_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_ids', full_name='context.Topology.device_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='link_ids', full_name='context.Topology.link_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=676, - serialized_end=802, -) - - -_TOPOLOGYIDLIST = _descriptor.Descriptor( - name='TopologyIdList', - full_name='context.TopologyIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=804, - serialized_end=863, -) - - -_TOPOLOGYLIST = _descriptor.Descriptor( - name='TopologyList', - full_name='context.TopologyList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topologies', full_name='context.TopologyList.topologies', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=865, - serialized_end=918, -) - - -_TOPOLOGYEVENT = _descriptor.Descriptor( - name='TopologyEvent', - full_name='context.TopologyEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.TopologyEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='topology_id', full_name='context.TopologyEvent.topology_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=920, - serialized_end=1008, -) - - -_DEVICEID = _descriptor.Descriptor( - name='DeviceId', - full_name='context.DeviceId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='device_uuid', full_name='context.DeviceId.device_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1010, - serialized_end=1056, -) - - -_DEVICE = _descriptor.Descriptor( - name='Device', - full_name='context.Device', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='device_id', full_name='context.Device.device_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_type', full_name='context.Device.device_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_config', full_name='context.Device.device_config', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_operational_status', full_name='context.Device.device_operational_status', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_drivers', full_name='context.Device.device_drivers', index=4, - number=5, type=14, cpp_type=8, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_endpoints', full_name='context.Device.device_endpoints', index=5, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1059, - serialized_end=1341, -) - - -_DEVICECONFIG = _descriptor.Descriptor( - name='DeviceConfig', - full_name='context.DeviceConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='config_rules', full_name='context.DeviceConfig.config_rules', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1343, - serialized_end=1400, -) - - -_DEVICEIDLIST = _descriptor.Descriptor( - name='DeviceIdList', - full_name='context.DeviceIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='device_ids', full_name='context.DeviceIdList.device_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1402, - serialized_end=1455, -) - - -_DEVICELIST = _descriptor.Descriptor( - name='DeviceList', - full_name='context.DeviceList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='devices', full_name='context.DeviceList.devices', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1457, - serialized_end=1503, -) - - -_DEVICEEVENT = _descriptor.Descriptor( - name='DeviceEvent', - full_name='context.DeviceEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.DeviceEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_id', full_name='context.DeviceEvent.device_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1505, - serialized_end=1587, -) - - -_LINKID = _descriptor.Descriptor( - name='LinkId', - full_name='context.LinkId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='link_uuid', full_name='context.LinkId.link_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1589, - serialized_end=1631, -) - - -_LINK = _descriptor.Descriptor( - name='Link', - full_name='context.Link', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='link_id', full_name='context.Link.link_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1633, - serialized_end=1721, -) - - -_LINKIDLIST = _descriptor.Descriptor( - name='LinkIdList', - full_name='context.LinkIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='link_ids', full_name='context.LinkIdList.link_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1723, - serialized_end=1770, -) - - -_LINKLIST = _descriptor.Descriptor( - name='LinkList', - full_name='context.LinkList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='links', full_name='context.LinkList.links', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1772, - serialized_end=1812, -) - - -_LINKEVENT = _descriptor.Descriptor( - name='LinkEvent', - full_name='context.LinkEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.LinkEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='link_id', full_name='context.LinkEvent.link_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1814, - serialized_end=1890, -) - - -_SERVICEID = _descriptor.Descriptor( - name='ServiceId', - full_name='context.ServiceId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.ServiceId.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_uuid', full_name='context.ServiceId.service_uuid', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1892, - serialized_end=1980, -) - - -_SERVICE = _descriptor.Descriptor( - name='Service', - full_name='context.Service', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='service_id', full_name='context.Service.service_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_type', full_name='context.Service.service_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_constraints', full_name='context.Service.service_constraints', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_status', full_name='context.Service.service_status', index=4, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_config', full_name='context.Service.service_config', index=5, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1983, - serialized_end=2277, -) - - -_SERVICESTATUS = _descriptor.Descriptor( - name='ServiceStatus', - full_name='context.ServiceStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='service_status', full_name='context.ServiceStatus.service_status', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2279, - serialized_end=2346, -) - - -_SERVICECONFIG = _descriptor.Descriptor( - name='ServiceConfig', - full_name='context.ServiceConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='config_rules', full_name='context.ServiceConfig.config_rules', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2348, - serialized_end=2406, -) - - -_SERVICEIDLIST = _descriptor.Descriptor( - name='ServiceIdList', - full_name='context.ServiceIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='service_ids', full_name='context.ServiceIdList.service_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2408, - serialized_end=2464, -) - - -_SERVICELIST = _descriptor.Descriptor( - name='ServiceList', - full_name='context.ServiceList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='services', full_name='context.ServiceList.services', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2466, - serialized_end=2515, -) - - -_SERVICEEVENT = _descriptor.Descriptor( - name='ServiceEvent', - full_name='context.ServiceEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.ServiceEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_id', full_name='context.ServiceEvent.service_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2517, - serialized_end=2602, -) - - -_SLICEID = _descriptor.Descriptor( - name='SliceId', - full_name='context.SliceId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.SliceId.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2604, - serialized_end=2688, -) - - -_SLICE = _descriptor.Descriptor( - name='Slice', - full_name='context.Slice', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slice_id', full_name='context.Slice.slice_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_constraints', full_name='context.Slice.slice_constraints', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_status', full_name='context.Slice.slice_status', index=5, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2691, - serialized_end=2968, -) - - -_SLICESTATUS = _descriptor.Descriptor( - name='SliceStatus', - full_name='context.SliceStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slice_status', full_name='context.SliceStatus.slice_status', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2970, - serialized_end=3031, -) - - -_SLICEIDLIST = _descriptor.Descriptor( - name='SliceIdList', - full_name='context.SliceIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3033, - serialized_end=3083, -) - - -_SLICELIST = _descriptor.Descriptor( - name='SliceList', - full_name='context.SliceList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slices', full_name='context.SliceList.slices', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3085, - serialized_end=3128, -) - - -_SLICEEVENT = _descriptor.Descriptor( - name='SliceEvent', - full_name='context.SliceEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.SliceEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_id', full_name='context.SliceEvent.slice_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3130, - serialized_end=3209, -) - - -_CONNECTIONID = _descriptor.Descriptor( - name='ConnectionId', - full_name='context.ConnectionId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3211, - serialized_end=3265, -) - - -_CONNECTION = _descriptor.Descriptor( - name='Connection', - full_name='context.Connection', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connection_id', full_name='context.Connection.connection_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_id', full_name='context.Connection.service_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3268, - serialized_end=3464, -) - - -_CONNECTIONIDLIST = _descriptor.Descriptor( - name='ConnectionIdList', - full_name='context.ConnectionIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3466, - serialized_end=3531, -) - - -_CONNECTIONLIST = _descriptor.Descriptor( - name='ConnectionList', - full_name='context.ConnectionList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connections', full_name='context.ConnectionList.connections', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3533, - serialized_end=3591, -) - - -_CONNECTIONEVENT = _descriptor.Descriptor( - name='ConnectionEvent', - full_name='context.ConnectionEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.ConnectionEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3593, - serialized_end=3687, -) - - -_ENDPOINTID = _descriptor.Descriptor( - name='EndPointId', - full_name='context.EndPointId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topology_id', full_name='context.EndPointId.topology_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_id', full_name='context.EndPointId.device_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3690, - serialized_end=3820, -) - - -_ENDPOINT = _descriptor.Descriptor( - name='EndPoint', - full_name='context.EndPoint', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2, - number=3, type=14, cpp_type=8, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3823, - serialized_end=3957, -) - - -_CONFIGRULE = _descriptor.Descriptor( - name='ConfigRule', - full_name='context.ConfigRule', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='action', full_name='context.ConfigRule.action', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='resource_key', full_name='context.ConfigRule.resource_key', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='resource_value', full_name='context.ConfigRule.resource_value', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3959, - serialized_end=4060, -) - - -_CONSTRAINT = _descriptor.Descriptor( - name='Constraint', - full_name='context.Constraint', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='constraint_type', full_name='context.Constraint.constraint_type', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='constraint_value', full_name='context.Constraint.constraint_value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4062, - serialized_end=4125, -) - - -_TERAFLOWCONTROLLER = _descriptor.Descriptor( - name='TeraFlowController', - full_name='context.TeraFlowController', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.TeraFlowController.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='ip_address', full_name='context.TeraFlowController.ip_address', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='port', full_name='context.TeraFlowController.port', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4127, - serialized_end=4221, -) - - -_AUTHENTICATIONRESULT = _descriptor.Descriptor( - name='AuthenticationResult', - full_name='context.AuthenticationResult', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.AuthenticationResult.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4223, - serialized_end=4308, -) - -_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM -_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID -_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID -_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID -_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID -_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER -_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID -_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT -_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT -_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID -_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID -_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID -_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID -_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID -_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID -_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID -_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY -_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT -_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID -_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID -_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID -_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG -_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM -_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM -_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT -_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE -_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID -_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE -_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT -_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID -_LINKID.fields_by_name['link_uuid'].message_type = _UUID -_LINK.fields_by_name['link_id'].message_type = _LINKID -_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID -_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID -_LINKLIST.fields_by_name['links'].message_type = _LINK -_LINKEVENT.fields_by_name['event'].message_type = _EVENT -_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID -_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID -_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID -_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID -_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM -_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID -_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT -_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS -_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG -_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM -_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE -_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID -_SERVICELIST.fields_by_name['services'].message_type = _SERVICE -_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT -_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID -_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID -_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID -_SLICE.fields_by_name['slice_id'].message_type = _SLICEID -_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID -_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT -_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID -_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID -_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS -_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM -_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID -_SLICELIST.fields_by_name['slices'].message_type = _SLICE -_SLICEEVENT.fields_by_name['event'].message_type = _EVENT -_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID -_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID -_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID -_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID -_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID -_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID -_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID -_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION -_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT -_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID -_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID -_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID -_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID -_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID -_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE -_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM -_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID -_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID -DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY -DESCRIPTOR.message_types_by_name['Uuid'] = _UUID -DESCRIPTOR.message_types_by_name['Event'] = _EVENT -DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID -DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT -DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST -DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST -DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT -DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID -DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY -DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST -DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST -DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT -DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID -DESCRIPTOR.message_types_by_name['Device'] = _DEVICE -DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG -DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST -DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST -DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT -DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID -DESCRIPTOR.message_types_by_name['Link'] = _LINK -DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST -DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST -DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT -DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID -DESCRIPTOR.message_types_by_name['Service'] = _SERVICE -DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS -DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG -DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST -DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST -DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT -DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID -DESCRIPTOR.message_types_by_name['Slice'] = _SLICE -DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS -DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST -DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST -DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT -DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID -DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION -DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST -DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST -DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT -DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID -DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT -DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE -DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT -DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER -DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT -DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM -DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM -DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM -DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM -DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM -DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM -DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), { - 'DESCRIPTOR' : _EMPTY, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Empty) - }) -_sym_db.RegisterMessage(Empty) - -Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), { - 'DESCRIPTOR' : _UUID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Uuid) - }) -_sym_db.RegisterMessage(Uuid) - -Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), { - 'DESCRIPTOR' : _EVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Event) - }) -_sym_db.RegisterMessage(Event) - -ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextId) - }) -_sym_db.RegisterMessage(ContextId) - -Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Context) - }) -_sym_db.RegisterMessage(Context) - -ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextIdList) - }) -_sym_db.RegisterMessage(ContextIdList) - -ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextList) - }) -_sym_db.RegisterMessage(ContextList) - -ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextEvent) - }) -_sym_db.RegisterMessage(ContextEvent) - -TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyId) - }) -_sym_db.RegisterMessage(TopologyId) - -Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGY, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Topology) - }) -_sym_db.RegisterMessage(Topology) - -TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyIdList) - }) -_sym_db.RegisterMessage(TopologyIdList) - -TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyList) - }) -_sym_db.RegisterMessage(TopologyList) - -TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyEvent) - }) -_sym_db.RegisterMessage(TopologyEvent) - -DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), { - 'DESCRIPTOR' : _DEVICEID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceId) - }) -_sym_db.RegisterMessage(DeviceId) - -Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), { - 'DESCRIPTOR' : _DEVICE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Device) - }) -_sym_db.RegisterMessage(Device) - -DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), { - 'DESCRIPTOR' : _DEVICECONFIG, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceConfig) - }) -_sym_db.RegisterMessage(DeviceConfig) - -DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), { - 'DESCRIPTOR' : _DEVICEIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceIdList) - }) -_sym_db.RegisterMessage(DeviceIdList) - -DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), { - 'DESCRIPTOR' : _DEVICELIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceList) - }) -_sym_db.RegisterMessage(DeviceList) - -DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), { - 'DESCRIPTOR' : _DEVICEEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceEvent) - }) -_sym_db.RegisterMessage(DeviceEvent) - -LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), { - 'DESCRIPTOR' : _LINKID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkId) - }) -_sym_db.RegisterMessage(LinkId) - -Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), { - 'DESCRIPTOR' : _LINK, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Link) - }) -_sym_db.RegisterMessage(Link) - -LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), { - 'DESCRIPTOR' : _LINKIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkIdList) - }) -_sym_db.RegisterMessage(LinkIdList) - -LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), { - 'DESCRIPTOR' : _LINKLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkList) - }) -_sym_db.RegisterMessage(LinkList) - -LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), { - 'DESCRIPTOR' : _LINKEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkEvent) - }) -_sym_db.RegisterMessage(LinkEvent) - -ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), { - 'DESCRIPTOR' : _SERVICEID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceId) - }) -_sym_db.RegisterMessage(ServiceId) - -Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), { - 'DESCRIPTOR' : _SERVICE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Service) - }) -_sym_db.RegisterMessage(Service) - -ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), { - 'DESCRIPTOR' : _SERVICESTATUS, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceStatus) - }) -_sym_db.RegisterMessage(ServiceStatus) - -ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), { - 'DESCRIPTOR' : _SERVICECONFIG, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceConfig) - }) -_sym_db.RegisterMessage(ServiceConfig) - -ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), { - 'DESCRIPTOR' : _SERVICEIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceIdList) - }) -_sym_db.RegisterMessage(ServiceIdList) - -ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), { - 'DESCRIPTOR' : _SERVICELIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceList) - }) -_sym_db.RegisterMessage(ServiceList) - -ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), { - 'DESCRIPTOR' : _SERVICEEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceEvent) - }) -_sym_db.RegisterMessage(ServiceEvent) - -SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), { - 'DESCRIPTOR' : _SLICEID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceId) - }) -_sym_db.RegisterMessage(SliceId) - -Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), { - 'DESCRIPTOR' : _SLICE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Slice) - }) -_sym_db.RegisterMessage(Slice) - -SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), { - 'DESCRIPTOR' : _SLICESTATUS, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceStatus) - }) -_sym_db.RegisterMessage(SliceStatus) - -SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), { - 'DESCRIPTOR' : _SLICEIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceIdList) - }) -_sym_db.RegisterMessage(SliceIdList) - -SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), { - 'DESCRIPTOR' : _SLICELIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceList) - }) -_sym_db.RegisterMessage(SliceList) - -SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), { - 'DESCRIPTOR' : _SLICEEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceEvent) - }) -_sym_db.RegisterMessage(SliceEvent) - -ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionId) - }) -_sym_db.RegisterMessage(ConnectionId) - -Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTION, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Connection) - }) -_sym_db.RegisterMessage(Connection) - -ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionIdList) - }) -_sym_db.RegisterMessage(ConnectionIdList) - -ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionList) - }) -_sym_db.RegisterMessage(ConnectionList) - -ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionEvent) - }) -_sym_db.RegisterMessage(ConnectionEvent) - -EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), { - 'DESCRIPTOR' : _ENDPOINTID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.EndPointId) - }) -_sym_db.RegisterMessage(EndPointId) - -EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), { - 'DESCRIPTOR' : _ENDPOINT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.EndPoint) - }) -_sym_db.RegisterMessage(EndPoint) - -ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), { - 'DESCRIPTOR' : _CONFIGRULE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConfigRule) - }) -_sym_db.RegisterMessage(ConfigRule) - -Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), { - 'DESCRIPTOR' : _CONSTRAINT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Constraint) - }) -_sym_db.RegisterMessage(Constraint) - -TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), { - 'DESCRIPTOR' : _TERAFLOWCONTROLLER, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TeraFlowController) - }) -_sym_db.RegisterMessage(TeraFlowController) - -AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), { - 'DESCRIPTOR' : _AUTHENTICATIONRESULT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.AuthenticationResult) - }) -_sym_db.RegisterMessage(AuthenticationResult) - - - -_CONTEXTSERVICE = _descriptor.ServiceDescriptor( - name='ContextService', - full_name='context.ContextService', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=5273, - serialized_end=7688, - methods=[ - _descriptor.MethodDescriptor( - name='ListContextIds', - full_name='context.ContextService.ListContextIds', - index=0, - containing_service=None, - input_type=_EMPTY, - output_type=_CONTEXTIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListContexts', - full_name='context.ContextService.ListContexts', - index=1, - containing_service=None, - input_type=_EMPTY, - output_type=_CONTEXTLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetContext', - full_name='context.ContextService.GetContext', - index=2, - containing_service=None, - input_type=_CONTEXTID, - output_type=_CONTEXT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetContext', - full_name='context.ContextService.SetContext', - index=3, - containing_service=None, - input_type=_CONTEXT, - output_type=_CONTEXTID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveContext', - full_name='context.ContextService.RemoveContext', - index=4, - containing_service=None, - input_type=_CONTEXTID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetContextEvents', - full_name='context.ContextService.GetContextEvents', - index=5, - containing_service=None, - input_type=_EMPTY, - output_type=_CONTEXTEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListTopologyIds', - full_name='context.ContextService.ListTopologyIds', - index=6, - containing_service=None, - input_type=_CONTEXTID, - output_type=_TOPOLOGYIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListTopologies', - full_name='context.ContextService.ListTopologies', - index=7, - containing_service=None, - input_type=_CONTEXTID, - output_type=_TOPOLOGYLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetTopology', - full_name='context.ContextService.GetTopology', - index=8, - containing_service=None, - input_type=_TOPOLOGYID, - output_type=_TOPOLOGY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetTopology', - full_name='context.ContextService.SetTopology', - index=9, - containing_service=None, - input_type=_TOPOLOGY, - output_type=_TOPOLOGYID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveTopology', - full_name='context.ContextService.RemoveTopology', - index=10, - containing_service=None, - input_type=_TOPOLOGYID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetTopologyEvents', - full_name='context.ContextService.GetTopologyEvents', - index=11, - containing_service=None, - input_type=_EMPTY, - output_type=_TOPOLOGYEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListDeviceIds', - full_name='context.ContextService.ListDeviceIds', - index=12, - containing_service=None, - input_type=_EMPTY, - output_type=_DEVICEIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListDevices', - full_name='context.ContextService.ListDevices', - index=13, - containing_service=None, - input_type=_EMPTY, - output_type=_DEVICELIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetDevice', - full_name='context.ContextService.GetDevice', - index=14, - containing_service=None, - input_type=_DEVICEID, - output_type=_DEVICE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetDevice', - full_name='context.ContextService.SetDevice', - index=15, - containing_service=None, - input_type=_DEVICE, - output_type=_DEVICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveDevice', - full_name='context.ContextService.RemoveDevice', - index=16, - containing_service=None, - input_type=_DEVICEID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetDeviceEvents', - full_name='context.ContextService.GetDeviceEvents', - index=17, - containing_service=None, - input_type=_EMPTY, - output_type=_DEVICEEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListLinkIds', - full_name='context.ContextService.ListLinkIds', - index=18, - containing_service=None, - input_type=_EMPTY, - output_type=_LINKIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListLinks', - full_name='context.ContextService.ListLinks', - index=19, - containing_service=None, - input_type=_EMPTY, - output_type=_LINKLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetLink', - full_name='context.ContextService.GetLink', - index=20, - containing_service=None, - input_type=_LINKID, - output_type=_LINK, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetLink', - full_name='context.ContextService.SetLink', - index=21, - containing_service=None, - input_type=_LINK, - output_type=_LINKID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveLink', - full_name='context.ContextService.RemoveLink', - index=22, - containing_service=None, - input_type=_LINKID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetLinkEvents', - full_name='context.ContextService.GetLinkEvents', - index=23, - containing_service=None, - input_type=_EMPTY, - output_type=_LINKEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListServiceIds', - full_name='context.ContextService.ListServiceIds', - index=24, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SERVICEIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListServices', - full_name='context.ContextService.ListServices', - index=25, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SERVICELIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetService', - full_name='context.ContextService.GetService', - index=26, - containing_service=None, - input_type=_SERVICEID, - output_type=_SERVICE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetService', - full_name='context.ContextService.SetService', - index=27, - containing_service=None, - input_type=_SERVICE, - output_type=_SERVICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveService', - full_name='context.ContextService.RemoveService', - index=28, - containing_service=None, - input_type=_SERVICEID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetServiceEvents', - full_name='context.ContextService.GetServiceEvents', - index=29, - containing_service=None, - input_type=_EMPTY, - output_type=_SERVICEEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListSliceIds', - full_name='context.ContextService.ListSliceIds', - index=30, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SLICEIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListSlices', - full_name='context.ContextService.ListSlices', - index=31, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SLICELIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetSlice', - full_name='context.ContextService.GetSlice', - index=32, - containing_service=None, - input_type=_SLICEID, - output_type=_SLICE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetSlice', - full_name='context.ContextService.SetSlice', - index=33, - containing_service=None, - input_type=_SLICE, - output_type=_SLICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveSlice', - full_name='context.ContextService.RemoveSlice', - index=34, - containing_service=None, - input_type=_SLICEID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetSliceEvents', - full_name='context.ContextService.GetSliceEvents', - index=35, - containing_service=None, - input_type=_EMPTY, - output_type=_SLICEEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListConnectionIds', - full_name='context.ContextService.ListConnectionIds', - index=36, - containing_service=None, - input_type=_SERVICEID, - output_type=_CONNECTIONIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListConnections', - full_name='context.ContextService.ListConnections', - index=37, - containing_service=None, - input_type=_SERVICEID, - output_type=_CONNECTIONLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetConnection', - full_name='context.ContextService.GetConnection', - index=38, - containing_service=None, - input_type=_CONNECTIONID, - output_type=_CONNECTION, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetConnection', - full_name='context.ContextService.SetConnection', - index=39, - containing_service=None, - input_type=_CONNECTION, - output_type=_CONNECTIONID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveConnection', - full_name='context.ContextService.RemoveConnection', - index=40, - containing_service=None, - input_type=_CONNECTIONID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetConnectionEvents', - full_name='context.ContextService.GetConnectionEvents', - index=41, - containing_service=None, - input_type=_EMPTY, - output_type=_CONNECTIONEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE) - -DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalattackmitigator/proto/kpi_sample_types_pb2.py b/src/opticalattackmitigator/proto/kpi_sample_types_pb2.py deleted file mode 100644 index ea7fd2f82757d4c3db02d7e2c7817e2787b0b490..0000000000000000000000000000000000000000 --- a/src/opticalattackmitigator/proto/kpi_sample_types_pb2.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: kpi_sample_types.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='kpi_sample_types.proto', - package='kpi_sample_types', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3' -) - -_KPISAMPLETYPE = _descriptor.EnumDescriptor( - name='KpiSampleType', - full_name='kpi_sample_types.KpiSampleType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=45, - serialized_end=235, -) -_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) - -KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) -KPISAMPLETYPE_UNKNOWN = 0 -KPISAMPLETYPE_PACKETS_TRANSMITTED = 101 -KPISAMPLETYPE_PACKETS_RECEIVED = 102 -KPISAMPLETYPE_BYTES_TRANSMITTED = 201 -KPISAMPLETYPE_BYTES_RECEIVED = 202 - - -DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalattackmitigator/proto/optical_attack_mitigator_pb2.py b/src/opticalattackmitigator/proto/optical_attack_mitigator_pb2.py deleted file mode 100644 index 651c1b8e9cff9db06021a4b45934f3676a9f9f5e..0000000000000000000000000000000000000000 --- a/src/opticalattackmitigator/proto/optical_attack_mitigator_pb2.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: optical_attack_mitigator.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import context_pb2 as context__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='optical_attack_mitigator.proto', - package='optical_attack_mitigator', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x1eoptical_attack_mitigator.proto\x12\x18optical_attack_mitigator\x1a\rcontext.proto\"t\n\x11\x41ttackDescription\x12\x1c\n\x05\x63s_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\x12\x11\n\tattack_id\x18\x02 \x01(\x05\x12\x12\n\nconfidence\x18\x03 \x01(\x02\x12\x1a\n\x12\x61ttack_description\x18\x04 \x01(\t\"\xa2\x01\n\x0e\x41ttackResponse\x12\x1c\n\x05\x63s_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\x12\x11\n\tattack_id\x18\x02 \x01(\x05\x12\x1a\n\x12\x61ttack_description\x18\x03 \x01(\t\x12\x1c\n\x14response_strategy_id\x18\x04 \x01(\x05\x12%\n\x1dresponse_strategy_description\x18\x05 \x01(\t2z\n\x0f\x41ttackMitigator\x12g\n\x0cNotifyAttack\x12+.optical_attack_mitigator.AttackDescription\x1a(.optical_attack_mitigator.AttackResponse\"\x00\x62\x06proto3' - , - dependencies=[context__pb2.DESCRIPTOR,]) - - - - -_ATTACKDESCRIPTION = _descriptor.Descriptor( - name='AttackDescription', - full_name='optical_attack_mitigator.AttackDescription', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='cs_id', full_name='optical_attack_mitigator.AttackDescription.cs_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='attack_id', full_name='optical_attack_mitigator.AttackDescription.attack_id', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='confidence', full_name='optical_attack_mitigator.AttackDescription.confidence', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='attack_description', full_name='optical_attack_mitigator.AttackDescription.attack_description', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=75, - serialized_end=191, -) - - -_ATTACKRESPONSE = _descriptor.Descriptor( - name='AttackResponse', - full_name='optical_attack_mitigator.AttackResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='cs_id', full_name='optical_attack_mitigator.AttackResponse.cs_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='attack_id', full_name='optical_attack_mitigator.AttackResponse.attack_id', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='attack_description', full_name='optical_attack_mitigator.AttackResponse.attack_description', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='response_strategy_id', full_name='optical_attack_mitigator.AttackResponse.response_strategy_id', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='response_strategy_description', full_name='optical_attack_mitigator.AttackResponse.response_strategy_description', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=194, - serialized_end=356, -) - -_ATTACKDESCRIPTION.fields_by_name['cs_id'].message_type = context__pb2._UUID -_ATTACKRESPONSE.fields_by_name['cs_id'].message_type = context__pb2._UUID -DESCRIPTOR.message_types_by_name['AttackDescription'] = _ATTACKDESCRIPTION -DESCRIPTOR.message_types_by_name['AttackResponse'] = _ATTACKRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -AttackDescription = _reflection.GeneratedProtocolMessageType('AttackDescription', (_message.Message,), { - 'DESCRIPTOR' : _ATTACKDESCRIPTION, - '__module__' : 'optical_attack_mitigator_pb2' - # @@protoc_insertion_point(class_scope:optical_attack_mitigator.AttackDescription) - }) -_sym_db.RegisterMessage(AttackDescription) - -AttackResponse = _reflection.GeneratedProtocolMessageType('AttackResponse', (_message.Message,), { - 'DESCRIPTOR' : _ATTACKRESPONSE, - '__module__' : 'optical_attack_mitigator_pb2' - # @@protoc_insertion_point(class_scope:optical_attack_mitigator.AttackResponse) - }) -_sym_db.RegisterMessage(AttackResponse) - - - -_ATTACKMITIGATOR = _descriptor.ServiceDescriptor( - name='AttackMitigator', - full_name='optical_attack_mitigator.AttackMitigator', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=358, - serialized_end=480, - methods=[ - _descriptor.MethodDescriptor( - name='NotifyAttack', - full_name='optical_attack_mitigator.AttackMitigator.NotifyAttack', - index=0, - containing_service=None, - input_type=_ATTACKDESCRIPTION, - output_type=_ATTACKRESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_ATTACKMITIGATOR) - -DESCRIPTOR.services_by_name['AttackMitigator'] = _ATTACKMITIGATOR - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalattackmitigator/proto/optical_attack_mitigator_pb2_grpc.py b/src/opticalattackmitigator/proto/optical_attack_mitigator_pb2_grpc.py deleted file mode 100644 index 2f12816a1f909e073ece0ad5a4b3d8fda4235d89..0000000000000000000000000000000000000000 --- a/src/opticalattackmitigator/proto/optical_attack_mitigator_pb2_grpc.py +++ /dev/null @@ -1,66 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from . import optical_attack_mitigator_pb2 as optical__attack__mitigator__pb2 - - -class AttackMitigatorStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.NotifyAttack = channel.unary_unary( - '/optical_attack_mitigator.AttackMitigator/NotifyAttack', - request_serializer=optical__attack__mitigator__pb2.AttackDescription.SerializeToString, - response_deserializer=optical__attack__mitigator__pb2.AttackResponse.FromString, - ) - - -class AttackMitigatorServicer(object): - """Missing associated documentation comment in .proto file.""" - - def NotifyAttack(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_AttackMitigatorServicer_to_server(servicer, server): - rpc_method_handlers = { - 'NotifyAttack': grpc.unary_unary_rpc_method_handler( - servicer.NotifyAttack, - request_deserializer=optical__attack__mitigator__pb2.AttackDescription.FromString, - response_serializer=optical__attack__mitigator__pb2.AttackResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'optical_attack_mitigator.AttackMitigator', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class AttackMitigator(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def NotifyAttack(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/optical_attack_mitigator.AttackMitigator/NotifyAttack', - optical__attack__mitigator__pb2.AttackDescription.SerializeToString, - optical__attack__mitigator__pb2.AttackResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/opticalattackmitigator/requirements.in b/src/opticalattackmitigator/requirements.in index 378e9a10a70f6a41a264c6a76f47239d7515989a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/opticalattackmitigator/requirements.in +++ b/src/opticalattackmitigator/requirements.in @@ -11,14 +11,3 @@ # 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. - -grpcio-health-checking -grpcio -prometheus-client -pytest -pytest-benchmark -redis -# from the monitoring component -influxdb -python-json-logger -coverage diff --git a/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py b/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py index e2783e6ca6907cccad0e344cf2f058acabe53b93..c5a3ff4cdda1f800a5571b4b975a6427690834c9 100644 --- a/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py +++ b/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py @@ -12,61 +12,28 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc import logging -from concurrent import futures -from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH -from grpc_health.v1.health_pb2 import HealthCheckResponse -from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server -from opticalattackmitigator.proto.optical_attack_mitigator_pb2_grpc import ( - add_AttackMitigatorServicer_to_server) -from opticalattackmitigator.service.OpticalAttackMitigatorServiceServicerImpl import ( - OpticalAttackMitigatorServiceServicerImpl) -from opticalattackmitigator.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD -BIND_ADDRESS = '0.0.0.0' -LOGGER = logging.getLogger(__name__) - -class OpticalAttackMitigatorService: - def __init__( - self, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, - grace_period=GRPC_GRACE_PERIOD): - - self.address = address - self.port = port - self.endpoint = None - self.max_workers = max_workers - self.grace_period = grace_period - self.attack_mitigator_servicer = None - self.health_servicer = None - self.pool = None - self.server = None - - def start(self): - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port)) - LOGGER.debug('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format( - str(self.endpoint), str(self.max_workers))) +from common.Constants import ServiceNameEnum +from common.proto.optical_attack_mitigator_pb2_grpc import \ + add_AttackMitigatorServicer_to_server +from common.Settings import get_service_port_grpc +from common.tools.service.GenericGrpcService import GenericGrpcService - self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers) - self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,)) +from opticalattackmitigator.service.OpticalAttackMitigatorServiceServicerImpl import \ + OpticalAttackMitigatorServiceServicerImpl - self.attack_mitigator_servicer = OpticalAttackMitigatorServiceServicerImpl() - add_AttackMitigatorServicer_to_server(self.attack_mitigator_servicer, self.server) - - self.health_servicer = HealthServicer( - experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1)) - add_HealthServicer_to_server(self.health_servicer, self.server) - - port = self.server.add_insecure_port(self.endpoint) - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port)) - LOGGER.info('Listening on {:s}...'.format(self.endpoint)) - self.server.start() - self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member +LOGGER = logging.getLogger(__name__) - LOGGER.debug('Service started') - def stop(self): - LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period))) - self.health_servicer.enter_graceful_shutdown() - self.server.stop(self.grace_period) - LOGGER.debug('Service stopped') +class OpticalAttackMitigatorService(GenericGrpcService): + def __init__( + self, + cls_name=__name__, + ): + port = get_service_port_grpc(ServiceNameEnum.OPTICALATTACKMITIGATOR) + super().__init__(port, cls_name=cls_name) + self.opticalattackmitigator_services = OpticalAttackMitigatorServiceServicerImpl() + + def install_servicers(self): + add_AttackMitigatorServicer_to_server(self.opticalattackmitigator_services, self.server) diff --git a/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py b/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py index 16777e799deef7e50905b70b049f25765ebe7d96..d6018b733f9dc2078027420cc2d55f627a12c1a7 100644 --- a/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py +++ b/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py @@ -12,27 +12,33 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, grpc, logging, random -from influxdb import InfluxDBClient -from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method -from opticalattackmitigator.proto.optical_attack_mitigator_pb2_grpc import ( - AttackMitigatorServicer) -from opticalattackmitigator.proto.optical_attack_mitigator_pb2 import AttackDescription, AttackResponse +import logging + +import grpc +from common.method_wrappers.Decorator import (MetricsPool, + safe_and_metered_rpc_method) +from common.proto.optical_attack_mitigator_pb2 import (AttackDescription, + AttackResponse) +from common.proto.optical_attack_mitigator_pb2_grpc import \ + AttackMitigatorServicer LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('OpticalAttackMitigator', 'RPC') +METRICS_POOL = MetricsPool("OpticalAttackMitigator", "RPC") class OpticalAttackMitigatorServiceServicerImpl(AttackMitigatorServicer): - def __init__(self): - LOGGER.debug('Creating Servicer...') - LOGGER.debug('Servicer Created') + LOGGER.debug("Creating Servicer...") + LOGGER.debug("Servicer Created") @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def NotifyAttack(self, request : AttackDescription, context : grpc.ServicerContext) -> AttackResponse: + def NotifyAttack( + self, request: AttackDescription, context: grpc.ServicerContext + ) -> AttackResponse: LOGGER.debug(f"NotifyAttack: {request}") response: AttackResponse = AttackResponse() - response.response_strategy_description = 'The AttackMitigator has received the attack description.' + response.response_strategy_description = ( + "The AttackMitigator has received the attack description." + ) return response diff --git a/src/opticalattackmitigator/service/__init__.py b/src/opticalattackmitigator/service/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/opticalattackmitigator/service/__init__.py +++ b/src/opticalattackmitigator/service/__init__.py @@ -11,4 +11,3 @@ # 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/opticalattackmitigator/service/__main__.py b/src/opticalattackmitigator/service/__main__.py index 649d079c0cee6347e452acbaf35263d77150bd45..dc725a94f77c1f53e2f02a83c3d1b82350fb3b7d 100644 --- a/src/opticalattackmitigator/service/__main__.py +++ b/src/opticalattackmitigator/service/__main__.py @@ -12,53 +12,67 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, logging, signal, sys, time, threading, multiprocessing +import logging +import signal +import sys +import threading + from prometheus_client import start_http_server -from common.Settings import get_setting -from opticalattackmitigator.Config import ( - GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT) -from opticalattackmitigator.service.OpticalAttackMitigatorService import OpticalAttackMitigatorService + +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 opticalattackmitigator.service.OpticalAttackMitigatorService import \ + OpticalAttackMitigatorService terminate = threading.Event() LOGGER = None -def signal_handler(signal, frame): # pylint: disable=redefined-outer-name - LOGGER.warning('Terminate signal received') + +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 - service_port = get_setting('OPTICALATTACKMITIGATORSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT) - max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) - grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD) - log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) - metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) +def main(): + global LOGGER # pylint: disable=global-statement + log_level = get_log_level() logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) - signal.signal(signal.SIGINT, signal_handler) + wait_for_environment_variables( + [ + get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ] + ) + + signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) - LOGGER.info('Starting...') + LOGGER.info("Starting...") # Start metrics server + metrics_port = get_metrics_port() start_http_server(metrics_port) # Starting CentralizedCybersecurity service - grpc_service = OpticalAttackMitigatorService( - port=service_port, max_workers=max_workers, grace_period=grace_period) + grpc_service = OpticalAttackMitigatorService() grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1): + pass - LOGGER.info('Terminating...') + LOGGER.info("Terminating...") grpc_service.stop() - LOGGER.info('Bye') + LOGGER.info("Bye") return 0 -if __name__ == '__main__': + +if __name__ == "__main__": sys.exit(main()) diff --git a/src/opticalattackmitigator/tests/__init__.py b/src/opticalattackmitigator/tests/__init__.py index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/opticalattackmitigator/tests/__init__.py +++ b/src/opticalattackmitigator/tests/__init__.py @@ -11,4 +11,3 @@ # 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/opticalattackmitigator/tests/test_unitary.py b/src/opticalattackmitigator/tests/test_unitary.py index 24d0853b90a7b9f30fd25bfe7431f4e3e7e5fd0f..68836c4e81dd8e88b34cf85c9e2a29fd9f5e5678 100644 --- a/src/opticalattackmitigator/tests/test_unitary.py +++ b/src/opticalattackmitigator/tests/test_unitary.py @@ -12,31 +12,54 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, pytest -from opticalattackmitigator.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD -from opticalattackmitigator.client.OpticalAttackMitigatorClient import OpticalAttackMitigatorClient -from opticalattackmitigator.service.OpticalAttackMitigatorService import OpticalAttackMitigatorService -from opticalattackmitigator.proto.optical_attack_mitigator_pb2 import AttackDescription, AttackResponse +import logging +import os +from unittest.mock import patch -port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports +import pytest +from common.Constants import (DEFAULT_GRPC_GRACE_PERIOD, + DEFAULT_GRPC_MAX_WORKERS) +from common.proto.optical_attack_mitigator_pb2 import AttackDescription + +from opticalattackmitigator.client.OpticalAttackMitigatorClient import \ + OpticalAttackMitigatorClient +from opticalattackmitigator.Config import GRPC_SERVICE_PORT +from opticalattackmitigator.service.OpticalAttackMitigatorService import \ + OpticalAttackMitigatorService + +port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -@pytest.fixture(scope='session') + +@pytest.fixture(scope="session") def optical_attack_mitigator_service(): _service = OpticalAttackMitigatorService( - port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD) + port=port, + max_workers=DEFAULT_GRPC_MAX_WORKERS, + grace_period=DEFAULT_GRPC_GRACE_PERIOD, + ) _service.start() yield _service _service.stop() -@pytest.fixture(scope='session') + +@pytest.fixture(scope="session") def optical_attack_mitigator_client(optical_attack_mitigator_service): - _client = OpticalAttackMitigatorClient(address='127.0.0.1', port=port) - yield _client + with patch.dict( + os.environ, + { + "OPTICALATTACKMITIGATORSERVICE_SERVICE_HOST": "127.0.0.1", + "OPTICALATTACKMITIGATORSERVICE_SERVICE_PORT_GRPC": str(port), + }, + clear=True, + ): + _client = OpticalAttackMitigatorClient() + yield _client _client.close() + def test_call_service(optical_attack_mitigator_client: OpticalAttackMitigatorClient): request = AttackDescription() optical_attack_mitigator_client.NotifyAttack(request) diff --git a/src/opticalcentralizedattackdetector/Config.py b/src/opticalcentralizedattackdetector/Config.py deleted file mode 100644 index c9bfe106b8d69ca52016ccc9512ec4598d3914bf..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/Config.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 - -# General settings -LOG_LEVEL = logging.DEBUG - -# gRPC settings -GRPC_SERVICE_PORT = 10005 -GRPC_MAX_WORKERS = 10 -GRPC_GRACE_PERIOD = 60 - -# service settings -MONITORING_INTERVAL = 2 # monitoring interval in seconds -#TODO: adjust the addresses below for the specific case -MONITORING_SERVICE_ADDRESS = 'monitoringservice' # address/name of the monitoring service -# MONITORING_SERVICE_ADDRESS = '10.99.41.20' # address/name of the monitoring service -CONTEXT_SERVICE_ADDRESS = 'contextservice' # address/name of the monitoring service -# CONTEXT_SERVICE_ADDRESS = '10.107.199.65' # address/name of the monitoring service -SERVICE_SERVICE_ADDRESS = 'serviceservice' # address/name of the service service -# SERVICE_SERVICE_ADDRESS = '10.99.234.88' # address/name of the service service -# INFERENCE_SERVICE_ADDRESS = '10.108.113.78' # address/name of the inference service -INFERENCE_SERVICE_ADDRESS = 'dbscanservingservice' # address/name of the inference service -# ATTACK_MITIGATOR_SERVICE_ADDRESS = '10.96.248.167' -ATTACK_MITIGATOR_SERVICE_ADDRESS = 'opticalattackmitigatorservice' - -# Prometheus settings -METRICS_PORT = 9192 diff --git a/src/opticalcentralizedattackdetector/Dockerfile b/src/opticalcentralizedattackdetector/Dockerfile deleted file mode 100644 index a7b32ccc6ee94f0fe741885452a44ca9fb7a0f3f..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/Dockerfile +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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-slim - -# Install dependencies -RUN apt-get --yes --quiet --quiet update && \ - apt-get --yes --quiet --quiet install wget g++ && \ - rm -rf /var/lib/apt/lists/* - -# Set Python to show logs as they occur -ENV PYTHONUNBUFFERED=0 - -# Download the gRPC health probe -RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ - wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ - chmod +x /bin/grpc_health_probe - -# Get generic Python packages -RUN python3 -m pip install --upgrade pip setuptools wheel pip-tools - -# Set working directory -WORKDIR /var/teraflow - -# Create module sub-folders -RUN mkdir -p /var/teraflow/opticalcentralizedattackdetector - -# Get Python packages per module -COPY opticalcentralizedattackdetector/requirements.in opticalcentralizedattackdetector/requirements.in -RUN pip-compile --output-file=opticalcentralizedattackdetector/requirements.txt opticalcentralizedattackdetector/requirements.in -RUN python3 -m pip install -r opticalcentralizedattackdetector/requirements.txt - -# Add files into working directory -COPY common/. common -COPY context/. context -COPY monitoring/. monitoring -COPY service/. service -COPY dbscanserving/. dbscanserving -COPY opticalattackmitigator/. opticalattackmitigator -COPY opticalcentralizedattackdetector/. opticalcentralizedattackdetector - -ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python - -# Start opticalcentralizedattackdetector service -ENTRYPOINT ["python", "-m", "opticalcentralizedattackdetector.service"] diff --git a/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py b/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py deleted file mode 100644 index 3dc2f3ae8f3837fe1c12d530d61fe70acf2563b6..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.tools.client.RetryDecorator import retry, delay_exponential -from opticalcentralizedattackdetector.proto.context_pb2 import Empty, Service -from opticalcentralizedattackdetector.proto.monitoring_pb2 import KpiList -from opticalcentralizedattackdetector.proto.optical_centralized_attack_detector_pb2_grpc import OpticalCentralizedAttackDetectorServiceStub - -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 OpticalCentralizedAttackDetectorClient: - def __init__(self, address, port): - self.endpoint = '{:s}:{:s}'.format(str(address), str(port)) - LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint))) - self.channel = None - self.stub = None - self.connect() - LOGGER.debug('Channel created') - - def connect(self): - self.channel = grpc.insecure_channel(self.endpoint) - self.stub = OpticalCentralizedAttackDetectorServiceStub(self.channel) - - def close(self): - if(self.channel is not None): self.channel.close() - self.channel = None - self.stub = None - - @RETRY_DECORATOR - def NotifyServiceUpdate(self, request : Service) -> Empty: - LOGGER.debug('NotifyServiceUpdate request: {:s}'.format(str(request))) - response = self.stub.NotifyServiceUpdate(request) - LOGGER.debug('NotifyServiceUpdate result: {:s}'.format(str(response))) - return response - - @RETRY_DECORATOR - def DetectAttack(self, request : Empty) -> Empty: - LOGGER.debug('DetectAttack request: {:s}'.format(str(request))) - response = self.stub.DetectAttack(request) - LOGGER.debug('DetectAttack result: {:s}'.format(str(response))) - return response - - @RETRY_DECORATOR - def ReportSummarizedKpi(self, request : KpiList) -> Empty: - LOGGER.debug('ReportSummarizedKpi request: {:s}'.format(str(request))) - response = self.stub.ReportSummarizedKpi(request) - LOGGER.debug('ReportSummarizedKpi result: {:s}'.format(str(response))) - return response - - @RETRY_DECORATOR - def ReportKpi(self, request : KpiList) -> Empty: - LOGGER.debug('ReportKpi request: {:s}'.format(str(request))) - response = self.stub.ReportKpi(request) - LOGGER.debug('ReportKpi result: {:s}'.format(str(response))) - return response diff --git a/src/opticalcentralizedattackdetector/genproto.sh b/src/opticalcentralizedattackdetector/genproto.sh deleted file mode 100755 index 85941a266c1def6f352d5ade7bfe5b9e99309fd9..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/genproto.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -# Make folder containing the script the root folder for its execution -cd $(dirname $0) - -rm -rf proto/*.py -rm -rf proto/__pycache__ -tee proto/__init__.py << EOF > /dev/null -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -EOF - -# building protos of services used -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto service.proto -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto monitoring.proto -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto - -rm proto/context_pb2_grpc.py -rm proto/service_pb2_grpc.py -rm proto/monitoring_pb2_grpc.py -rm proto/kpi_sample_types_pb2_grpc.py - -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/service_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/monitoring_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py - -# building current service protos -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto optical_centralized_attack_detector.proto - -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/optical_centralized_attack_detector_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/optical_centralized_attack_detector_pb2_grpc.py diff --git a/src/opticalcentralizedattackdetector/proto/context_pb2.py b/src/opticalcentralizedattackdetector/proto/context_pb2.py deleted file mode 100644 index 50d501d3ac053ad644554331af26e3c40cd426a1..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/proto/context_pb2.py +++ /dev/null @@ -1,3071 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: context.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='context.proto', - package='context', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3' - , - dependencies=[kpi__sample__types__pb2.DESCRIPTOR,]) - -_EVENTTYPEENUM = _descriptor.EnumDescriptor( - name='EventTypeEnum', - full_name='context.EventTypeEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_CREATE', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_UPDATE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EVENTTYPE_REMOVE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4310, - serialized_end=4416, -) -_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM) - -EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM) -_DEVICEDRIVERENUM = _descriptor.EnumDescriptor( - name='DeviceDriverEnum', - full_name='context.DeviceDriverEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_OPENCONFIG', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_P4', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEDRIVER_ONF_TR_352', index=5, number=5, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4419, - serialized_end=4616, -) -_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM) - -DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM) -_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor( - name='DeviceOperationalStatusEnum', - full_name='context.DeviceOperationalStatusEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4619, - serialized_end=4762, -) -_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM) - -DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM) -_SERVICETYPEENUM = _descriptor.EnumDescriptor( - name='ServiceTypeEnum', - full_name='context.ServiceTypeEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_L3NM', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_L2NM', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4765, - serialized_end=4894, -) -_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM) - -ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM) -_SERVICESTATUSENUM = _descriptor.EnumDescriptor( - name='ServiceStatusEnum', - full_name='context.ServiceStatusEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_PLANNED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_ACTIVE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=4897, - serialized_end=5033, -) -_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM) - -ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM) -_SLICESTATUSENUM = _descriptor.EnumDescriptor( - name='SliceStatusEnum', - full_name='context.SliceStatusEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_PLANNED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_INIT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_ACTIVE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SLICESTATUS_DEINIT', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=5036, - serialized_end=5175, -) -_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM) - -SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM) -_CONFIGACTIONENUM = _descriptor.EnumDescriptor( - name='ConfigActionEnum', - full_name='context.ConfigActionEnum', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='CONFIGACTION_UNDEFINED', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CONFIGACTION_SET', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CONFIGACTION_DELETE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=5177, - serialized_end=5270, -) -_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM) - -ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM) -EVENTTYPE_UNDEFINED = 0 -EVENTTYPE_CREATE = 1 -EVENTTYPE_UPDATE = 2 -EVENTTYPE_REMOVE = 3 -DEVICEDRIVER_UNDEFINED = 0 -DEVICEDRIVER_OPENCONFIG = 1 -DEVICEDRIVER_TRANSPORT_API = 2 -DEVICEDRIVER_P4 = 3 -DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4 -DEVICEDRIVER_ONF_TR_352 = 5 -DEVICEOPERATIONALSTATUS_UNDEFINED = 0 -DEVICEOPERATIONALSTATUS_DISABLED = 1 -DEVICEOPERATIONALSTATUS_ENABLED = 2 -SERVICETYPE_UNKNOWN = 0 -SERVICETYPE_L3NM = 1 -SERVICETYPE_L2NM = 2 -SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3 -SERVICESTATUS_UNDEFINED = 0 -SERVICESTATUS_PLANNED = 1 -SERVICESTATUS_ACTIVE = 2 -SERVICESTATUS_PENDING_REMOVAL = 3 -SLICESTATUS_UNDEFINED = 0 -SLICESTATUS_PLANNED = 1 -SLICESTATUS_INIT = 2 -SLICESTATUS_ACTIVE = 3 -SLICESTATUS_DEINIT = 4 -CONFIGACTION_UNDEFINED = 0 -CONFIGACTION_SET = 1 -CONFIGACTION_DELETE = 2 - - - -_EMPTY = _descriptor.Descriptor( - name='Empty', - full_name='context.Empty', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=50, - serialized_end=57, -) - - -_UUID = _descriptor.Descriptor( - name='Uuid', - full_name='context.Uuid', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uuid', full_name='context.Uuid.uuid', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=59, - serialized_end=79, -) - - -_EVENT = _descriptor.Descriptor( - name='Event', - full_name='context.Event', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='timestamp', full_name='context.Event.timestamp', index=0, - number=1, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='event_type', full_name='context.Event.event_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=81, - serialized_end=151, -) - - -_CONTEXTID = _descriptor.Descriptor( - name='ContextId', - full_name='context.ContextId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_uuid', full_name='context.ContextId.context_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=153, - serialized_end=201, -) - - -_CONTEXT = _descriptor.Descriptor( - name='Context', - full_name='context.Context', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.Context.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='topology_ids', full_name='context.Context.topology_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_ids', full_name='context.Context.service_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='controller', full_name='context.Context.controller', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=204, - serialized_end=386, -) - - -_CONTEXTIDLIST = _descriptor.Descriptor( - name='ContextIdList', - full_name='context.ContextIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_ids', full_name='context.ContextIdList.context_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=388, - serialized_end=444, -) - - -_CONTEXTLIST = _descriptor.Descriptor( - name='ContextList', - full_name='context.ContextList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='contexts', full_name='context.ContextList.contexts', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=446, - serialized_end=495, -) - - -_CONTEXTEVENT = _descriptor.Descriptor( - name='ContextEvent', - full_name='context.ContextEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.ContextEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='context_id', full_name='context.ContextEvent.context_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=497, - serialized_end=582, -) - - -_TOPOLOGYID = _descriptor.Descriptor( - name='TopologyId', - full_name='context.TopologyId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.TopologyId.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=584, - serialized_end=674, -) - - -_TOPOLOGY = _descriptor.Descriptor( - name='Topology', - full_name='context.Topology', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topology_id', full_name='context.Topology.topology_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_ids', full_name='context.Topology.device_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='link_ids', full_name='context.Topology.link_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=676, - serialized_end=802, -) - - -_TOPOLOGYIDLIST = _descriptor.Descriptor( - name='TopologyIdList', - full_name='context.TopologyIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=804, - serialized_end=863, -) - - -_TOPOLOGYLIST = _descriptor.Descriptor( - name='TopologyList', - full_name='context.TopologyList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topologies', full_name='context.TopologyList.topologies', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=865, - serialized_end=918, -) - - -_TOPOLOGYEVENT = _descriptor.Descriptor( - name='TopologyEvent', - full_name='context.TopologyEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.TopologyEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='topology_id', full_name='context.TopologyEvent.topology_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=920, - serialized_end=1008, -) - - -_DEVICEID = _descriptor.Descriptor( - name='DeviceId', - full_name='context.DeviceId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='device_uuid', full_name='context.DeviceId.device_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1010, - serialized_end=1056, -) - - -_DEVICE = _descriptor.Descriptor( - name='Device', - full_name='context.Device', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='device_id', full_name='context.Device.device_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_type', full_name='context.Device.device_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_config', full_name='context.Device.device_config', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_operational_status', full_name='context.Device.device_operational_status', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_drivers', full_name='context.Device.device_drivers', index=4, - number=5, type=14, cpp_type=8, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_endpoints', full_name='context.Device.device_endpoints', index=5, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1059, - serialized_end=1341, -) - - -_DEVICECONFIG = _descriptor.Descriptor( - name='DeviceConfig', - full_name='context.DeviceConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='config_rules', full_name='context.DeviceConfig.config_rules', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1343, - serialized_end=1400, -) - - -_DEVICEIDLIST = _descriptor.Descriptor( - name='DeviceIdList', - full_name='context.DeviceIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='device_ids', full_name='context.DeviceIdList.device_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1402, - serialized_end=1455, -) - - -_DEVICELIST = _descriptor.Descriptor( - name='DeviceList', - full_name='context.DeviceList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='devices', full_name='context.DeviceList.devices', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1457, - serialized_end=1503, -) - - -_DEVICEEVENT = _descriptor.Descriptor( - name='DeviceEvent', - full_name='context.DeviceEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.DeviceEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_id', full_name='context.DeviceEvent.device_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1505, - serialized_end=1587, -) - - -_LINKID = _descriptor.Descriptor( - name='LinkId', - full_name='context.LinkId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='link_uuid', full_name='context.LinkId.link_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1589, - serialized_end=1631, -) - - -_LINK = _descriptor.Descriptor( - name='Link', - full_name='context.Link', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='link_id', full_name='context.Link.link_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1633, - serialized_end=1721, -) - - -_LINKIDLIST = _descriptor.Descriptor( - name='LinkIdList', - full_name='context.LinkIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='link_ids', full_name='context.LinkIdList.link_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1723, - serialized_end=1770, -) - - -_LINKLIST = _descriptor.Descriptor( - name='LinkList', - full_name='context.LinkList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='links', full_name='context.LinkList.links', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1772, - serialized_end=1812, -) - - -_LINKEVENT = _descriptor.Descriptor( - name='LinkEvent', - full_name='context.LinkEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.LinkEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='link_id', full_name='context.LinkEvent.link_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1814, - serialized_end=1890, -) - - -_SERVICEID = _descriptor.Descriptor( - name='ServiceId', - full_name='context.ServiceId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.ServiceId.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_uuid', full_name='context.ServiceId.service_uuid', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1892, - serialized_end=1980, -) - - -_SERVICE = _descriptor.Descriptor( - name='Service', - full_name='context.Service', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='service_id', full_name='context.Service.service_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_type', full_name='context.Service.service_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_constraints', full_name='context.Service.service_constraints', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_status', full_name='context.Service.service_status', index=4, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_config', full_name='context.Service.service_config', index=5, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1983, - serialized_end=2277, -) - - -_SERVICESTATUS = _descriptor.Descriptor( - name='ServiceStatus', - full_name='context.ServiceStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='service_status', full_name='context.ServiceStatus.service_status', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2279, - serialized_end=2346, -) - - -_SERVICECONFIG = _descriptor.Descriptor( - name='ServiceConfig', - full_name='context.ServiceConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='config_rules', full_name='context.ServiceConfig.config_rules', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2348, - serialized_end=2406, -) - - -_SERVICEIDLIST = _descriptor.Descriptor( - name='ServiceIdList', - full_name='context.ServiceIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='service_ids', full_name='context.ServiceIdList.service_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2408, - serialized_end=2464, -) - - -_SERVICELIST = _descriptor.Descriptor( - name='ServiceList', - full_name='context.ServiceList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='services', full_name='context.ServiceList.services', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2466, - serialized_end=2515, -) - - -_SERVICEEVENT = _descriptor.Descriptor( - name='ServiceEvent', - full_name='context.ServiceEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.ServiceEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_id', full_name='context.ServiceEvent.service_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2517, - serialized_end=2602, -) - - -_SLICEID = _descriptor.Descriptor( - name='SliceId', - full_name='context.SliceId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.SliceId.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2604, - serialized_end=2688, -) - - -_SLICE = _descriptor.Descriptor( - name='Slice', - full_name='context.Slice', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slice_id', full_name='context.Slice.slice_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_constraints', full_name='context.Slice.slice_constraints', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_status', full_name='context.Slice.slice_status', index=5, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2691, - serialized_end=2968, -) - - -_SLICESTATUS = _descriptor.Descriptor( - name='SliceStatus', - full_name='context.SliceStatus', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slice_status', full_name='context.SliceStatus.slice_status', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2970, - serialized_end=3031, -) - - -_SLICEIDLIST = _descriptor.Descriptor( - name='SliceIdList', - full_name='context.SliceIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3033, - serialized_end=3083, -) - - -_SLICELIST = _descriptor.Descriptor( - name='SliceList', - full_name='context.SliceList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='slices', full_name='context.SliceList.slices', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3085, - serialized_end=3128, -) - - -_SLICEEVENT = _descriptor.Descriptor( - name='SliceEvent', - full_name='context.SliceEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.SliceEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='slice_id', full_name='context.SliceEvent.slice_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3130, - serialized_end=3209, -) - - -_CONNECTIONID = _descriptor.Descriptor( - name='ConnectionId', - full_name='context.ConnectionId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3211, - serialized_end=3265, -) - - -_CONNECTION = _descriptor.Descriptor( - name='Connection', - full_name='context.Connection', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connection_id', full_name='context.Connection.connection_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_id', full_name='context.Connection.service_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3268, - serialized_end=3464, -) - - -_CONNECTIONIDLIST = _descriptor.Descriptor( - name='ConnectionIdList', - full_name='context.ConnectionIdList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3466, - serialized_end=3531, -) - - -_CONNECTIONLIST = _descriptor.Descriptor( - name='ConnectionList', - full_name='context.ConnectionList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='connections', full_name='context.ConnectionList.connections', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3533, - serialized_end=3591, -) - - -_CONNECTIONEVENT = _descriptor.Descriptor( - name='ConnectionEvent', - full_name='context.ConnectionEvent', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='event', full_name='context.ConnectionEvent.event', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3593, - serialized_end=3687, -) - - -_ENDPOINTID = _descriptor.Descriptor( - name='EndPointId', - full_name='context.EndPointId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='topology_id', full_name='context.EndPointId.topology_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_id', full_name='context.EndPointId.device_id', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3690, - serialized_end=3820, -) - - -_ENDPOINT = _descriptor.Descriptor( - name='EndPoint', - full_name='context.EndPoint', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2, - number=3, type=14, cpp_type=8, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3823, - serialized_end=3957, -) - - -_CONFIGRULE = _descriptor.Descriptor( - name='ConfigRule', - full_name='context.ConfigRule', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='action', full_name='context.ConfigRule.action', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='resource_key', full_name='context.ConfigRule.resource_key', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='resource_value', full_name='context.ConfigRule.resource_value', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3959, - serialized_end=4060, -) - - -_CONSTRAINT = _descriptor.Descriptor( - name='Constraint', - full_name='context.Constraint', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='constraint_type', full_name='context.Constraint.constraint_type', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='constraint_value', full_name='context.Constraint.constraint_value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4062, - serialized_end=4125, -) - - -_TERAFLOWCONTROLLER = _descriptor.Descriptor( - name='TeraFlowController', - full_name='context.TeraFlowController', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.TeraFlowController.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='ip_address', full_name='context.TeraFlowController.ip_address', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='port', full_name='context.TeraFlowController.port', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4127, - serialized_end=4221, -) - - -_AUTHENTICATIONRESULT = _descriptor.Descriptor( - name='AuthenticationResult', - full_name='context.AuthenticationResult', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='context_id', full_name='context.AuthenticationResult.context_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4223, - serialized_end=4308, -) - -_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM -_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID -_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID -_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID -_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID -_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER -_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID -_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT -_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT -_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID -_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID -_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID -_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID -_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID -_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID -_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID -_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY -_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT -_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID -_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID -_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID -_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG -_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM -_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM -_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT -_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE -_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID -_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE -_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT -_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID -_LINKID.fields_by_name['link_uuid'].message_type = _UUID -_LINK.fields_by_name['link_id'].message_type = _LINKID -_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID -_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID -_LINKLIST.fields_by_name['links'].message_type = _LINK -_LINKEVENT.fields_by_name['event'].message_type = _EVENT -_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID -_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID -_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID -_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID -_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM -_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID -_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT -_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS -_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG -_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM -_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE -_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID -_SERVICELIST.fields_by_name['services'].message_type = _SERVICE -_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT -_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID -_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID -_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID -_SLICE.fields_by_name['slice_id'].message_type = _SLICEID -_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID -_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT -_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID -_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID -_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS -_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM -_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID -_SLICELIST.fields_by_name['slices'].message_type = _SLICE -_SLICEEVENT.fields_by_name['event'].message_type = _EVENT -_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID -_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID -_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID -_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID -_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID -_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID -_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID -_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION -_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT -_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID -_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID -_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID -_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID -_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID -_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE -_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM -_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID -_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID -DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY -DESCRIPTOR.message_types_by_name['Uuid'] = _UUID -DESCRIPTOR.message_types_by_name['Event'] = _EVENT -DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID -DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT -DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST -DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST -DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT -DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID -DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY -DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST -DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST -DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT -DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID -DESCRIPTOR.message_types_by_name['Device'] = _DEVICE -DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG -DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST -DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST -DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT -DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID -DESCRIPTOR.message_types_by_name['Link'] = _LINK -DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST -DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST -DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT -DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID -DESCRIPTOR.message_types_by_name['Service'] = _SERVICE -DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS -DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG -DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST -DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST -DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT -DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID -DESCRIPTOR.message_types_by_name['Slice'] = _SLICE -DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS -DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST -DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST -DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT -DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID -DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION -DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST -DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST -DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT -DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID -DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT -DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE -DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT -DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER -DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT -DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM -DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM -DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM -DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM -DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM -DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM -DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), { - 'DESCRIPTOR' : _EMPTY, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Empty) - }) -_sym_db.RegisterMessage(Empty) - -Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), { - 'DESCRIPTOR' : _UUID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Uuid) - }) -_sym_db.RegisterMessage(Uuid) - -Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), { - 'DESCRIPTOR' : _EVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Event) - }) -_sym_db.RegisterMessage(Event) - -ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextId) - }) -_sym_db.RegisterMessage(ContextId) - -Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Context) - }) -_sym_db.RegisterMessage(Context) - -ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextIdList) - }) -_sym_db.RegisterMessage(ContextIdList) - -ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextList) - }) -_sym_db.RegisterMessage(ContextList) - -ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), { - 'DESCRIPTOR' : _CONTEXTEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ContextEvent) - }) -_sym_db.RegisterMessage(ContextEvent) - -TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyId) - }) -_sym_db.RegisterMessage(TopologyId) - -Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGY, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Topology) - }) -_sym_db.RegisterMessage(Topology) - -TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyIdList) - }) -_sym_db.RegisterMessage(TopologyIdList) - -TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyList) - }) -_sym_db.RegisterMessage(TopologyList) - -TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), { - 'DESCRIPTOR' : _TOPOLOGYEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TopologyEvent) - }) -_sym_db.RegisterMessage(TopologyEvent) - -DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), { - 'DESCRIPTOR' : _DEVICEID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceId) - }) -_sym_db.RegisterMessage(DeviceId) - -Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), { - 'DESCRIPTOR' : _DEVICE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Device) - }) -_sym_db.RegisterMessage(Device) - -DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), { - 'DESCRIPTOR' : _DEVICECONFIG, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceConfig) - }) -_sym_db.RegisterMessage(DeviceConfig) - -DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), { - 'DESCRIPTOR' : _DEVICEIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceIdList) - }) -_sym_db.RegisterMessage(DeviceIdList) - -DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), { - 'DESCRIPTOR' : _DEVICELIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceList) - }) -_sym_db.RegisterMessage(DeviceList) - -DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), { - 'DESCRIPTOR' : _DEVICEEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.DeviceEvent) - }) -_sym_db.RegisterMessage(DeviceEvent) - -LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), { - 'DESCRIPTOR' : _LINKID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkId) - }) -_sym_db.RegisterMessage(LinkId) - -Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), { - 'DESCRIPTOR' : _LINK, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Link) - }) -_sym_db.RegisterMessage(Link) - -LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), { - 'DESCRIPTOR' : _LINKIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkIdList) - }) -_sym_db.RegisterMessage(LinkIdList) - -LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), { - 'DESCRIPTOR' : _LINKLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkList) - }) -_sym_db.RegisterMessage(LinkList) - -LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), { - 'DESCRIPTOR' : _LINKEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.LinkEvent) - }) -_sym_db.RegisterMessage(LinkEvent) - -ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), { - 'DESCRIPTOR' : _SERVICEID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceId) - }) -_sym_db.RegisterMessage(ServiceId) - -Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), { - 'DESCRIPTOR' : _SERVICE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Service) - }) -_sym_db.RegisterMessage(Service) - -ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), { - 'DESCRIPTOR' : _SERVICESTATUS, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceStatus) - }) -_sym_db.RegisterMessage(ServiceStatus) - -ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), { - 'DESCRIPTOR' : _SERVICECONFIG, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceConfig) - }) -_sym_db.RegisterMessage(ServiceConfig) - -ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), { - 'DESCRIPTOR' : _SERVICEIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceIdList) - }) -_sym_db.RegisterMessage(ServiceIdList) - -ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), { - 'DESCRIPTOR' : _SERVICELIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceList) - }) -_sym_db.RegisterMessage(ServiceList) - -ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), { - 'DESCRIPTOR' : _SERVICEEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ServiceEvent) - }) -_sym_db.RegisterMessage(ServiceEvent) - -SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), { - 'DESCRIPTOR' : _SLICEID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceId) - }) -_sym_db.RegisterMessage(SliceId) - -Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), { - 'DESCRIPTOR' : _SLICE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Slice) - }) -_sym_db.RegisterMessage(Slice) - -SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), { - 'DESCRIPTOR' : _SLICESTATUS, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceStatus) - }) -_sym_db.RegisterMessage(SliceStatus) - -SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), { - 'DESCRIPTOR' : _SLICEIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceIdList) - }) -_sym_db.RegisterMessage(SliceIdList) - -SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), { - 'DESCRIPTOR' : _SLICELIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceList) - }) -_sym_db.RegisterMessage(SliceList) - -SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), { - 'DESCRIPTOR' : _SLICEEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.SliceEvent) - }) -_sym_db.RegisterMessage(SliceEvent) - -ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionId) - }) -_sym_db.RegisterMessage(ConnectionId) - -Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTION, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Connection) - }) -_sym_db.RegisterMessage(Connection) - -ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONIDLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionIdList) - }) -_sym_db.RegisterMessage(ConnectionIdList) - -ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONLIST, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionList) - }) -_sym_db.RegisterMessage(ConnectionList) - -ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), { - 'DESCRIPTOR' : _CONNECTIONEVENT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConnectionEvent) - }) -_sym_db.RegisterMessage(ConnectionEvent) - -EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), { - 'DESCRIPTOR' : _ENDPOINTID, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.EndPointId) - }) -_sym_db.RegisterMessage(EndPointId) - -EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), { - 'DESCRIPTOR' : _ENDPOINT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.EndPoint) - }) -_sym_db.RegisterMessage(EndPoint) - -ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), { - 'DESCRIPTOR' : _CONFIGRULE, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.ConfigRule) - }) -_sym_db.RegisterMessage(ConfigRule) - -Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), { - 'DESCRIPTOR' : _CONSTRAINT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.Constraint) - }) -_sym_db.RegisterMessage(Constraint) - -TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), { - 'DESCRIPTOR' : _TERAFLOWCONTROLLER, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.TeraFlowController) - }) -_sym_db.RegisterMessage(TeraFlowController) - -AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), { - 'DESCRIPTOR' : _AUTHENTICATIONRESULT, - '__module__' : 'context_pb2' - # @@protoc_insertion_point(class_scope:context.AuthenticationResult) - }) -_sym_db.RegisterMessage(AuthenticationResult) - - - -_CONTEXTSERVICE = _descriptor.ServiceDescriptor( - name='ContextService', - full_name='context.ContextService', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=5273, - serialized_end=7688, - methods=[ - _descriptor.MethodDescriptor( - name='ListContextIds', - full_name='context.ContextService.ListContextIds', - index=0, - containing_service=None, - input_type=_EMPTY, - output_type=_CONTEXTIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListContexts', - full_name='context.ContextService.ListContexts', - index=1, - containing_service=None, - input_type=_EMPTY, - output_type=_CONTEXTLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetContext', - full_name='context.ContextService.GetContext', - index=2, - containing_service=None, - input_type=_CONTEXTID, - output_type=_CONTEXT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetContext', - full_name='context.ContextService.SetContext', - index=3, - containing_service=None, - input_type=_CONTEXT, - output_type=_CONTEXTID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveContext', - full_name='context.ContextService.RemoveContext', - index=4, - containing_service=None, - input_type=_CONTEXTID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetContextEvents', - full_name='context.ContextService.GetContextEvents', - index=5, - containing_service=None, - input_type=_EMPTY, - output_type=_CONTEXTEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListTopologyIds', - full_name='context.ContextService.ListTopologyIds', - index=6, - containing_service=None, - input_type=_CONTEXTID, - output_type=_TOPOLOGYIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListTopologies', - full_name='context.ContextService.ListTopologies', - index=7, - containing_service=None, - input_type=_CONTEXTID, - output_type=_TOPOLOGYLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetTopology', - full_name='context.ContextService.GetTopology', - index=8, - containing_service=None, - input_type=_TOPOLOGYID, - output_type=_TOPOLOGY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetTopology', - full_name='context.ContextService.SetTopology', - index=9, - containing_service=None, - input_type=_TOPOLOGY, - output_type=_TOPOLOGYID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveTopology', - full_name='context.ContextService.RemoveTopology', - index=10, - containing_service=None, - input_type=_TOPOLOGYID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetTopologyEvents', - full_name='context.ContextService.GetTopologyEvents', - index=11, - containing_service=None, - input_type=_EMPTY, - output_type=_TOPOLOGYEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListDeviceIds', - full_name='context.ContextService.ListDeviceIds', - index=12, - containing_service=None, - input_type=_EMPTY, - output_type=_DEVICEIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListDevices', - full_name='context.ContextService.ListDevices', - index=13, - containing_service=None, - input_type=_EMPTY, - output_type=_DEVICELIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetDevice', - full_name='context.ContextService.GetDevice', - index=14, - containing_service=None, - input_type=_DEVICEID, - output_type=_DEVICE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetDevice', - full_name='context.ContextService.SetDevice', - index=15, - containing_service=None, - input_type=_DEVICE, - output_type=_DEVICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveDevice', - full_name='context.ContextService.RemoveDevice', - index=16, - containing_service=None, - input_type=_DEVICEID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetDeviceEvents', - full_name='context.ContextService.GetDeviceEvents', - index=17, - containing_service=None, - input_type=_EMPTY, - output_type=_DEVICEEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListLinkIds', - full_name='context.ContextService.ListLinkIds', - index=18, - containing_service=None, - input_type=_EMPTY, - output_type=_LINKIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListLinks', - full_name='context.ContextService.ListLinks', - index=19, - containing_service=None, - input_type=_EMPTY, - output_type=_LINKLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetLink', - full_name='context.ContextService.GetLink', - index=20, - containing_service=None, - input_type=_LINKID, - output_type=_LINK, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetLink', - full_name='context.ContextService.SetLink', - index=21, - containing_service=None, - input_type=_LINK, - output_type=_LINKID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveLink', - full_name='context.ContextService.RemoveLink', - index=22, - containing_service=None, - input_type=_LINKID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetLinkEvents', - full_name='context.ContextService.GetLinkEvents', - index=23, - containing_service=None, - input_type=_EMPTY, - output_type=_LINKEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListServiceIds', - full_name='context.ContextService.ListServiceIds', - index=24, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SERVICEIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListServices', - full_name='context.ContextService.ListServices', - index=25, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SERVICELIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetService', - full_name='context.ContextService.GetService', - index=26, - containing_service=None, - input_type=_SERVICEID, - output_type=_SERVICE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetService', - full_name='context.ContextService.SetService', - index=27, - containing_service=None, - input_type=_SERVICE, - output_type=_SERVICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveService', - full_name='context.ContextService.RemoveService', - index=28, - containing_service=None, - input_type=_SERVICEID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetServiceEvents', - full_name='context.ContextService.GetServiceEvents', - index=29, - containing_service=None, - input_type=_EMPTY, - output_type=_SERVICEEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListSliceIds', - full_name='context.ContextService.ListSliceIds', - index=30, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SLICEIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListSlices', - full_name='context.ContextService.ListSlices', - index=31, - containing_service=None, - input_type=_CONTEXTID, - output_type=_SLICELIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetSlice', - full_name='context.ContextService.GetSlice', - index=32, - containing_service=None, - input_type=_SLICEID, - output_type=_SLICE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetSlice', - full_name='context.ContextService.SetSlice', - index=33, - containing_service=None, - input_type=_SLICE, - output_type=_SLICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveSlice', - full_name='context.ContextService.RemoveSlice', - index=34, - containing_service=None, - input_type=_SLICEID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetSliceEvents', - full_name='context.ContextService.GetSliceEvents', - index=35, - containing_service=None, - input_type=_EMPTY, - output_type=_SLICEEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListConnectionIds', - full_name='context.ContextService.ListConnectionIds', - index=36, - containing_service=None, - input_type=_SERVICEID, - output_type=_CONNECTIONIDLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListConnections', - full_name='context.ContextService.ListConnections', - index=37, - containing_service=None, - input_type=_SERVICEID, - output_type=_CONNECTIONLIST, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetConnection', - full_name='context.ContextService.GetConnection', - index=38, - containing_service=None, - input_type=_CONNECTIONID, - output_type=_CONNECTION, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='SetConnection', - full_name='context.ContextService.SetConnection', - index=39, - containing_service=None, - input_type=_CONNECTION, - output_type=_CONNECTIONID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='RemoveConnection', - full_name='context.ContextService.RemoveConnection', - index=40, - containing_service=None, - input_type=_CONNECTIONID, - output_type=_EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetConnectionEvents', - full_name='context.ContextService.GetConnectionEvents', - index=41, - containing_service=None, - input_type=_EMPTY, - output_type=_CONNECTIONEVENT, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE) - -DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalcentralizedattackdetector/proto/kpi_sample_types_pb2.py b/src/opticalcentralizedattackdetector/proto/kpi_sample_types_pb2.py deleted file mode 100644 index ea7fd2f82757d4c3db02d7e2c7817e2787b0b490..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/proto/kpi_sample_types_pb2.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: kpi_sample_types.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='kpi_sample_types.proto', - package='kpi_sample_types', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3' -) - -_KPISAMPLETYPE = _descriptor.EnumDescriptor( - name='KpiSampleType', - full_name='kpi_sample_types.KpiSampleType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=45, - serialized_end=235, -) -_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) - -KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) -KPISAMPLETYPE_UNKNOWN = 0 -KPISAMPLETYPE_PACKETS_TRANSMITTED = 101 -KPISAMPLETYPE_PACKETS_RECEIVED = 102 -KPISAMPLETYPE_BYTES_TRANSMITTED = 201 -KPISAMPLETYPE_BYTES_RECEIVED = 202 - - -DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalcentralizedattackdetector/proto/monitoring_pb2.py b/src/opticalcentralizedattackdetector/proto/monitoring_pb2.py deleted file mode 100644 index b313ebb68f0da37a540898e8c362fd204a799076..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/proto/monitoring_pb2.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: monitoring.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import context_pb2 as context__pb2 -from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='monitoring.proto', - package='monitoring', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x10monitoring.proto\x12\nmonitoring\x1a\rcontext.proto\x1a\x16kpi_sample_types.proto\"\xda\x01\n\rKpiDescriptor\x12\x17\n\x0fkpi_description\x18\x01 \x01(\t\x12\x38\n\x0fkpi_sample_type\x18\x02 \x01(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\x12$\n\tdevice_id\x18\x03 \x01(\x0b\x32\x11.context.DeviceId\x12(\n\x0b\x65ndpoint_id\x18\x04 \x01(\x0b\x32\x13.context.EndPointId\x12&\n\nservice_id\x18\x05 \x01(\x0b\x32\x12.context.ServiceId\"p\n\x11MonitorKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x1b\n\x13sampling_duration_s\x18\x02 \x01(\x02\x12\x1b\n\x13sampling_interval_s\x18\x03 \x01(\x02\"&\n\x05KpiId\x12\x1d\n\x06kpi_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"d\n\x03Kpi\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\'\n\tkpi_value\x18\x04 \x01(\x0b\x32\x14.monitoring.KpiValue\"a\n\x08KpiValue\x12\x10\n\x06intVal\x18\x01 \x01(\rH\x00\x12\x12\n\x08\x66loatVal\x18\x02 \x01(\x02H\x00\x12\x13\n\tstringVal\x18\x03 \x01(\tH\x00\x12\x11\n\x07\x62oolVal\x18\x04 \x01(\x08H\x00\x42\x07\n\x05value\",\n\x07KpiList\x12!\n\x08kpi_list\x18\x01 \x03(\x0b\x32\x0f.monitoring.Kpi2\xf3\x02\n\x11MonitoringService\x12;\n\tCreateKpi\x12\x19.monitoring.KpiDescriptor\x1a\x11.monitoring.KpiId\"\x00\x12\x42\n\x10GetKpiDescriptor\x12\x11.monitoring.KpiId\x1a\x19.monitoring.KpiDescriptor\"\x00\x12/\n\nIncludeKpi\x12\x0f.monitoring.Kpi\x1a\x0e.context.Empty\"\x00\x12=\n\nMonitorKpi\x12\x1d.monitoring.MonitorKpiRequest\x1a\x0e.context.Empty\"\x00\x12\x36\n\x0cGetStreamKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x30\x01\x12\x35\n\rGetInstantKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x62\x06proto3' - , - dependencies=[context__pb2.DESCRIPTOR,kpi__sample__types__pb2.DESCRIPTOR,]) - - - - -_KPIDESCRIPTOR = _descriptor.Descriptor( - name='KpiDescriptor', - full_name='monitoring.KpiDescriptor', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi_description', full_name='monitoring.KpiDescriptor.kpi_description', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_type', full_name='monitoring.KpiDescriptor.kpi_sample_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='device_id', full_name='monitoring.KpiDescriptor.device_id', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='endpoint_id', full_name='monitoring.KpiDescriptor.endpoint_id', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service_id', full_name='monitoring.KpiDescriptor.service_id', index=4, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=72, - serialized_end=290, -) - - -_MONITORKPIREQUEST = _descriptor.Descriptor( - name='MonitorKpiRequest', - full_name='monitoring.MonitorKpiRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.MonitorKpiRequest.kpi_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sampling_duration_s', full_name='monitoring.MonitorKpiRequest.sampling_duration_s', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sampling_interval_s', full_name='monitoring.MonitorKpiRequest.sampling_interval_s', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=292, - serialized_end=404, -) - - -_KPIID = _descriptor.Descriptor( - name='KpiId', - full_name='monitoring.KpiId', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.KpiId.kpi_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=406, - serialized_end=444, -) - - -_KPI = _descriptor.Descriptor( - name='Kpi', - full_name='monitoring.Kpi', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.Kpi.kpi_id', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='timestamp', full_name='monitoring.Kpi.timestamp', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_value', full_name='monitoring.Kpi.kpi_value', index=2, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=446, - serialized_end=546, -) - - -_KPIVALUE = _descriptor.Descriptor( - name='KpiValue', - full_name='monitoring.KpiValue', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='intVal', full_name='monitoring.KpiValue.intVal', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='floatVal', full_name='monitoring.KpiValue.floatVal', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='stringVal', full_name='monitoring.KpiValue.stringVal', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='boolVal', full_name='monitoring.KpiValue.boolVal', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='value', full_name='monitoring.KpiValue.value', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=548, - serialized_end=645, -) - - -_KPILIST = _descriptor.Descriptor( - name='KpiList', - full_name='monitoring.KpiList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi_list', full_name='monitoring.KpiList.kpi_list', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=647, - serialized_end=691, -) - -_KPIDESCRIPTOR.fields_by_name['kpi_sample_type'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE -_KPIDESCRIPTOR.fields_by_name['device_id'].message_type = context__pb2._DEVICEID -_KPIDESCRIPTOR.fields_by_name['endpoint_id'].message_type = context__pb2._ENDPOINTID -_KPIDESCRIPTOR.fields_by_name['service_id'].message_type = context__pb2._SERVICEID -_MONITORKPIREQUEST.fields_by_name['kpi_id'].message_type = _KPIID -_KPIID.fields_by_name['kpi_id'].message_type = context__pb2._UUID -_KPI.fields_by_name['kpi_id'].message_type = _KPIID -_KPI.fields_by_name['kpi_value'].message_type = _KPIVALUE -_KPIVALUE.oneofs_by_name['value'].fields.append( - _KPIVALUE.fields_by_name['intVal']) -_KPIVALUE.fields_by_name['intVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] -_KPIVALUE.oneofs_by_name['value'].fields.append( - _KPIVALUE.fields_by_name['floatVal']) -_KPIVALUE.fields_by_name['floatVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] -_KPIVALUE.oneofs_by_name['value'].fields.append( - _KPIVALUE.fields_by_name['stringVal']) -_KPIVALUE.fields_by_name['stringVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] -_KPIVALUE.oneofs_by_name['value'].fields.append( - _KPIVALUE.fields_by_name['boolVal']) -_KPIVALUE.fields_by_name['boolVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] -_KPILIST.fields_by_name['kpi_list'].message_type = _KPI -DESCRIPTOR.message_types_by_name['KpiDescriptor'] = _KPIDESCRIPTOR -DESCRIPTOR.message_types_by_name['MonitorKpiRequest'] = _MONITORKPIREQUEST -DESCRIPTOR.message_types_by_name['KpiId'] = _KPIID -DESCRIPTOR.message_types_by_name['Kpi'] = _KPI -DESCRIPTOR.message_types_by_name['KpiValue'] = _KPIVALUE -DESCRIPTOR.message_types_by_name['KpiList'] = _KPILIST -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -KpiDescriptor = _reflection.GeneratedProtocolMessageType('KpiDescriptor', (_message.Message,), { - 'DESCRIPTOR' : _KPIDESCRIPTOR, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.KpiDescriptor) - }) -_sym_db.RegisterMessage(KpiDescriptor) - -MonitorKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _MONITORKPIREQUEST, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.MonitorKpiRequest) - }) -_sym_db.RegisterMessage(MonitorKpiRequest) - -KpiId = _reflection.GeneratedProtocolMessageType('KpiId', (_message.Message,), { - 'DESCRIPTOR' : _KPIID, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.KpiId) - }) -_sym_db.RegisterMessage(KpiId) - -Kpi = _reflection.GeneratedProtocolMessageType('Kpi', (_message.Message,), { - 'DESCRIPTOR' : _KPI, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.Kpi) - }) -_sym_db.RegisterMessage(Kpi) - -KpiValue = _reflection.GeneratedProtocolMessageType('KpiValue', (_message.Message,), { - 'DESCRIPTOR' : _KPIVALUE, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.KpiValue) - }) -_sym_db.RegisterMessage(KpiValue) - -KpiList = _reflection.GeneratedProtocolMessageType('KpiList', (_message.Message,), { - 'DESCRIPTOR' : _KPILIST, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.KpiList) - }) -_sym_db.RegisterMessage(KpiList) - - - -_MONITORINGSERVICE = _descriptor.ServiceDescriptor( - name='MonitoringService', - full_name='monitoring.MonitoringService', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=694, - serialized_end=1065, - methods=[ - _descriptor.MethodDescriptor( - name='CreateKpi', - full_name='monitoring.MonitoringService.CreateKpi', - index=0, - containing_service=None, - input_type=_KPIDESCRIPTOR, - output_type=_KPIID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetKpiDescriptor', - full_name='monitoring.MonitoringService.GetKpiDescriptor', - index=1, - containing_service=None, - input_type=_KPIID, - output_type=_KPIDESCRIPTOR, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='IncludeKpi', - full_name='monitoring.MonitoringService.IncludeKpi', - index=2, - containing_service=None, - input_type=_KPI, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='MonitorKpi', - full_name='monitoring.MonitoringService.MonitorKpi', - index=3, - containing_service=None, - input_type=_MONITORKPIREQUEST, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetStreamKpi', - full_name='monitoring.MonitoringService.GetStreamKpi', - index=4, - containing_service=None, - input_type=_KPIID, - output_type=_KPI, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='GetInstantKpi', - full_name='monitoring.MonitoringService.GetInstantKpi', - index=5, - containing_service=None, - input_type=_KPIID, - output_type=_KPI, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_MONITORINGSERVICE) - -DESCRIPTOR.services_by_name['MonitoringService'] = _MONITORINGSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalcentralizedattackdetector/proto/optical_centralized_attack_detector_pb2.py b/src/opticalcentralizedattackdetector/proto/optical_centralized_attack_detector_pb2.py deleted file mode 100644 index b97a93fef290a5d27c2369d3b69d1405ea8a6442..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/proto/optical_centralized_attack_detector_pb2.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: optical_centralized_attack_detector.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import context_pb2 as context__pb2 -from . import monitoring_pb2 as monitoring__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='optical_centralized_attack_detector.proto', - package='centralized_attack_detector', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n)optical_centralized_attack_detector.proto\x12\x1b\x63\x65ntralized_attack_detector\x1a\rcontext.proto\x1a\x10monitoring.proto2\x88\x02\n\'OpticalCentralizedAttackDetectorService\x12\x39\n\x13NotifyServiceUpdate\x12\x10.context.Service\x1a\x0e.context.Empty\"\x00\x12\x30\n\x0c\x44\x65tectAttack\x12\x0e.context.Empty\x1a\x0e.context.Empty\"\x00\x12<\n\x13ReportSummarizedKpi\x12\x13.monitoring.KpiList\x1a\x0e.context.Empty\"\x00\x12\x32\n\tReportKpi\x12\x13.monitoring.KpiList\x1a\x0e.context.Empty\"\x00\x62\x06proto3' - , - dependencies=[context__pb2.DESCRIPTOR,monitoring__pb2.DESCRIPTOR,]) - - - -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - -_OPTICALCENTRALIZEDATTACKDETECTORSERVICE = _descriptor.ServiceDescriptor( - name='OpticalCentralizedAttackDetectorService', - full_name='centralized_attack_detector.OpticalCentralizedAttackDetectorService', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=108, - serialized_end=372, - methods=[ - _descriptor.MethodDescriptor( - name='NotifyServiceUpdate', - full_name='centralized_attack_detector.OpticalCentralizedAttackDetectorService.NotifyServiceUpdate', - index=0, - containing_service=None, - input_type=context__pb2._SERVICE, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='DetectAttack', - full_name='centralized_attack_detector.OpticalCentralizedAttackDetectorService.DetectAttack', - index=1, - containing_service=None, - input_type=context__pb2._EMPTY, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ReportSummarizedKpi', - full_name='centralized_attack_detector.OpticalCentralizedAttackDetectorService.ReportSummarizedKpi', - index=2, - containing_service=None, - input_type=monitoring__pb2._KPILIST, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ReportKpi', - full_name='centralized_attack_detector.OpticalCentralizedAttackDetectorService.ReportKpi', - index=3, - containing_service=None, - input_type=monitoring__pb2._KPILIST, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_OPTICALCENTRALIZEDATTACKDETECTORSERVICE) - -DESCRIPTOR.services_by_name['OpticalCentralizedAttackDetectorService'] = _OPTICALCENTRALIZEDATTACKDETECTORSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalcentralizedattackdetector/proto/optical_centralized_attack_detector_pb2_grpc.py b/src/opticalcentralizedattackdetector/proto/optical_centralized_attack_detector_pb2_grpc.py deleted file mode 100644 index 17b839fa3bbaafb8ecfa795db21ba6baba8cd28b..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/proto/optical_centralized_attack_detector_pb2_grpc.py +++ /dev/null @@ -1,168 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from . import context_pb2 as context__pb2 -from . import monitoring_pb2 as monitoring__pb2 - - -class OpticalCentralizedAttackDetectorServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.NotifyServiceUpdate = channel.unary_unary( - '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/NotifyServiceUpdate', - request_serializer=context__pb2.Service.SerializeToString, - response_deserializer=context__pb2.Empty.FromString, - ) - self.DetectAttack = channel.unary_unary( - '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/DetectAttack', - request_serializer=context__pb2.Empty.SerializeToString, - response_deserializer=context__pb2.Empty.FromString, - ) - self.ReportSummarizedKpi = channel.unary_unary( - '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/ReportSummarizedKpi', - request_serializer=monitoring__pb2.KpiList.SerializeToString, - response_deserializer=context__pb2.Empty.FromString, - ) - self.ReportKpi = channel.unary_unary( - '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/ReportKpi', - request_serializer=monitoring__pb2.KpiList.SerializeToString, - response_deserializer=context__pb2.Empty.FromString, - ) - - -class OpticalCentralizedAttackDetectorServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def NotifyServiceUpdate(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DetectAttack(self, request, context): - """rpc that triggers the attack detection loop - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ReportSummarizedKpi(self, request, context): - """rpc called by the distributed component to report KPIs - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ReportKpi(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_OpticalCentralizedAttackDetectorServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'NotifyServiceUpdate': grpc.unary_unary_rpc_method_handler( - servicer.NotifyServiceUpdate, - request_deserializer=context__pb2.Service.FromString, - response_serializer=context__pb2.Empty.SerializeToString, - ), - 'DetectAttack': grpc.unary_unary_rpc_method_handler( - servicer.DetectAttack, - request_deserializer=context__pb2.Empty.FromString, - response_serializer=context__pb2.Empty.SerializeToString, - ), - 'ReportSummarizedKpi': grpc.unary_unary_rpc_method_handler( - servicer.ReportSummarizedKpi, - request_deserializer=monitoring__pb2.KpiList.FromString, - response_serializer=context__pb2.Empty.SerializeToString, - ), - 'ReportKpi': grpc.unary_unary_rpc_method_handler( - servicer.ReportKpi, - request_deserializer=monitoring__pb2.KpiList.FromString, - response_serializer=context__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'centralized_attack_detector.OpticalCentralizedAttackDetectorService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class OpticalCentralizedAttackDetectorService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def NotifyServiceUpdate(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/NotifyServiceUpdate', - context__pb2.Service.SerializeToString, - context__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DetectAttack(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/DetectAttack', - context__pb2.Empty.SerializeToString, - context__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ReportSummarizedKpi(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/ReportSummarizedKpi', - monitoring__pb2.KpiList.SerializeToString, - context__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ReportKpi(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/centralized_attack_detector.OpticalCentralizedAttackDetectorService/ReportKpi', - monitoring__pb2.KpiList.SerializeToString, - context__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/opticalcentralizedattackdetector/proto/service_pb2.py b/src/opticalcentralizedattackdetector/proto/service_pb2.py deleted file mode 100644 index 8e2806c7685e24ab90a3d59a19f1e4f99ebc9712..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/proto/service_pb2.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: service.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from . import context_pb2 as context__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='service.proto', - package='service', - syntax='proto3', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xb9\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3' - , - dependencies=[context__pb2.DESCRIPTOR,]) - - - -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - -_SERVICESERVICE = _descriptor.ServiceDescriptor( - name='ServiceService', - full_name='service.ServiceService', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=42, - serialized_end=227, - methods=[ - _descriptor.MethodDescriptor( - name='CreateService', - full_name='service.ServiceService.CreateService', - index=0, - containing_service=None, - input_type=context__pb2._SERVICE, - output_type=context__pb2._SERVICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='UpdateService', - full_name='service.ServiceService.UpdateService', - index=1, - containing_service=None, - input_type=context__pb2._SERVICE, - output_type=context__pb2._SERVICEID, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='DeleteService', - full_name='service.ServiceService.DeleteService', - index=2, - containing_service=None, - input_type=context__pb2._SERVICEID, - output_type=context__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_SERVICESERVICE) - -DESCRIPTOR.services_by_name['ServiceService'] = _SERVICESERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/src/opticalcentralizedattackdetector/requirements.txt b/src/opticalcentralizedattackdetector/requirements.txt deleted file mode 100644 index 5d13e7bc5d318c65e5cc0fe8a4501631aa5428ff..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/requirements.txt +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. - -# -# This file is autogenerated by pip-compile with python 3.9 -# To update, run: -# -# pip-compile --output-file=opticalcentralizedattackdetector/requirements.txt opticalcentralizedattackdetector/requirements.in -# -attrs==21.2.0 - # via pytest -certifi==2021.10.8 - # via influxdb-client -grpcio==1.41.0 - # via - # -r opticalcentralizedattackdetector/requirements.in - # grpcio-health-checking -grpcio-health-checking==1.41.0 - # via -r opticalcentralizedattackdetector/requirements.in -influxdb-client==1.23.0 - # via -r opticalcentralizedattackdetector/requirements.in -iniconfig==1.1.1 - # via pytest -packaging==21.0 - # via pytest -pluggy==1.0.0 - # via pytest -prometheus-client==0.11.0 - # via -r opticalcentralizedattackdetector/requirements.in -protobuf==3.18.0 - # via grpcio-health-checking -py==1.10.0 - # via pytest -py-cpuinfo==8.0.0 - # via pytest-benchmark -pyparsing==2.4.7 - # via packaging -pytest==6.2.5 - # via - # -r opticalcentralizedattackdetector/requirements.in - # pytest-benchmark -pytest-benchmark==3.4.1 - # via -r opticalcentralizedattackdetector/requirements.in -python-dateutil==2.8.2 - # via influxdb-client -pytz==2021.3 - # via influxdb-client -redis==3.5.3 - # via -r opticalcentralizedattackdetector/requirements.in -rx==3.2.0 - # via influxdb-client -six==1.16.0 - # via - # grpcio - # influxdb-client - # python-dateutil -toml==0.10.2 - # via pytest -urllib3==1.26.7 - # via influxdb-client - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py deleted file mode 100644 index f281063f47cd7ef79b06640a5588286699d55848..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 -import logging -from concurrent import futures -from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH -from grpc_health.v1.health_pb2 import HealthCheckResponse -from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server -from opticalcentralizedattackdetector.proto.optical_centralized_attack_detector_pb2_grpc import ( - add_OpticalCentralizedAttackDetectorServiceServicer_to_server) -from opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl import ( - OpticalCentralizedAttackDetectorServiceServicerImpl) -from opticalcentralizedattackdetector.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD - -BIND_ADDRESS = '0.0.0.0' -LOGGER = logging.getLogger(__name__) - -class OpticalCentralizedAttackDetectorService: - def __init__( - self, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, - grace_period=GRPC_GRACE_PERIOD): - - self.address = address - self.port = port - self.endpoint = None - self.max_workers = max_workers - self.grace_period = grace_period - self.centralized_attack_detector_servicer = None - self.health_servicer = None - self.pool = None - self.server = None - - def start(self): - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port)) - LOGGER.debug('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format( - str(self.endpoint), str(self.max_workers))) - - self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers) - self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,)) - - self.centralized_attack_detector_servicer = OpticalCentralizedAttackDetectorServiceServicerImpl() - add_OpticalCentralizedAttackDetectorServiceServicer_to_server(self.centralized_attack_detector_servicer, self.server) - - self.health_servicer = HealthServicer( - experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1)) - add_HealthServicer_to_server(self.health_servicer, self.server) - - port = self.server.add_insecure_port(self.endpoint) - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port)) - LOGGER.info('Listening on {:s}...'.format(self.endpoint)) - self.server.start() - self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member - - LOGGER.debug('Service started') - - def stop(self): - LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period))) - self.health_servicer.enter_graceful_shutdown() - self.server.stop(self.grace_period) - LOGGER.debug('Service stopped') diff --git a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py deleted file mode 100644 index c3ca1c1cfc21dd22c3f2f801a8d1c1321274ad29..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, grpc, logging, random -from influxdb import InfluxDBClient -from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method -from context.client.ContextClient import ContextClient -from monitoring.client.MonitoringClient import MonitoringClient -from service.client.ServiceClient import ServiceClient -from dbscanserving.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse, Sample -from dbscanserving.client.DbscanServingClient import DbscanServingClient -from dbscanserving.Config import GRPC_SERVICE_PORT as DBSCANSERVING_GRPC_SERVICE_PORT -from opticalattackmitigator.client.OpticalAttackMitigatorClient import OpticalAttackMitigatorClient -from opticalattackmitigator.proto.optical_attack_mitigator_pb2 import AttackDescription, AttackResponse -from opticalattackmitigator.Config import GRPC_SERVICE_PORT as ATTACK_MITIGATOR_GRPC_SERVICE_PORT -from opticalcentralizedattackdetector.proto.context_pb2 import (Empty, - Context, ContextId, ContextIdList, ContextList, - Service, ServiceId, ServiceIdList, ServiceList -) -from opticalcentralizedattackdetector.proto.monitoring_pb2 import KpiList -from opticalcentralizedattackdetector.proto.optical_centralized_attack_detector_pb2_grpc import ( - OpticalCentralizedAttackDetectorServiceServicer) -from opticalcentralizedattackdetector.Config import ( - INFERENCE_SERVICE_ADDRESS, MONITORING_SERVICE_ADDRESS, ATTACK_MITIGATOR_SERVICE_ADDRESS) - - -LOGGER = logging.getLogger(__name__) - -METRICS_POOL = MetricsPool('OpticalCentralizedAttackDetector', 'RPC') - -INFLUXDB_HOSTNAME = os.environ.get("INFLUXDB_HOSTNAME") -INFLUXDB_USER = os.environ.get("INFLUXDB_USER") -INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD") -INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE") -context_client: ContextClient = ContextClient() -influxdb_client: InfluxDBClient = InfluxDBClient( - host=MONITORING_SERVICE_ADDRESS, port=8086, username=INFLUXDB_USER, password=INFLUXDB_PASSWORD, - database=INFLUXDB_DATABASE) -monitoring_client: MonitoringClient = MonitoringClient() -dbscanserving_client: DbscanServingClient = DbscanServingClient( - address=INFERENCE_SERVICE_ADDRESS, port=DBSCANSERVING_GRPC_SERVICE_PORT) -service_client: ServiceClient = ServiceClient() -attack_mitigator_client: OpticalAttackMitigatorClient = OpticalAttackMitigatorClient( - address=ATTACK_MITIGATOR_SERVICE_ADDRESS, port=ATTACK_MITIGATOR_GRPC_SERVICE_PORT) - - -class OpticalCentralizedAttackDetectorServiceServicerImpl(OpticalCentralizedAttackDetectorServiceServicer): - - def __init__(self): - LOGGER.debug('Creating Servicer...') - LOGGER.debug('Servicer Created') - - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def NotifyServiceUpdate(self, request : Service, context : grpc.ServicerContext) -> Empty: - return Empty() - - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def DetectAttack(self, request : Empty, context : grpc.ServicerContext) -> Empty: - - # retrieve list with current contexts - # import pdb; pdb.set_trace() - context_ids: ContextIdList = context_client.ListContextIds(Empty()) - - # for each context, retrieve list of current services - services = [] - for context_id in context_ids.context_ids: - - context_services: ServiceIdList = context_client.ListServices(context_id) - for service in context_services.services: - services.append(service) - - # get monitoring data for each of the current services - results = influxdb_client.query('select * from samples;') - - for service in services: - for endpoint in service.service_endpoint_ids: - # get instant KPI for this endpoint - LOGGER.warning(f'service: {service.service_id.service_uuid.uuid}\t endpoint: {endpoint.endpoint_uuid.uuid}\tdevice: {endpoint.device_id.device_uuid.uuid}') - # how to get all KPIs for a particular device? - points = results.get_points(tags={'device_id': endpoint.device_id.device_uuid.uuid}) - print('points:', points) - for point in points: - print('\t', point) - - # run attack detection for every service - request: DetectionRequest = DetectionRequest() - - request.num_samples = 310 - request.num_features = 100 - request.eps = 100.5 - request.min_samples = 50 - - for _ in range(200): - grpc_sample = Sample() - for __ in range(100): - grpc_sample.features.append(random.uniform(0., 10.)) - request.samples.append(grpc_sample) - - for _ in range(100): - grpc_sample = Sample() - for __ in range(100): - grpc_sample.features.append(random.uniform(50., 60.)) - request.samples.append(grpc_sample) - - for _ in range(10): - grpc_sample = Sample() - for __ in range(100): - grpc_sample.features.append(random.uniform(5000., 6000.)) - request.samples.append(grpc_sample) - - response: DetectionResponse = dbscanserving_client.Detect(request) - - if -1 in response.cluster_indices: # attack detected - attack = AttackDescription() - attack.cs_id.uuid = service.service_id.service_uuid.uuid - response: AttackResponse = attack_mitigator_client.NotifyAttack(attack) - - # if attack is detected, run the attack mitigator - return Empty() - - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def ReportSummarizedKpi(self, request : KpiList, context : grpc.ServicerContext) -> Empty: - return Empty() - - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def ReportKpi(self, request : KpiList, context : grpc.ServicerContext) -> Empty: - return Empty() diff --git a/src/opticalcentralizedattackdetector/service/__main__.py b/src/opticalcentralizedattackdetector/service/__main__.py deleted file mode 100644 index 89dfe277d1b642727cca1199e250153264aeb5c2..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/service/__main__.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, logging, signal, sys, time, threading, multiprocessing -from prometheus_client import start_http_server - -from common.Settings import get_setting -from opticalcentralizedattackdetector.Config import ( - GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT, - MONITORING_INTERVAL) -from opticalcentralizedattackdetector.proto.context_pb2 import (Empty, - Context, ContextId, ContextIdList, ContextList, - Service, ServiceId, ServiceIdList, ServiceList -) -from opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorService import OpticalCentralizedAttackDetectorService -from opticalcentralizedattackdetector.client.OpticalCentralizedAttackDetectorClient import OpticalCentralizedAttackDetectorClient - -terminate = threading.Event() -LOGGER = None - -client: OpticalCentralizedAttackDetectorClient = None - -def signal_handler(signal, frame): # pylint: disable=redefined-outer-name - LOGGER.warning('Terminate signal received') - terminate.set() - -def detect_attack(monitoring_interval): - time.sleep(10) # wait for the service to start - LOGGER.info("Starting the attack detection loop") - client = OpticalCentralizedAttackDetectorClient(address='localhost', port=GRPC_SERVICE_PORT) - client.connect() - while True: # infinite loop that runs until the terminate is set - if terminate.is_set(): # if terminate is set - LOGGER.warning("Stopping execution...") - client.close() - break # break the while and stop execution - client.DetectAttack(Empty()) - # sleep - LOGGER.debug("Sleeping for {} seconds...".format(monitoring_interval)) - time.sleep(monitoring_interval) - -def main(): - global LOGGER # pylint: disable=global-statement - - service_port = get_setting('OPTICALCENTRALIZEDATTACKDETECTORSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT) - max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) - grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD) - log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) - metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) - monitoring_interval = get_setting('MONITORING_INTERVAL', default=MONITORING_INTERVAL ) - - logging.basicConfig(level=log_level) - LOGGER = logging.getLogger(__name__) - - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - - LOGGER.info('Starting...') - - # Start metrics server - start_http_server(metrics_port) - - # Starting CentralizedCybersecurity service - grpc_service = OpticalCentralizedAttackDetectorService( - port=service_port, max_workers=max_workers, grace_period=grace_period) - grpc_service.start() - - # p = multiprocessing.Process(target=detect_attack, args=(monitoring_interval, )) - # p.start() - detect_attack(monitoring_interval) - - # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass - - LOGGER.info('Terminating...') - grpc_service.stop() - # p.kill() - - LOGGER.info('Bye') - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/src/opticalcentralizedattackdetector/tests/example_objects.py b/src/opticalcentralizedattackdetector/tests/example_objects.py deleted file mode 100644 index a6859bfb4defd4ccb9df318222237efb8e9cb036..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/tests/example_objects.py +++ /dev/null @@ -1,215 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 copy import deepcopy -from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME -from context.proto.context_pb2 import ( - ConfigActionEnum, DeviceDriverEnum, DeviceOperationalStatusEnum, ServiceStatusEnum, ServiceTypeEnum) - -# Some example objects to be used by the tests - -# Helper methods -def config_rule(action, resource_key, resource_value): - return {'action': action, 'resource_key': resource_key, 'resource_value': resource_value} - -def endpoint_id(topology_id, device_id, endpoint_uuid): - return {'topology_id': deepcopy(topology_id), 'device_id': deepcopy(device_id), - 'endpoint_uuid': {'uuid': endpoint_uuid}} - -def endpoint(topology_id, device_id, endpoint_uuid, endpoint_type): - return {'endpoint_id': endpoint_id(topology_id, device_id, endpoint_uuid), 'endpoint_type': endpoint_type} - -## use "deepcopy" to prevent propagating forced changes during tests -CONTEXT_ID = {'context_uuid': {'uuid': DEFAULT_CONTEXT_NAME}} -CONTEXT = { - 'context_id': deepcopy(CONTEXT_ID), - 'topology_ids': [], - 'service_ids': [], -} - -CONTEXT_ID_2 = {'context_uuid': {'uuid': 'test'}} -CONTEXT_2 = { - 'context_id': deepcopy(CONTEXT_ID_2), - 'topology_ids': [], - 'service_ids': [], -} - -TOPOLOGY_ID = { - 'context_id': deepcopy(CONTEXT_ID), - 'topology_uuid': {'uuid': DEFAULT_TOPOLOGY_NAME}, -} -TOPOLOGY = { - 'topology_id': deepcopy(TOPOLOGY_ID), - 'device_ids': [], - 'link_ids': [], -} - -DEVICE1_UUID = 'DEV1' -DEVICE1_ID = {'device_uuid': {'uuid': DEVICE1_UUID}} -DEVICE1 = { - 'device_id': deepcopy(DEVICE1_ID), - 'device_type': 'packet-router', - 'device_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value1'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value2'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value3'), - ]}, - 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, - 'device_drivers': [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_P4], - 'device_endpoints': [ - endpoint(TOPOLOGY_ID, DEVICE1_ID, 'EP2', 'port-packet-100G'), - endpoint(TOPOLOGY_ID, DEVICE1_ID, 'EP3', 'port-packet-100G'), - endpoint(TOPOLOGY_ID, DEVICE1_ID, 'EP100', 'port-packet-10G'), - ], -} - -DEVICE2_UUID = 'DEV2' -DEVICE2_ID = {'device_uuid': {'uuid': DEVICE2_UUID}} -DEVICE2 = { - 'device_id': deepcopy(DEVICE2_ID), - 'device_type': 'packet-router', - 'device_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value4'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value5'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value6'), - ]}, - 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, - 'device_drivers': [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_P4], - 'device_endpoints': [ - endpoint(TOPOLOGY_ID, DEVICE2_ID, 'EP1', 'port-packet-100G'), - endpoint(TOPOLOGY_ID, DEVICE2_ID, 'EP3', 'port-packet-100G'), - endpoint(TOPOLOGY_ID, DEVICE2_ID, 'EP100', 'port-packet-10G'), - ], -} - -DEVICE3_UUID = 'DEV3' -DEVICE3_ID = {'device_uuid': {'uuid': DEVICE3_UUID}} -DEVICE3 = { - 'device_id': deepcopy(DEVICE3_ID), - 'device_type': 'packet-router', - 'device_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value4'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value5'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value6'), - ]}, - 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, - 'device_drivers': [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_P4], - 'device_endpoints': [ - endpoint(TOPOLOGY_ID, DEVICE3_ID, 'EP1', 'port-packet-100G'), - endpoint(TOPOLOGY_ID, DEVICE3_ID, 'EP2', 'port-packet-100G'), - endpoint(TOPOLOGY_ID, DEVICE3_ID, 'EP100', 'port-packet-10G'), - ], -} - -LINK_DEV1_DEV2_UUID = 'DEV1/EP2 ==> DEV2/EP1' -LINK_DEV1_DEV2_ID = {'link_uuid': {'uuid': LINK_DEV1_DEV2_UUID}} -LINK_DEV1_DEV2 = { - 'link_id': deepcopy(LINK_DEV1_DEV2_ID), - 'link_endpoint_ids' : [ - endpoint_id(TOPOLOGY_ID, DEVICE1_ID, 'EP2'), - endpoint_id(TOPOLOGY_ID, DEVICE2_ID, 'EP1'), - ] -} - -LINK_DEV2_DEV3_UUID = 'DEV2/EP3 ==> DEV3/EP2' -LINK_DEV2_DEV3_ID = {'link_uuid': {'uuid': LINK_DEV2_DEV3_UUID}} -LINK_DEV2_DEV3 = { - 'link_id': deepcopy(LINK_DEV2_DEV3_ID), - 'link_endpoint_ids' : [ - endpoint_id(TOPOLOGY_ID, DEVICE2_ID, 'EP3'), - endpoint_id(TOPOLOGY_ID, DEVICE3_ID, 'EP2'), - ] -} - -LINK_DEV1_DEV3_UUID = 'DEV1/EP3 ==> DEV3/EP1' -LINK_DEV1_DEV3_ID = {'link_uuid': {'uuid': LINK_DEV1_DEV3_UUID}} -LINK_DEV1_DEV3 = { - 'link_id': deepcopy(LINK_DEV1_DEV3_ID), - 'link_endpoint_ids' : [ - endpoint_id(TOPOLOGY_ID, DEVICE1_ID, 'EP3'), - endpoint_id(TOPOLOGY_ID, DEVICE3_ID, 'EP1'), - ] -} - -SERVICE_DEV1_DEV2_UUID = 'SVC:DEV1/EP100-DEV2/EP100' -SERVICE_DEV1_DEV2_ID = { - 'context_id': deepcopy(CONTEXT_ID), - 'service_uuid': {'uuid': SERVICE_DEV1_DEV2_UUID}, -} -SERVICE_DEV1_DEV2 = { - 'service_id': deepcopy(SERVICE_DEV1_DEV2_ID), - 'service_type': ServiceTypeEnum.SERVICETYPE_L3NM, - 'service_endpoint_ids' : [ - endpoint_id(TOPOLOGY_ID, DEVICE1_ID, 'EP100'), - endpoint_id(TOPOLOGY_ID, DEVICE2_ID, 'EP100'), - ], - 'service_constraints': [ - {'constraint_type': 'latency_ms', 'constraint_value': '15.2'}, - {'constraint_type': 'jitter_us', 'constraint_value': '1.2'}, - ], - 'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_ACTIVE}, - 'service_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9'), - ]}, -} - -SERVICE_DEV1_DEV3_UUID = 'SVC:DEV1/EP100-DEV3/EP100' -SERVICE_DEV1_DEV3_ID = { - 'context_id': deepcopy(CONTEXT_ID), - 'service_uuid': {'uuid': SERVICE_DEV1_DEV3_UUID}, -} -SERVICE_DEV1_DEV3 = { - 'service_id': deepcopy(SERVICE_DEV1_DEV3_ID), - 'service_type': ServiceTypeEnum.SERVICETYPE_L3NM, - 'service_endpoint_ids' : [ - endpoint_id(TOPOLOGY_ID, DEVICE1_ID, 'EP100'), - endpoint_id(TOPOLOGY_ID, DEVICE3_ID, 'EP100'), - ], - 'service_constraints': [ - {'constraint_type': 'latency_ms', 'constraint_value': '5.8'}, - {'constraint_type': 'jitter_us', 'constraint_value': '0.1'}, - ], - 'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_ACTIVE}, - 'service_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9'), - ]}, -} - -SERVICE_DEV2_DEV3_UUID = 'SVC:DEV2/EP100-DEV3/EP100' -SERVICE_DEV2_DEV3_ID = { - 'context_id': deepcopy(CONTEXT_ID), - 'service_uuid': {'uuid': SERVICE_DEV2_DEV3_UUID}, -} -SERVICE_DEV2_DEV3 = { - 'service_id': deepcopy(SERVICE_DEV2_DEV3_ID), - 'service_type': ServiceTypeEnum.SERVICETYPE_L3NM, - 'service_endpoint_ids' : [ - endpoint_id(TOPOLOGY_ID, DEVICE2_ID, 'EP100'), - endpoint_id(TOPOLOGY_ID, DEVICE3_ID, 'EP100'), - ], - 'service_constraints': [ - {'constraint_type': 'latency_ms', 'constraint_value': '23.1'}, - {'constraint_type': 'jitter_us', 'constraint_value': '3.4'}, - ], - 'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_ACTIVE}, - 'service_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9'), - ]}, -} diff --git a/src/opticalcentralizedattackdetector/tests/test_unitary.py b/src/opticalcentralizedattackdetector/tests/test_unitary.py deleted file mode 100644 index d89ef2fe27a7d284b655698e7ee89e79b230b04b..0000000000000000000000000000000000000000 --- a/src/opticalcentralizedattackdetector/tests/test_unitary.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 unittest.mock import patch -from opticalcentralizedattackdetector.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD -from opticalcentralizedattackdetector.client.OpticalCentralizedAttackDetectorClient import OpticalCentralizedAttackDetectorClient -from opticalcentralizedattackdetector.proto.context_pb2 import ContextIdList, ContextId, Empty, Service, ContextId, ServiceList -from opticalcentralizedattackdetector.proto.monitoring_pb2 import Kpi, KpiList -from opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorService import OpticalCentralizedAttackDetectorService -from .example_objects import CONTEXT_ID, CONTEXT_ID_2, SERVICE_DEV1_DEV2 - -port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports - -LOGGER = logging.getLogger(__name__) -LOGGER.setLevel(logging.DEBUG) - -@pytest.fixture(scope='session') -def optical_centralized_attack_detector_service(): - _service = OpticalCentralizedAttackDetectorService( - port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD) - # mocker_context_client = mock.patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') - # mocker_context_client.start() - - # mocker_influx_db = mock.patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') - # mocker_influx_db.start() - - _service.start() - yield _service - _service.stop() - # mocker_context_client.stop() - # mocker_influx_db.stop() - -@pytest.fixture(scope='session') -def optical_centralized_attack_detector_client(optical_centralized_attack_detector_service): - _client = OpticalCentralizedAttackDetectorClient(address='127.0.0.1', port=port) - yield _client - _client.close() - -def test_notify_service_update(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient): - service = Service() - optical_centralized_attack_detector_client.NotifyServiceUpdate(service) - -def test_detect_attack_no_contexts(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient): - with patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') as context, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') as influxdb: - request = Empty() - optical_centralized_attack_detector_client.DetectAttack(request) - context.ListContextIds.assert_called_once() - influxdb.query.assert_called_once() - context.ListServices.assert_not_called() - -def test_detect_attack_with_context(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient,): - with patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') as context, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') as influxdb: - # setting up the mock - cid_list = ContextIdList() - cid_list.context_ids.append(ContextId(**CONTEXT_ID)) - context.ListContextIds.return_value = cid_list - - # making the test - request = Empty() - optical_centralized_attack_detector_client.DetectAttack(request) - - # checking behavior - context.ListContextIds.assert_called_once() - context.ListServices.assert_called_with(cid_list.context_ids[0]) - influxdb.query.assert_called_once() - -def test_detect_attack_with_contexts(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient,): - with patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') as context, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') as influxdb: - # setting up the mock - cid_list = ContextIdList() - cid_list.context_ids.append(ContextId(**CONTEXT_ID)) - cid_list.context_ids.append(ContextId(**CONTEXT_ID_2)) - context.ListContextIds.return_value = cid_list - - # making the test - request = Empty() - optical_centralized_attack_detector_client.DetectAttack(request) - - # checking behavior - context.ListContextIds.assert_called_once() - context.ListServices.assert_any_call(cid_list.context_ids[0]) - context.ListServices.assert_any_call(cid_list.context_ids[1]) - influxdb.query.assert_called_once() - -def test_detect_attack_with_service(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient,): - with patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') as context, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') as influxdb, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.dbscanserving_client') as dbscan: - - # setting up the mock - cid_list = ContextIdList() - cid_list.context_ids.append(ContextId(**CONTEXT_ID)) - context.ListContextIds.return_value = cid_list - - service_list = ServiceList() - service_list.services.append(Service(**SERVICE_DEV1_DEV2)) - context.ListServices.return_value = service_list - - influxdb.query.return_value.get_points.return_value = [(1, 2), (3, 4)] - - # making the test - request = Empty() - optical_centralized_attack_detector_client.DetectAttack(request) - - # checking behavior - context.ListContextIds.assert_called_once() - context.ListServices.assert_called_with(cid_list.context_ids[0]) - influxdb.query.assert_called_once() - dbscan.Detect.assert_called() - -def test_detect_attack_no_attack(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient,): - with patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') as context, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') as influxdb, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.dbscanserving_client') as dbscan, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.attack_mitigator_client') as mitigator: - - # setting up the mock - cid_list = ContextIdList() - cid_list.context_ids.append(ContextId(**CONTEXT_ID)) - context.ListContextIds.return_value = cid_list - - service_list = ServiceList() - service_list.services.append(Service(**SERVICE_DEV1_DEV2)) - context.ListServices.return_value = service_list - - # dbscan.Detect.return_value = object() - dbscan.Detect.return_value.cluster_indices = [0, 1, 2, 3, 4, 5] - - # making the test - request = Empty() - optical_centralized_attack_detector_client.DetectAttack(request) - - # checking behavior - context.ListContextIds.assert_called_once() - context.ListServices.assert_called_with(cid_list.context_ids[0]) - influxdb.query.assert_called_once() - dbscan.Detect.assert_called() - mitigator.NotifyAttack.assert_not_called() - -def test_detect_attack_with_attack(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient,): - with patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.context_client') as context, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.influxdb_client') as influxdb, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.dbscanserving_client') as dbscan, \ - patch('opticalcentralizedattackdetector.service.OpticalCentralizedAttackDetectorServiceServicerImpl.attack_mitigator_client') as mitigator: - - # setting up the mock - cid_list = ContextIdList() - cid_list.context_ids.append(ContextId(**CONTEXT_ID)) - context.ListContextIds.return_value = cid_list - - service_list = ServiceList() - service_list.services.append(Service(**SERVICE_DEV1_DEV2)) - context.ListServices.return_value = service_list - - # dbscan.Detect.return_value = object() - dbscan.Detect.return_value.cluster_indices = [0, 1, 2, 3, 4, -1] - - # making the test - request = Empty() - optical_centralized_attack_detector_client.DetectAttack(request) - - # checking behavior - context.ListContextIds.assert_called_once() - context.ListServices.assert_called_with(cid_list.context_ids[0]) - influxdb.query.assert_called_once() - dbscan.Detect.assert_called() - mitigator.NotifyAttack.assert_called() - -def test_report_summarized_kpi(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient): - kpi_list = KpiList() - optical_centralized_attack_detector_client.ReportSummarizedKpi(kpi_list) - -def test_report_kpi(optical_centralized_attack_detector_client: OpticalCentralizedAttackDetectorClient): - kpi_list = KpiList() - optical_centralized_attack_detector_client.ReportKpi(kpi_list) diff --git a/src/pathcomp/.gitignore b/src/pathcomp/.gitignore index 48a680bf0f45eb556108c349bc45be896f4219aa..82fc0ca316f8863947b66c3f294444161902e79c 100644 --- a/src/pathcomp/.gitignore +++ b/src/pathcomp/.gitignore @@ -1 +1,4 @@ backend/wireshark +backend/*.o +backend/pathComp +backend/pathComp-dbg diff --git a/src/pathcomp/backend/Makefile b/src/pathcomp/backend/Makefile index 058701098308620cd1a71f3718b934c63646d42a..56d249510497785316c2e0c36ea8ee0e28c461b1 100644 --- a/src/pathcomp/backend/Makefile +++ b/src/pathcomp/backend/Makefile @@ -30,16 +30,16 @@ coverage: CFLAGS += -O0 -ggdb -g -DDEBUG -fprofile-arcs -ftest-coverage -DGCOV coverage: LDFLAGS += -g -lgcov --coverage -fprofile-arcs -ftest-coverage -DGCOV coverage: pathComp-cvr -pathComp: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o - gcc -o pathComp pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o \ +pathComp: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_ear.o pathComp_RESTapi.o + gcc -o pathComp pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_ear.o pathComp_RESTapi.o \ -L/usr/lib/x86_64-linux-gnu/ -lglib-2.0 -luuid $(LDFLAGS) $(LDLIBS) -pathComp-dbg: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o - gcc -o pathComp-dbg pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o \ +pathComp-dbg: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_ear.o pathComp_RESTapi.o + gcc -o pathComp-dbg pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_ear.o pathComp_RESTapi.o \ -L/usr/lib/x86_64-linux-gnu/ -lglib-2.0 -luuid $(LDFLAGS) $(LDLIBS) -pathComp-cvr: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o - gcc -o pathComp-cvr pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o \ +pathComp-cvr: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_ear.o pathComp_RESTapi.o + gcc -o pathComp-cvr pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_ear.o pathComp_RESTapi.o \ -L/usr/lib/x86_64-linux-gnu/ -lglib-2.0 -luuid $(LDFLAGS) $(LDLIBS) pathComp_log.o: pathComp_log.h pathComp_log.c @@ -56,8 +56,11 @@ pathComp_ksp.o: pathComp_log.h pathComp_tools.h pathComp_ksp.h pathComp_ksp.c pathComp_sp.o: pathComp_log.h pathComp_tools.h pathComp_sp.h pathComp_sp.c $(CC) $(CFLAGS) -c pathComp_sp.c -o pathComp_sp.o + +pathComp_ear.o: pathComp_log.h pathComp_tools.h pathComp_ear.h pathComp_ear.c + $(CC) $(CFLAGS) -c pathComp_ear.c -o pathComp_ear.o -pathComp_RESTapi.o: pathComp_tools.h pathComp_log.h pathComp_cjson.h pathComp_ksp.h pathComp_sp.h pathComp_RESTapi.h pathComp_RESTapi.c +pathComp_RESTapi.o: pathComp_tools.h pathComp_log.h pathComp_cjson.h pathComp_ksp.h pathComp_sp.h pathComp_ear.h pathComp_RESTapi.h pathComp_RESTapi.c $(CC) $(CFLAGS) -c pathComp_RESTapi.c -o pathComp_RESTapi.o pathComp.o: pathComp_log.h pathComp_RESTapi.h pathComp.c pathComp.h diff --git a/src/pathcomp/backend/pathComp.c b/src/pathcomp/backend/pathComp.c index aa6c2b7341862a0115581abee7f977edabe93126..537cf378f1d6124ebc7c2a0140c0a408af547254 100644 --- a/src/pathcomp/backend/pathComp.c +++ b/src/pathcomp/backend/pathComp.c @@ -48,10 +48,8 @@ void my_gcov_handler(int signum) // External Variables FILE *logfile = NULL; - // PATH COMP IP address API Client struct in_addr pathComp_IpAddr; - // REST API ENABLED int RESTAPI_ENABLED = 0; diff --git a/src/pathcomp/backend/pathComp_RESTapi.c b/src/pathcomp/backend/pathComp_RESTapi.c index 8ee7f6d82537b7eab297334a0a0dcfad13f8af44..a8c7c7f47aa2f4e88719337d8f09eb955795bf17 100644 --- a/src/pathcomp/backend/pathComp_RESTapi.c +++ b/src/pathcomp/backend/pathComp_RESTapi.c @@ -36,6 +36,7 @@ #include "pathComp_cjson.h" #include "pathComp_ksp.h" #include "pathComp_sp.h" +#include "pathComp_ear.h" #include "pathComp_RESTapi.h" #define ISspace(x) isspace((int)(x)) @@ -50,9 +51,10 @@ guint CLIENT_ID = 0; guint32 paId_req = 0; // Global variables -struct linkList_t* linkList; -struct deviceList_t* deviceList; -struct serviceList_t* serviceList; +GList* linkList; +GList* deviceList; +GList* serviceList; +GList* activeServList; gchar algId[MAX_ALG_ID_LENGTH]; gboolean syncPath = FALSE; @@ -78,8 +80,9 @@ gint find_rl_client_by_fd (gconstpointer data, gconstpointer userdata) struct pathComp_client *client = (struct pathComp_client*)data; gint fd = *(gint *)userdata; - if (client->fd == fd) - return 0; + if (client->fd == fd) { + return 0; + } return -1; } @@ -278,7 +281,6 @@ void add_comp_path_deviceId_endpointId_json(cJSON* pathObj, struct path_t* p, st return; } - //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c @@ -454,7 +456,6 @@ void rapi_response_json_contents (char *body, gint *length, struct compRouteOutp */ ///////////////////////////////////////////////////////////////////////////////////////// void rapi_response_ok (GIOChannel *source, gint httpCode, struct compRouteOutputList_t *compRouteOutputList) { - gint ret = 0; //DEBUG_PC ("Creating the JSON Body and sending the response of the computed Route List"); @@ -526,8 +527,7 @@ void rapi_response_ok (GIOChannel *source, gint httpCode, struct compRouteOutput * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void rapi_response (GIOChannel *source, gint error) -{ +void rapi_response (GIOChannel *source, gint error) { int ret = 0; guchar buftmp[1024]; char * buf = g_malloc0 (sizeof (char) * 2048000); @@ -566,11 +566,94 @@ void rapi_response (GIOChannel *source, gint error) return; } +/////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_RESTapi.c + * @brief parsing topology Identifier Object (contains Context Id and Toplogy UUID) JSON object + * + * @param obj + * @param topology_id + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void parse_topology_Id(cJSON* obj, struct topology_id_t* topology_id) { + g_assert(topology_id); + // Get the context Id (UUID) from the topologyIdObj + cJSON* contextIdObj = cJSON_GetObjectItem(obj, "contextId"); + if (cJSON_IsString(contextIdObj)) { + duplicate_string(topology_id->contextId, contextIdObj->valuestring); + } + // Get the topologyId (UUID) from the topologyIdObj + cJSON* topologyUuidObj = cJSON_GetObjectItem(obj, "topology_uuid"); + if (cJSON_IsString(topologyUuidObj)) { + duplicate_string(topology_id->topology_uuid, topologyUuidObj->valuestring); + } + return; +} + +/////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_RESTapi.c + * @brief parsing EndpointIds JSON object + * + * @param item + * @param serviceEndPointId + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void parse_endPointsIds(cJSON* item, struct service_endpoints_id_t* serviceEndPointId) { + // Get the topology Id Object + cJSON* topologyIdObj = cJSON_GetObjectItem(item, "topology_id"); + if (cJSON_IsObject(topologyIdObj)) { + parse_topology_Id(topologyIdObj, &serviceEndPointId->topology_id); + } + // Get the deviceId (UUID) + cJSON* deviceIdObj = cJSON_GetObjectItem(item, "device_id"); + if (cJSON_IsString(deviceIdObj)) { + duplicate_string(serviceEndPointId->device_uuid, deviceIdObj->valuestring); + DEBUG_PC("DeviceId: %s", serviceEndPointId->device_uuid); + } + // Get the endpointId (UUID) + cJSON* endPointIdObj = cJSON_GetObjectItem(item, "endpoint_uuid"); + if (cJSON_IsString(endPointIdObj)) { + duplicate_string(serviceEndPointId->endpoint_uuid, endPointIdObj->valuestring); + DEBUG_PC("EndPointId: %s", serviceEndPointId->endpoint_uuid); + } + return; +} + +/////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_RESTapi.c + * @brief Function used to parse the array of Endpoint Ids of the active services + * + * @param endPointArray + * @param actServ + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void parse_act_service_endPointsIds_array(cJSON* endPointIdArray, struct activeService_t* actServ) { + g_assert(actServ); + + for (gint i = 0; i < cJSON_GetArraySize(endPointIdArray); i++) { + actServ->num_service_endpoints_id++; + struct service_endpoints_id_t* serviceEndPointId = &(actServ->service_endpoints_id[i]); + cJSON* item = cJSON_GetArrayItem(endPointIdArray, i); + parse_endPointsIds(item, serviceEndPointId); + } + return; +} /////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c - * @brief Function used to parse the array of Endpoint Ids + * @brief Function used to parse the array of Endpoint Ids of the requested services * * @param endPointArray * @param s @@ -586,35 +669,7 @@ void parse_service_endPointsIds_array(cJSON* endPointIdArray, struct service_t* struct service_endpoints_id_t* serviceEndPointId = &(s->service_endpoints_id[i]); cJSON* item = cJSON_GetArrayItem(endPointIdArray, i); - - // Get the topology Id Object - cJSON* topologyIdObj = cJSON_GetObjectItem(item, "topology_id"); - if (cJSON_IsObject(topologyIdObj)) { - // Get the context Id (UUID) from the topologyIdObj - cJSON* contextIdObj = cJSON_GetObjectItem(topologyIdObj, "contextId"); - if (cJSON_IsString(contextIdObj)) { - duplicate_string(serviceEndPointId->topology_id.contextId, contextIdObj->valuestring); - //DEBUG_PC("Service EndPoint [%d]-- ContextId: %s (uuid string format)", i + 1, serviceEndPointId->topology_id.contextId); - } - // Get the topologyId (UUID) from the topologyIdObj - cJSON* topologyUuidObj = cJSON_GetObjectItem(topologyIdObj, "topology_uuid"); - if (cJSON_IsString(topologyUuidObj)) { - duplicate_string(serviceEndPointId->topology_id.topology_uuid, topologyUuidObj->valuestring); - //DEBUG_PC("Service Endpoint (%d) -- TopologyId: %s (uuid string format)", i + 1, serviceEndPointId->topology_id.topology_uuid); - } - } - // Get the deviceId (UUID) - cJSON* deviceIdObj = cJSON_GetObjectItem(item, "device_id"); - if (cJSON_IsString(deviceIdObj)) { - duplicate_string(serviceEndPointId->device_uuid, deviceIdObj->valuestring); - DEBUG_PC("[%d] - DeviceId: %s", i + 1, serviceEndPointId->device_uuid); - } - // Get the endpointId (UUID) - cJSON* endPointIdObj = cJSON_GetObjectItem(item, "endpoint_uuid"); - if (cJSON_IsString(endPointIdObj)) { - duplicate_string(serviceEndPointId->endpoint_uuid, endPointIdObj->valuestring); - DEBUG_PC("[%d] EndPointId: %s", i + 1, serviceEndPointId->endpoint_uuid); - } + parse_endPointsIds(item, serviceEndPointId); } return; } @@ -632,11 +687,8 @@ void parse_service_endPointsIds_array(cJSON* endPointIdArray, struct service_t* */ ///////////////////////////////////////////////////////////////////////////////////////// void parse_service_constraints(cJSON* constraintArray, struct service_t* s) { - for (gint i = 0; i < cJSON_GetArraySize(constraintArray); i++) { - s->num_service_constraints++; - struct constraint_t* constraint = &(s->constraints[i]); cJSON* item = cJSON_GetArrayItem(constraintArray, i); @@ -656,6 +708,38 @@ void parse_service_constraints(cJSON* constraintArray, struct service_t* s) { return; } +/////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_RESTapi.c + * @brief Function used to parse the serviceId information from a JSON obj + * + * @param obj + * @param serviceId + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void parse_json_serviceId(cJSON* obj, struct serviceId_t* serviceId) { + g_assert(obj); + g_assert(serviceId); + + // Get context Id uuid + cJSON* contextIdObj = cJSON_GetObjectItem(obj, "contextId"); + if (cJSON_IsString(contextIdObj)) { + // convert the string in contextId->valuestring in uuid binary format + duplicate_string(serviceId->contextId, contextIdObj->valuestring); + DEBUG_PC("ContextId: %s (uuid string format)", serviceId->contextId); + } + // Get service Id uuid + cJSON* serviceUuidObj = cJSON_GetObjectItem(obj, "service_uuid"); + if (cJSON_IsString(serviceUuidObj)) { + duplicate_string(serviceId->service_uuid, serviceUuidObj->valuestring); + DEBUG_PC("Service UUID: %s (uuid string format)", serviceId->service_uuid); + } + return; +} + /////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c @@ -672,15 +756,15 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { for (gint i = 0; i < cJSON_GetArraySize(serviceArray); i++) { - serviceList->numServiceList++; - struct service_t* service = &(serviceList->services[i]); - + struct service_t* service = g_malloc0(sizeof(struct service_t)); + if (service == NULL) { + DEBUG_PC("Memory allocation error ..."); + exit(-1); + } cJSON* item = cJSON_GetArrayItem(serviceArray, i); - // Get the algorithm Id cJSON* algIdItem = cJSON_GetObjectItem(item, "algId"); - if (cJSON_IsString(algIdItem)) - { + if (cJSON_IsString(algIdItem)) { duplicate_string(service->algId, algIdItem->valuestring); DEBUG_PC ("algId: %s", service->algId); // assumed that all the services request the same algId @@ -689,16 +773,13 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { // Get the syncPaths cJSON* synchPathObj = cJSON_GetObjectItemCaseSensitive(item, "syncPaths"); - if (cJSON_IsBool(synchPathObj)) - { + if (cJSON_IsBool(synchPathObj)) { // Check Synchronization of multiple Paths to attain e.g. global concurrent optimization - if (cJSON_IsTrue(synchPathObj)) - { + if (cJSON_IsTrue(synchPathObj)) { syncPath = TRUE; DEBUG_PC("Path Synchronization is required"); } - if (cJSON_IsFalse(synchPathObj)) - { + if (cJSON_IsFalse(synchPathObj)) { syncPath = FALSE; DEBUG_PC("No Path Synchronization"); } @@ -707,19 +788,7 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { // Get service Id in terms of contextId and service uuids cJSON* serviceIdObj = cJSON_GetObjectItem(item, "serviceId"); if (cJSON_IsObject(serviceIdObj)) { - // Get context Id uuid - cJSON* contextIdObj = cJSON_GetObjectItem(serviceIdObj, "contextId"); - if (cJSON_IsString(contextIdObj)) { - // convert the string in contextId->valuestring in uuid binary format - duplicate_string(service->serviceId.contextId, contextIdObj->valuestring); - DEBUG_PC("ContextId: %s (uuid string format)", service->serviceId.contextId); - } - // Get service Id uuid - cJSON* serviceUuidObj = cJSON_GetObjectItem(serviceIdObj, "service_uuid"); - if (cJSON_IsString(serviceUuidObj)) { - duplicate_string(service->serviceId.service_uuid, serviceUuidObj->valuestring); - DEBUG_PC("Service UUID: %s (uuid string format)", service->serviceId.service_uuid); - } + parse_json_serviceId(serviceIdObj, &service->serviceId); } // Get de service type @@ -742,11 +811,20 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { parse_service_constraints(constraintArray, service); } - // Get the maximum number of paths to be computed (kPaths) - cJSON* kPathsObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths"); - if (cJSON_IsNumber(kPathsObj)){ - service->kPaths = (guint)(kPathsObj->valuedouble); + // Get the maximum number of paths to be computed (kPaths) inspected/explored + cJSON* kPathsInspObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_inspection"); + if (cJSON_IsNumber(kPathsInspObj)){ + service->kPaths_inspected = (guint)(kPathsInspObj->valuedouble); } + + // Get the maximum number of paths to be computed (kPaths) returned + cJSON* kPathsRetpObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_return"); + if (cJSON_IsNumber(kPathsRetpObj)){ + service->kPaths_returned = (guint)(kPathsRetpObj->valuedouble); + } + + // Append the requested service to the serviceList + serviceList = g_list_append(serviceList, service); } return; } @@ -764,7 +842,6 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { */ ///////////////////////////////////////////////////////////////////////////////////////// void parse_capacity_object(cJSON* capacity, struct capacity_t* c) { - cJSON* totalSizeObj = cJSON_GetObjectItem(capacity, "total-size"); if (cJSON_IsObject(totalSizeObj)) { //Get the capacity value @@ -794,9 +871,11 @@ void parse_capacity_object(cJSON* capacity, struct capacity_t* c) { */ ///////////////////////////////////////////////////////////////////////////////////////// void parse_json_device_endpoints_array(cJSON* endPointsArray, struct device_t* d) { - for (gint i = 0; i < cJSON_GetArraySize(endPointsArray); i++) { d->numEndPoints++; + if (d->numEndPoints >= MAX_DEV_ENDPOINT_LENGTH) { + DEBUG_PC("d->numEndPoints(%d) exceeded MAX_DEV_ENDPOINT_LENGTH(%d)", d->numEndPoints, MAX_DEV_ENDPOINT_LENGTH); + } struct endPoint_t* endpoint = &(d->endPoints[i]); cJSON* item = cJSON_GetArrayItem(endPointsArray, i); @@ -807,30 +886,17 @@ void parse_json_device_endpoints_array(cJSON* endPointsArray, struct device_t* d // Get the topology Id Object cJSON* topologyIdObj = cJSON_GetObjectItem(endPointIdObj, "topology_id"); if (cJSON_IsObject(topologyIdObj)) { - // Get the context Id (UUID) from the topologyIdObj - cJSON* contextIdObj = cJSON_GetObjectItem(topologyIdObj, "contextId"); - if (cJSON_IsString(contextIdObj)) { - duplicate_string(endpoint->endPointId.topology_id.contextId, contextIdObj->valuestring); - //DEBUG_PC("Device EndPoint (%d)-- ContextId: %s (uuid string format)", i + 1, endpoint->endPointId.topology_id.contextId); - } - // Get the topologyId (UUID) from the topologyIdObj - cJSON* topologyUuidObj = cJSON_GetObjectItem(topologyIdObj, "topology_uuid"); - if (cJSON_IsString(topologyUuidObj)) { - duplicate_string(endpoint->endPointId.topology_id.topology_uuid, topologyUuidObj->valuestring); - //DEBUG_PC("Device Endpoint (%d) -- TopologyId: %s (uuid string format)", i + 1, endpoint->endPointId.topology_id.topology_uuid); - } + parse_topology_Id(topologyIdObj, &endpoint->endPointId.topology_id); } // Get the deviceId cJSON* deviceIdObj = cJSON_GetObjectItem(endPointIdObj, "device_id"); if (cJSON_IsString(deviceIdObj)) { duplicate_string(endpoint->endPointId.device_id, deviceIdObj->valuestring); - //DEBUG_PC("Device Endpoint (%d) -- Device Id: %s (uuid)", i + 1, endpoint->endPointId.device_id); } // Get the endpoint_uuid cJSON* endPointUuidObj = cJSON_GetObjectItem(endPointIdObj, "endpoint_uuid"); if (cJSON_IsString(endPointUuidObj)) { duplicate_string(endpoint->endPointId.endpoint_uuid, endPointUuidObj->valuestring); - //DEBUG_PC("Device Endpoint (%d) -- EndPoint Uuid: %s (uuid)", i + 1, endpoint->endPointId.endpoint_uuid); } } // Get the EndPoint Type @@ -889,6 +955,20 @@ void parse_json_device_endpoints_array(cJSON* endPointsArray, struct device_t* d //DEBUG_PC("Inter-Domain Remote Id: %s", endpoint->inter_domain_plug_in.inter_domain_plug_in_remote_id); } } + + // Energy consumption per endPoint port + cJSON* energyPortObj = cJSON_GetObjectItem(item, "energy_consumption"); + if (cJSON_IsNumber(energyPortObj)) { + memcpy(&endpoint->energyConsumption, &energyPortObj->valuedouble, sizeof(gdouble)); + DEBUG_PC("Endpoint Energy Consumption: %f", endpoint->energyConsumption); + } + + // Endpoint Operational Status + cJSON* operationalStatusObj = cJSON_GetObjectItem(item, "operational_status"); + if (cJSON_IsNumber(operationalStatusObj)) { + endpoint->operational_status = (gint)(operationalStatusObj->valuedouble); + DEBUG_PC("Endpoint Operational Status: %d", endpoint->operational_status); + } } return; } @@ -907,11 +987,28 @@ void parse_json_device_endpoints_array(cJSON* endPointsArray, struct device_t* d void parsing_json_deviceList_array(cJSON* deviceArray) { DEBUG_PC(""); DEBUG_PC("========= PARSING DEVICE LIST ============"); - for (gint i = 0; i < cJSON_GetArraySize(deviceArray); i++) { - deviceList->numDevices++; - struct device_t* d = &(deviceList->devices[i]); + for (gint i = 0; i < cJSON_GetArraySize(deviceArray); i++) { + struct device_t* d = g_malloc0(sizeof(struct device_t)); + if (d == NULL) { + DEBUG_PC("Memory Allocation Failure"); + exit(-1); + } cJSON* item = cJSON_GetArrayItem(deviceArray, i); + // Get the power idle of the switch + cJSON* powerIdleObj = cJSON_GetObjectItem(item, "power_idle"); + if (cJSON_IsNumber(powerIdleObj)) { + memcpy(&d->power_idle, &powerIdleObj->valuedouble, sizeof(gdouble)); + DEBUG_PC("Power Idle: %f", d->power_idle); + } + + // Get the operational state + cJSON* opeStatusObj = cJSON_GetObjectItem(item, "operational_status"); + if (cJSON_IsNumber(opeStatusObj)) { + d->operational_status = (gint)(opeStatusObj->valuedouble); + DEBUG_PC("Operational Status: %d (0 Undefined, 1 Disabled, 2 Enabled", d->operational_status); + } + // Get the device UUID cJSON* deviceUuidObj = cJSON_GetObjectItem(item, "device_Id"); if (cJSON_IsString(deviceUuidObj)) { @@ -932,6 +1029,8 @@ void parsing_json_deviceList_array(cJSON* deviceArray) { if (cJSON_IsArray(deviceEndpointsArray)) { parse_json_device_endpoints_array(deviceEndpointsArray, d); } + // append the device into the deviceList + deviceList = g_list_append(deviceList, d); } return; } @@ -949,7 +1048,6 @@ void parsing_json_deviceList_array(cJSON* deviceArray) { */ ///////////////////////////////////////////////////////////////////////////////////////// void parse_json_link_endpoints_array(cJSON *endPointsLinkObj, struct link_t* l) { - for (gint i = 0; i < cJSON_GetArraySize(endPointsLinkObj); i++) { //DEBUG_PC("link: %s has %d endPointIds", l->linkId, l->numLinkEndPointIds); l->numLinkEndPointIds++; @@ -963,18 +1061,7 @@ void parse_json_link_endpoints_array(cJSON *endPointsLinkObj, struct link_t* l) // Get the topology Id Object cJSON* topologyIdObj = cJSON_GetObjectItem(endPointIdObj, "topology_id"); if (cJSON_IsObject(topologyIdObj)) { - // Get the context Id (UUID) from the topologyIdObj - cJSON* contextIdObj = cJSON_GetObjectItem(topologyIdObj, "contextId"); - if (cJSON_IsString(contextIdObj)) { - duplicate_string(endPointLink->topology_id.contextId, contextIdObj->valuestring); - //DEBUG_PC("Link EndPoint (%d)-- ContextId: %s (uuid string format)", i + 1, endPointLink->topology_id.contextId); - } - // Get the topologyId (UUID) from the topologyIdObj - cJSON* topologyUuidObj = cJSON_GetObjectItem(topologyIdObj, "topology_uuid"); - if (cJSON_IsString(topologyUuidObj)) { - duplicate_string(endPointLink->topology_id.topology_uuid, topologyUuidObj->valuestring); - //DEBUG_PC("Link Endpoint (%d) -- TopologyId: %s (uuid string format)", i + 1, endPointLink->topology_id.topology_uuid); - } + parse_topology_Id(topologyIdObj, &endPointLink->topology_id); } // Get the deviceId cJSON* deviceIdObj = cJSON_GetObjectItem(endPointIdObj, "device_id"); @@ -1006,21 +1093,23 @@ void parse_json_link_endpoints_array(cJSON *endPointsLinkObj, struct link_t* l) */ ///////////////////////////////////////////////////////////////////////////////////////// void parsing_json_linkList_array(cJSON* linkListArray) { - DEBUG_PC(""); DEBUG_PC("======= PARSING OF THE LINK LIST ARRAY =========="); - for (gint i = 0; i < cJSON_GetArraySize(linkListArray); i++) { - linkList->numLinks++; - struct link_t* l = &(linkList->links[i]); - //l->numLinkEndPointIds = 0; - + for (gint i = 0; i < cJSON_GetArraySize(linkListArray); i++) { + struct link_t* l = g_malloc0(sizeof(struct link_t)); + if (l == NULL) { + DEBUG_PC("Memory Allocation Failure"); + exit(-1); + } cJSON* item = cJSON_GetArrayItem(linkListArray, i); + // Get the link Id (uuid) cJSON* linkIdObj = cJSON_GetObjectItem(item, "link_Id"); if (cJSON_IsString(linkIdObj)) { duplicate_string(l->linkId, linkIdObj->valuestring); DEBUG_PC(" * Link (%d) -- Id: %s (uuid)", i + 1, l->linkId); } + // Get the link endpoints (assumed to be p2p) cJSON* endPointsLinkObj = cJSON_GetObjectItem(item, "link_endpoint_ids"); if (cJSON_IsArray(endPointsLinkObj)) { @@ -1083,6 +1172,7 @@ void parsing_json_linkList_array(cJSON* linkListArray) { //DEBUG_PC("Link (%d) -- Latency: %f", i + 1, l->latency_characteristics.fixed_latency); } } + linkList = g_list_append(linkList, l); } return; } @@ -1100,15 +1190,22 @@ void parsing_json_linkList_array(cJSON* linkListArray) { void generate_reverse_linkList() { DEBUG_PC(""); DEBUG_PC("CREATION OF REVERSE LINKS"); - gint numLinks = linkList->numLinks; - - for (gint i = 0; i < numLinks; i++) { - struct link_t* refLink = &(linkList->links[i]); - struct link_t* newLink = &(linkList->links[numLinks + i]); - linkList->numLinks++; + gint numLinks = g_list_length (linkList); + DEBUG_PC("Initial Number of links in the main List: %d", numLinks); + gint i = 0; + for (GList* ln = g_list_first(linkList); + (ln) && (i < numLinks); + ln = g_list_next(ln), i++) + { + struct link_t* refLink = (struct link_t*)(ln->data); + struct link_t* newLink = g_malloc0(sizeof(struct link_t)); + if (newLink == NULL) { + DEBUG_PC("Memory Allocation Failure"); + exit(-1); + } // Copy the linkId + appending "_rev" duplicate_string(newLink->linkId, refLink->linkId); - strcat(newLink->linkId, "_rev"); + strcat(newLink->linkId, "_rev"); //DEBUG_PC("refLink: %s // newLink: %s", refLink->linkId, newLink->linkId); @@ -1121,7 +1218,7 @@ void generate_reverse_linkList() { exit(-1); } #endif - DEBUG_PC(" * Link[%d] -- Id: %s", numLinks + i, newLink->linkId); + //DEBUG_PC(" * Link[%d] -- Id: %s", numLinks + i, newLink->linkId); //DEBUG_PC("Number of Endpoints in Link: %d", refLink->numLinkEndPointIds); for (gint j = refLink->numLinkEndPointIds - 1, m = 0; j >= 0; j--, m++) { @@ -1131,9 +1228,9 @@ void generate_reverse_linkList() { duplicate_string(newEndPId->topology_id.contextId, refEndPId->topology_id.contextId); duplicate_string(newEndPId->topology_id.topology_uuid, refEndPId->topology_id.topology_uuid); //duplicate the deviceId and endPoint_uuid - duplicate_string(newEndPId->deviceId, refEndPId->deviceId); - duplicate_string(newEndPId->endPointId, refEndPId->endPointId); - DEBUG_PC("refLink Endpoint[%d]: %s(%s)", j, refEndPId->deviceId, refEndPId->endPointId); + duplicate_string(newEndPId->deviceId, refEndPId->endPointId); + duplicate_string(newEndPId->endPointId, refEndPId->deviceId); + //DEBUG_PC("refLink Endpoint[%d]: %s(%s)", j, refEndPId->deviceId, refEndPId->endPointId); //DEBUG_PC("newLink Endpoint[%d]: %s(%s)", m, newEndPId->deviceId, newEndPId->endPointId); newLink->numLinkEndPointIds++; } @@ -1155,11 +1252,87 @@ void generate_reverse_linkList() { // duplicate latency characteristics memcpy(&newLink->latency_characteristics.fixed_latency, &refLink->latency_characteristics.fixed_latency, sizeof(gdouble)); + // Append in the linkList the new creted Link + linkList = g_list_append(linkList, newLink); } - DEBUG_PC("Terminating Reverse Links [total: %d]", linkList->numLinks); + DEBUG_PC("Terminating Reverse Links [total links: %d]", g_list_length(linkList)); return; } +/////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_RESTapi.c + * @brief Function used to parse the JSON object/s for active services + * + * @param actServiceArray + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void parsing_json_activeService_array(cJSON* actServiceArray) { + DEBUG_PC(""); + DEBUG_PC("====== PARSING THE JSON CONTENTS OF THE ACTIVE SERVICES ======="); + + for (gint i = 0; i < cJSON_GetArraySize(actServiceArray); i++) { + struct activeService_t* actServ = g_malloc0(sizeof(struct activeService_t)); + if (actServ == NULL) { + DEBUG_PC("Memory Allocation Failure"); + exit(-1); + } + cJSON* item = cJSON_GetArrayItem(actServiceArray, i); + // ServiceId + cJSON* serviceIdObj = cJSON_GetObjectItem(item, "serviceId"); + if (cJSON_IsObject(serviceIdObj)) { + parse_json_serviceId(serviceIdObj, &actServ->serviceId); + } + // Service Type + cJSON* serviceTypeObj = cJSON_GetObjectItem(item, "serviceType"); + if (cJSON_IsNumber(serviceTypeObj)) + { + actServ->service_type = (guint)(serviceTypeObj->valuedouble); + print_service_type(actServ->service_type); + } + // Service Endpoints + cJSON* endPointIdsArray = cJSON_GetObjectItem(item, "service_endpoints_ids"); + if (cJSON_IsArray(endPointIdsArray)) { + parse_act_service_endPointsIds_array(endPointIdsArray, actServ); + } + // Parsing the active service path + actServ->activeServPath = NULL; + cJSON* actServPathArray = cJSON_GetObjectItem(item, "devices"); + if (cJSON_IsArray(endPointIdsArray)) { + for (gint j = 0; j < cJSON_GetArraySize(actServPathArray); j++) { + struct activeServPath_t* actServPath = g_malloc0(sizeof(struct activeServPath_t)); + if (actServPath == NULL) { + DEBUG_PC("Memory Allocation Failure"); + exit(-1); + } + cJSON* item2 = cJSON_GetArrayItem(item, j); + // Topology Id + cJSON* topologyIdObj = cJSON_GetObjectItem(item2, "topology_id"); + if (cJSON_IsObject(topologyIdObj)) { + parse_topology_Id(topologyIdObj, &actServPath->topology_id); + } + // Device Id + cJSON* deviceIdObj = cJSON_GetObjectItem(item2, "device_id"); + if (cJSON_IsString(deviceIdObj)) { + duplicate_string(actServPath->deviceId, deviceIdObj->valuestring); + } + // EndPointId + cJSON* endPointUUIDObj = cJSON_GetObjectItem(item2, "endpoint_uuid"); + if (cJSON_IsString(endPointUUIDObj)) { + duplicate_string(actServPath->endPointId, endPointUUIDObj->valuestring); + } + // Append element from the Active Service Path (i.e.,topologyId, deviceId and endpointId) + actServ->activeServPath = g_list_append(actServ->activeServPath, actServPath); + } + } + // append into the Actice Service List + activeServList = g_list_append(activeServList, actServ); + } + return; +} /////////////////////////////////////////////////////////////////////////////////////// /** @@ -1176,22 +1349,6 @@ void generate_reverse_linkList() { ///////////////////////////////////////////////////////////////////////////////////////// void parsing_json_obj_pathComp_request(cJSON * root, GIOChannel * source) { - //DEBUG_PC("**"); - if (deviceList == NULL){ - DEBUG_PC ("Device List does not exist ... STOP"); - exit(-1); - } - - if (linkList == NULL) { - DEBUG_PC("Link List does not exist ... STOP") - } - - if (serviceList == NULL) - { - DEBUG_PC ("Service List does not exist ... STOP"); - exit(-1); - } - // Set of services to seek their path and resource selection cJSON* serviceListArray = cJSON_GetObjectItem(root, "serviceList"); if (cJSON_IsArray(serviceListArray)) { @@ -1211,7 +1368,14 @@ void parsing_json_obj_pathComp_request(cJSON * root, GIOChannel * source) // In the context information, if solely the list of links are passed for a single direction, // the reverse direction MUST be created sythetically - generate_reverse_linkList(); + // LGR: deactivated; link duplication needs to be done smartly with TAPI. done manually in topology by now + //generate_reverse_linkList(); + } + + // Get the list of active services + cJSON* actServiceArray = cJSON_GetObjectItem(root, "activeServList"); + if (cJSON_IsArray(actServiceArray)) { + parsing_json_activeService_array(actServiceArray); } return; } @@ -1233,7 +1397,8 @@ gint parsing_json_obj (guchar *data, GIOChannel *source) { char * print = cJSON_Print(root); DEBUG_PC("STARTING PARSING JSON CONTENTS"); - parsing_json_obj_pathComp_request (root, source); + parsing_json_obj_pathComp_request (root, source); + DEBUG_PC("ENDING PARSING JSON CONTENTS"); // Release the root JSON object variable cJSON_free (root); g_free(print); @@ -1293,19 +1458,16 @@ struct pathComp_client * RESTapi_client_create (GIOChannel * channel_client, gin * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void RESTapi_client_close (struct pathComp_client* client) -{ +void RESTapi_client_close (struct pathComp_client* client) { //DEBUG_PC("Closing the client (Id: %d) %p", client->type, client); //DEBUG_PC("Client ibuf: %p || obuf: %p", client->ibuf, client->obuf); - if (client->ibuf != NULL) - { + if (client->ibuf != NULL) { //DEBUG_PC("Client ibuf: %p", client->ibuf); stream_free(client->ibuf); client->ibuf = NULL; } - if (client->obuf != NULL) - { + if (client->obuf != NULL) { //DEBUG_PC("Client obuf: %p", client->obuf); stream_free(client->obuf); client->obuf = NULL; @@ -1331,16 +1493,14 @@ void RESTapi_client_close (struct pathComp_client* client) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void RESTapi_close_operations (GIOChannel * source) -{ +void RESTapi_close_operations (GIOChannel * source) { gint fd = g_io_channel_unix_get_fd (source); //DEBUG_PC ("Stop all the operations over the fd: %d", fd); g_io_channel_flush(source, NULL); GError *error = NULL; g_io_channel_shutdown (source, TRUE, &error); - if(error) - { + if(error) { DEBUG_PC ("An error occurred ..."); } g_io_channel_unref (source); @@ -1360,8 +1520,7 @@ void RESTapi_close_operations (GIOChannel * source) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void RESTapi_stop (struct pathComp_client* client, GIOChannel * source, gint fd) -{ +void RESTapi_stop (struct pathComp_client* client, GIOChannel * source, gint fd) { DEBUG_PC("Client Socket: %d is Stopped", fd); // remove client @@ -1385,38 +1544,31 @@ void RESTapi_stop (struct pathComp_client* client, GIOChannel * source, gint fd) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint RESTapi_get_line (GIOChannel *channel, gchar *buf, gint size) -{ +gint RESTapi_get_line (GIOChannel *channel, gchar *buf, gint size) { gint i = 0; //DEBUG_PC ("\n"); //DEBUG_PC ("----- Read REST API Line(\r\n) ------"); gint n = 0; guchar c = '\0'; // END OF FILE gboolean cr = FALSE; - while (i < size - 1) - { + while (i < size - 1) { n = read_channel (channel, &c, 1); - if (n == -1) - { + if (n == -1) { //DEBUG_PC ("Close the channel and eliminate the client"); return -1; } - if (n > 0) - { + if (n > 0) { //DEBUG_PC ("%c", c); buf[i] = c; i++; - if (c == '\r') - { + if (c == '\r') { cr = TRUE; } - if ((c == '\n') && (cr == TRUE)) - { + if ((c == '\n') && (cr == TRUE)) { break; } } - else - { + else { c = '\n'; buf[i] = c; i++; @@ -1445,8 +1597,7 @@ guint RESTapi_get_method (gchar *buf, gint *j) guint RestApiMethod = 0; gchar method[255]; gint i = 0; - while (!ISspace(buf[*j]) && (i < sizeof(method) - 1)) - { + while (!ISspace(buf[*j]) && (i < sizeof(method) - 1)) { method[i] = buf[*j]; i++; *j = *j + 1; @@ -1456,32 +1607,60 @@ guint RESTapi_get_method (gchar *buf, gint *j) // Check that the methods are GET, POST or PUT if (strcasecmp((const char *)method, "GET") && strcasecmp((const char *)method, "POST") && - strcasecmp ((const char *)method, "HTTP/1.1") && strcasecmp ((const char *)method, "PUT")) - { - DEBUG_PC ("The method: %s is not currently supported ...", method); + strcasecmp ((const char *)method, "HTTP/1.1") && strcasecmp ((const char *)method, "PUT")) { + DEBUG_PC ("%s is not a method ...", method); return RestApiMethod; } // Method selector - if (strncmp ((const char*)method, "GET", 3) == 0) - { + if (strncmp ((const char*)method, "GET", 3) == 0) { RestApiMethod = REST_API_METHOD_GET; } - else if (strncmp ((const char*)method, "POST", 4) == 0) - { + else if (strncmp ((const char*)method, "POST", 4) == 0) { RestApiMethod = REST_API_METHOD_POST; } - else if (strncmp ((const char *)method, "HTTP/1.1", 8) == 0) - { + else if (strncmp ((const char *)method, "HTTP/1.1", 8) == 0) { RestApiMethod = REST_API_METHOD_HTTP; } - else if (strncmp ((const char *)method, "PUT", 3) == 0) - { + else if (strncmp ((const char *)method, "PUT", 3) == 0) { RestApiMethod = REST_API_METHOD_PUT; - } - + } return RestApiMethod; } +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_RESTapi.c + * @brief Function used to check whether it is a supported method, and return the associated numerical id + * + * @param method + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +guint is_rest_api_method(char *method) { + guint RestApiMethod = 0; + if (strcasecmp((const char*)method, "GET") && strcasecmp((const char*)method, "POST") && + strcasecmp((const char*)method, "HTTP/1.1") && strcasecmp((const char*)method, "PUT")) { + DEBUG_PC("The method: %s is not currently supported ...", method); + return RestApiMethod; + } + // Method selector + if (strncmp((const char*)method, "GET", 3) == 0) { + RestApiMethod = REST_API_METHOD_GET; + } + else if (strncmp((const char*)method, "POST", 4) == 0) { + RestApiMethod = REST_API_METHOD_POST; + } + else if (strncmp((const char*)method, "HTTP/1.1", 8) == 0) { + RestApiMethod = REST_API_METHOD_HTTP; + } + else if (strncmp((const char*)method, "PUT", 3) == 0) { + RestApiMethod = REST_API_METHOD_PUT; + } + return RestApiMethod; +} + //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c @@ -1535,8 +1714,7 @@ gint get_url (gchar *buf, gint *j, gchar *url) ///////////////////////////////////////////////////////////////////////////////////////// gint get_version (gchar *buf, gint *j, gchar *version) { // Skip space char - while (ISspace(buf[*j]) && (*j < strlen(buf))) - { + while (ISspace(buf[*j]) && (*j < strlen(buf))) { *j = *j + 1; } //DEBUG_PC ("buf[%d]: %c", *j, buf[*j]); @@ -1553,7 +1731,7 @@ gint get_version (gchar *buf, gint *j, gchar *version) { //DEBUG_PC ("numChar: %d", numChar); memcpy (version, buf + initChar, numChar); version[numChar] = '\0'; - //DEBUG_PC ("version: %s", version); + //DEBUG_PC ("version: %s", version); return numChar; } @@ -1576,8 +1754,7 @@ gint triggering_routeComp (struct compRouteOutputList_t *compRouteList, gchar *a DEBUG_PC("Requested Algorithm: %s", algId); //////////////////// Algorithm Selector (RAId)////////////////////////////////////// // KSP algorithm - if (strncmp ((const char*)algId, "KSP", 3) == 0) - { + if (strncmp ((const char*)algId, "KSP", 3) == 0) { DEBUG_PC ("Alg Id: KSP"); httpCode = pathComp_ksp_alg(compRouteList); } @@ -1586,20 +1763,11 @@ gint triggering_routeComp (struct compRouteOutputList_t *compRouteList, gchar *a DEBUG_PC("Alg Id: SP"); httpCode = pathComp_sp_alg(compRouteList); } -#if 0 - // Infrastructure Abstraction (InA) - else if (strncmp ((const char*)raId, "InA", 3) == 0) - { - //DEBUG_PC ("RA: InA"); - httpCode = ra_InA_alg (compRouteList); - } - // Global Concurrent Optimization (GCO): Resoration / Re-Allocation / Re-Optimization - else if (strncmp ((const char*)raId, "GCO", 3) == 0) - { - //DEBUG_PC ("RA: GCO"); - httpCode = ra_GCO_alg (compRouteList); + // energy-aware routing + else if (strncmp((const char*)algId, "EAR", 3) == 0) { + DEBUG_PC("Alg Id: Energy Aware Routing, EAR"); + httpCode = pathComp_ear_alg(compRouteList); } -#endif return httpCode; } @@ -1616,8 +1784,7 @@ gint triggering_routeComp (struct compRouteOutputList_t *compRouteList, gchar *a * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data) -{ +gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data) { /** some checks */ g_assert(source != NULL); g_assert(data != NULL); @@ -1635,24 +1802,21 @@ gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data) gint fd = g_io_channel_unix_get_fd (source); DEBUG_PC ("fd: %d, cond: %d", fd, cond); - if (cond != G_IO_IN) - { + if (cond != G_IO_IN) { DEBUG_PC ("Something happening with the channel and fd ... (cond: %d)", cond); RESTapi_stop(client, source, fd); return FALSE; } - /** Clear input buffer. */ + // Clear input buffer stream_reset (client->ibuf); // get line gint nbytes = RESTapi_get_line (source, buf, sizeof (buf)); - if (nbytes == -1) - { + if (nbytes == -1) { DEBUG_PC ("nbytes -1 ... CLOSE CLIENT FD and eliminate CLIENT"); RESTapi_stop(client, source, fd); return FALSE; - } - + } if ((buf[0] == '\n') && (nbytes == 1)) { //DEBUG_PC (" -- buf[0] = newline --"); @@ -1661,132 +1825,127 @@ gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data) } gint i = 0, j = 0; - // Get the REST Method - guint RestApiMethod = RESTapi_get_method (buf, &j); - if (RestApiMethod == 0) { - DEBUG_PC ("The method is NOT supported ..."); - RESTapi_unimplemented (source); - RESTapi_stop(client, source, fd); - return FALSE; - } - // get the REST url - gchar url[255]; - i = get_url (buf, &j, url); - url[i] = '\0'; - - // GET - used for checking status of pathComp ... used url /pathComp/api/v1/health - if (RestApiMethod == REST_API_METHOD_GET) { - if (strncmp((const char*)url, "/health", 7) != 0) { - DEBUG_PC("unknown url [%s] for GET method -- Heatlh function", url); - RESTapi_stop(client, source, fd); - exit(-1); + while (1) { + DEBUG_PC("%s", buf); + char word[255]; + while (!ISspace(buf[j]) && (i < sizeof(word) - 1)) { + word[i] = buf[j]; i++; j++; } - else { - DEBUG_PC("Sending API Response OK to health requests"); - rapi_response_ok(source, HTTP_RETURN_CODE_OK, NULL); - return TRUE; + word[i] = '\0'; + // Check if word is bound to a Method, i.e., POST, GET, HTTP/1.1. + guint method = is_rest_api_method(word); + if (method == 0) { + // ignore other REST fields i.e., Host:, User-Agent:, Accept: .... + break; } - } - - // for method POST, PUT check that the url is "/pathComp" - if (RestApiMethod == REST_API_METHOD_POST) { - if (strncmp((const char*)url, "/pathComp/api/v1/compRoute", 26) != 0) - { - DEBUG_PC("Unknown url: %s", url); - RESTapi_stop(client, source, fd); - exit(-1); + // word is bound to a known / supported REST Method + else { + gchar url[255]; + i = get_url(buf, &j, url); + url[i] = '\0'; + // GET - used for checking status of pathComp ... used url /pathComp/api/v1/health + if (method == REST_API_METHOD_GET) { + if (strncmp((const char*)url, "/health", 7) != 0) { + DEBUG_PC("unknown url [%s] for GET method -- Heatlh function", url); + RESTapi_stop(client, source, fd); + exit(-1); + } + else { + DEBUG_PC("Sending API Response OK to health requests"); + rapi_response_ok(source, HTTP_RETURN_CODE_OK, NULL); + return TRUE; + } + } + // for method POST, PUT check that the url is "/pathComp" + if (method == REST_API_METHOD_POST) { + if (strncmp((const char*)url, "/pathComp/api/v1/compRoute", 26) != 0) { + DEBUG_PC("Unknown url: %s", url); + RESTapi_stop(client, source, fd); + exit(-1); + } + } + // get the version + i = get_version(buf, &j, version); + version[i] = '\0'; + break; } } - - // get the version - i = get_version (buf, &j, version); - version[i] = '\0'; - // Assume HTTP/1.1, then there is Host Header memset(buf, '\0', sizeof(buf)); nbytes = RESTapi_get_line(source, buf, sizeof (buf)); - if (nbytes == -1) - { + if (nbytes == -1) { DEBUG_PC ("nbytes -1 ... then close the fd and eliminate associated client"); RESTapi_stop(client, source, fd); return FALSE; - } - - //DEBUG_PC ("Header: %s", buf); + } // Headers --- The Header Fields ends up with a void line (i.e., \r\n) - while ((nbytes > 0) && (strcmp ("\r\n", (const char *)buf) != 0)) - { + while ((nbytes > 0) && (strcmp ("\r\n", (const char *)buf) != 0)) { /* read & discard headers */ memset(buf, '\0', sizeof(buf)); nbytes = RESTapi_get_line (source, buf, sizeof (buf)); - if (nbytes == -1) - { + if (nbytes == -1) { DEBUG_PC ("nbytes -1 ... then close the fd and eliminate associated client"); RESTapi_stop(client, source, fd); return FALSE; } //DEBUG_PC ("Header: %s", buf); - if (strncmp ((const char *)buf, "Content-Length:", 15) == 0) - { + if (strncmp ((const char *)buf, "Content-Length:", 15) == 0) { //DEBUG_PC ("Header Content-Length Found"); gchar str[20]; gint i = 15, k = 0; // "Content-Length:" We skip the first 16 characters to directly retrieve the length in bytes of the Body of Request gchar contentLength[255]; memset (contentLength, '\0', sizeof (contentLength)); - while (buf[i] != '\r') - { + while (buf[i] != '\r') { //DEBUG_PC ("%c", buf[i]); str[k] = buf[i]; k++, i++; } str[k] = '\0'; j = 0, i = 0; - while (ISspace(str[j]) && (j < strlen(str))) - { + while (ISspace(str[j]) && (j < strlen(str))) { j++; } - while (j < strlen(str)) - { + while (j < strlen(str)) { contentLength[i] = str[j]; i++; j++; } contentLength[i] = '\0'; body_length = atoi (contentLength); - //DEBUG_PC ("Body length: %d (%s) in Bytes", body_length, contentLength); + DEBUG_PC ("Body length: %d (%s) in Bytes", body_length, contentLength); } } - //DEBUG_PC("Read Entire HTTP Header"); - if (body_length == 0) - { + DEBUG_PC("Read Entire HTTP Header"); + if (body_length == 0) { DEBUG_PC ("--- NO REST API Body length (length = %d) ---", body_length); return TRUE; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Processing Body of the Request ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - //DEBUG_PC ("REST API Request - Body -"); + DEBUG_PC ("REST API Request - Body -"); nbytes = read_channel (source, (guchar *)(client->ibuf->data + client->ibuf->putp), body_length); - if ((nbytes < 0) && (body_length > 0)) - { + if ((nbytes < 0) && (body_length > 0)) { DEBUG_PC ("nbytes: %d; body_length: %d", nbytes, body_length); exit (-1); - } - + } client->ibuf->putp += nbytes; client->ibuf->endp += nbytes; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Parsing the contents of the Request /////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // build the device list - deviceList = create_device_list(); + // build the device list + deviceList = NULL; // build the link list - linkList = create_link_list(); + linkList = NULL; // Create the network connectivity service list - serviceList = create_service_list(); + serviceList = NULL; + // Create the active service List + activeServList = NULL; + DEBUG_PC("Parsing JSON..."); // Process the json contents and store relevant information at Device, Link, // and network connectivity service gint ret = parsing_json_obj (client->ibuf->data, source); @@ -1794,32 +1953,32 @@ gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data) DEBUG_PC ("Something wrong with the JSON Objects ... "); RESTapi_stop(client, source, fd); return FALSE; - } + } + DEBUG_PC("Parsing done"); ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Trigger the path computation ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //DEBUG_PC ("Triggering the computation"); + DEBUG_PC ("Triggering the computation"); struct compRouteOutputList_t *compRouteOutputList = create_route_list (); gint httpCode = triggering_routeComp (compRouteOutputList, algId); // Send the response to the REST API Client - if (httpCode != HTTP_RETURN_CODE_OK) - { + if (httpCode != HTTP_RETURN_CODE_OK) { DEBUG_PC ("HTTP CODE: %d -- NO OK", httpCode); rapi_response (source, httpCode); } - else - { + else { DEBUG_PC ("HTTP CODE: %d -- OK", httpCode); rapi_response_ok (source, httpCode, compRouteOutputList); } // Release the variables - g_free (compRouteOutputList); - g_free(linkList); - g_free(deviceList); - g_free(serviceList); + g_free (compRouteOutputList); + g_list_free_full(g_steal_pointer(&linkList), (GDestroyNotify)destroy_link); + g_list_free_full(g_steal_pointer(&deviceList), (GDestroyNotify)destroy_device); + g_list_free_full(g_steal_pointer(&serviceList), (GDestroyNotify)destroy_requested_service); + g_list_free_full(g_steal_pointer(&activeServList), (GDestroyNotify)destroy_active_service); return TRUE; } @@ -1836,23 +1995,20 @@ gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gboolean RESTapi_tcp_new_connection(GIOChannel *source, GIOCondition cond, gpointer data) -{ +gboolean RESTapi_tcp_new_connection(GIOChannel *source, GIOCondition cond, gpointer data) { DEBUG_PC (" ****** New TCP Connection (REST API) ******"); /** get size of client_addre structure */ struct sockaddr_in client_addr; socklen_t client = sizeof(client_addr); - if ((cond == G_IO_HUP) || (cond == G_IO_ERR) || (G_IO_NVAL)) - { + if ((cond == G_IO_HUP) || (cond == G_IO_ERR) || (G_IO_NVAL)) { //DEBUG_PC ("Something happening with the channel and fd ... cond: %d", cond); // Find the associated client (by the fd) and remove from PATH COMP client list. // Stop all the operations over that PATH COMP client bound channel struct pathComp_client *pathComp_client = NULL; gint fd = g_io_channel_unix_get_fd (source); GList *found = g_list_find_custom (RESTapi_tcp_client_list, &fd, find_rl_client_by_fd); - if (found != NULL) - { + if (found != NULL) { pathComp_client = (struct pathComp_client*)(found->data); // remove client RESTapi_client_close(pathComp_client); @@ -1860,30 +2016,24 @@ gboolean RESTapi_tcp_new_connection(GIOChannel *source, GIOCondition cond, gpoin RESTapi_close_operations(source); close (fd); return FALSE; - } + } } - if (cond == G_IO_IN) - { + if (cond == G_IO_IN) { gint new = accept(g_io_channel_unix_get_fd(source), (struct sockaddr*)&client_addr, &client); - if (new < 0) - { + if (new < 0) { //DEBUG_PC ("Unable to accept new connection"); return FALSE; } - /** new channel */ + // new channel GIOChannel * new_channel = g_io_channel_unix_new (new); //DEBUG_PC ("TCP Connection (REST API) is UP; (socket: %d)", new); - - /** create pathComp client */ + // create pathComp client struct pathComp_client *new_client = RESTapi_client_create (new_channel, new); - /** - * force binary encoding with NULL - */ + // force binary encoding with NULL GError *error = NULL; - if ( g_io_channel_set_encoding (new_channel, NULL, &error) != G_IO_STATUS_NORMAL) - { + if ( g_io_channel_set_encoding (new_channel, NULL, &error) != G_IO_STATUS_NORMAL) { DEBUG_PC ("Error: %s", error->message); exit (-1); } @@ -1891,8 +2041,7 @@ gboolean RESTapi_tcp_new_connection(GIOChannel *source, GIOCondition cond, gpoin // On unbuffered channels, it is safe to mix read // & write calls from the new and old APIs. g_io_channel_set_buffered (new_channel, FALSE); - if (g_io_channel_set_flags (new_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL ) - { + if (g_io_channel_set_flags (new_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL ) { DEBUG_PC ("Error: %s", error->message); exit (-1); } diff --git a/src/pathcomp/backend/pathComp_RESTapi.h b/src/pathcomp/backend/pathComp_RESTapi.h index 3b662955959fd8ddad27e337338440b6834f9741..e47c7df4ae0c0190b15cf3b5d5db21322574aa07 100644 --- a/src/pathcomp/backend/pathComp_RESTapi.h +++ b/src/pathcomp/backend/pathComp_RESTapi.h @@ -40,7 +40,7 @@ #define REST_API_METHOD_HTTP 3 #define REST_API_METHOD_PUT 4 -#define MAXLENGTH 131072 +#define MAXLENGTH 1024*1024 // 131072 // LGR: increased stream size; otherwise fails for big networks //////////////////////////////////////////////////// // Client Struct for connecting to PATH COMP SERVER @@ -48,8 +48,7 @@ // List of tcp clients connected to PATH COMP #define PATH_COMP_CLIENT_TYPE 1000 -struct pathComp_client -{ +struct pathComp_client { /** IO Channel from client. */ GIOChannel *channel; diff --git a/src/pathcomp/backend/pathComp_ear.c b/src/pathcomp/backend/pathComp_ear.c new file mode 100644 index 0000000000000000000000000000000000000000..aee3d09f768619f3f6eb40231133fedd30dbb769 --- /dev/null +++ b/src/pathcomp/backend/pathComp_ear.c @@ -0,0 +1,210 @@ +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pathComp_log.h" +#include "pathComp_tools.h" +#include "pathComp_ear.h" + +// Global Variables +GList* contextSet; + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_ear.c + * @brief Iterates over the list of network connectivity service requests + * to compute their own paths fulfilling the constraints and minimizing the + * total consume energy (power) + * + * @param outputList + * + * @author Ricardo Mart�nez + * @date 2022 + */ +void ear_comp_services(struct compRouteOutputList_t* oPathList, gint activeFlag) { + g_assert(oPathList); + // Check at least there is a service to be processed + if (g_list_length(serviceList) == 0) { + DEBUG_PC("serviceList is Empty..."); + return; + } + gint i = 0; + DEBUG_PC("[EAR]----- Starting the Energy Aware Routing Computation ------"); + DEBUG_PC("[EAR]----- Over Context %s Devices and Links", activeFlag ? "Active" : "All"); + for (GList* listnode = g_list_first(serviceList); + listnode; + listnode = g_list_next(listnode), i++) { + struct service_t* service = (struct service_t*)(listnode->data); + + DEBUG_PC("[EAR] Triggering Computation ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); + struct compRouteOutput_t* pathService = &(oPathList->compRouteConnection[i]); + DEBUG_PC("Number of pathService[%d]->paths: %d", i, pathService->numPaths); + // check endpoints of the service are different (PE devices/nodes are different) + if (same_src_dst_pe_nodeid(service) == 0) { + DEBUG_PC("[EAR] PEs are the same... no path computation"); + comp_route_connection_issue_handler(pathService, service); + oPathList->numCompRouteConnList++; + continue; + } + struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId); + if (g == NULL) { + DEBUG_PC("[EAR] contextId: %s NOT in the ContextSet ... then NO graph", service->serviceId.contextId); + comp_route_connection_issue_handler(pathService, service); + oPathList->numCompRouteConnList++; + continue; + } + alg_comp(service, pathService, g, ENERGY_EFFICIENT_ARGUMENT); + oPathList->numCompRouteConnList++; + + // for each network connectivity service, a single computed path (out of the KCSP) is retuned + // If path is found, then the selected resources must be pre-assigned into the context information + if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { + continue; + } + struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); + allocate_graph_resources(path, service, g); + allocate_graph_reverse_resources(path, service, g); + print_graph(g); + } + return; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_ear.c + * @brief Tries to route all the services over the active devices and links. If not all + * these services can be routed, then it is tried to route them through the whole context + * including both active and slept/power off devices and links + * + * @param oList + * + * @author Ricardo Mart�nez + * @date 2022 + */ + //////////////////////////////////////////////////////////////////////////////////////// +void ear_comp(struct compRouteOutputList_t* oList) { + g_assert(oList); + + DEBUG_PC("Number of services to be processed: %d", g_list_length(serviceList)); + // Make a copy of oList to be derived from the active devices and links + struct compRouteOutputList_t* oListTmp = create_route_list(); + duplicate_route_list(oListTmp, oList); + print_path_connection_list(oListTmp); + + // 1st - try to accommodate all the requested service over the active device and links + gint activeContext = 1; + // Create the context for the active devicesand links + DEBUG_PC("=========================== Building the Active ContextSet ================================="); + contextSet = NULL; + build_contextSet_active(&contextSet); + //print_contextSet(contextSet); + ear_comp_services(oListTmp, activeContext); + + gint numSuccessPaths = 0; + // Check the number of succesfully computed paths, i.e., without path issues + for (gint i = 0; i < oListTmp->numCompRouteConnList; i++) { + struct compRouteOutput_t* ro = &(oListTmp->compRouteConnection[i]); + DEBUG_PC("Number of paths: %d for oListTmp[%d]", ro->numPaths, i); + if (ro->noPathIssue == 0) { + numSuccessPaths++; + } + } + if (numSuccessPaths == oListTmp->numCompRouteConnList) { + duplicate_route_list(oList, oListTmp); + g_free(oListTmp); + return; + } + // 2nd - If not all the services have been accommodated, use the whole device and links + // Create the context for all the devices and links + + // Remove the previous Context subject to active devices and links + g_list_free_full(g_steal_pointer(&contextSet), (GDestroyNotify)destroy_context); + contextSet = NULL; + DEBUG_PC("====================== Building the whole ContextSet ====================================="); + build_contextSet(&contextSet); + //print_contextSet(contextSet); + + activeContext = 0; // Active flag is not SET + ear_comp_services(oList, activeContext); + return; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_ear.c + * @brief handles the path computation for energy aware routing + * + * @param compRouteOutput + * + * @author Ricardo Mart�nez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +gint pathComp_ear_alg(struct compRouteOutputList_t* routeConnList) { + g_assert(routeConnList); + print_path_connection_list(routeConnList); + + gint numSuccesPathComp = 0, numPathCompIntents = 0; + + DEBUG_PC("================================================================"); + DEBUG_PC("=========================== EAR ========================="); + DEBUG_PC("================================================================"); + // increase the number of Path Comp. Intents + numPathCompIntents++; + gint http_code = HTTP_CODE_OK; + + // timestamp t0 + struct timeval t0; + gettimeofday(&t0, NULL); + + // Initialize and create the contextSet + //contextSet = NULL; + //build_contextSet(contextSet); + //print_contextSet(contextSet); +#if 1 + //Triggering the path computation for each specific network connectivity service + ear_comp(routeConnList); + + // -- timestamp t1 + struct timeval t1, delta; + gettimeofday(&t1, NULL); + delta.tv_sec = t1.tv_sec - t0.tv_sec; + delta.tv_usec = t1.tv_usec - t0.tv_usec; + delta = tv_adjust(delta); + + numSuccesPathComp++; + update_stats_path_comp(routeConnList, delta, numSuccesPathComp, numPathCompIntents); + print_path_connection_list(routeConnList); +#endif + g_list_free_full(g_steal_pointer(&contextSet), (GDestroyNotify)destroy_context); + return http_code; +} \ No newline at end of file diff --git a/src/pathcomp/backend/pathComp_ear.h b/src/pathcomp/backend/pathComp_ear.h new file mode 100644 index 0000000000000000000000000000000000000000..dff6202568572bfa3343c21c29ad663e167ccfaa --- /dev/null +++ b/src/pathcomp/backend/pathComp_ear.h @@ -0,0 +1,27 @@ +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + */ + +#ifndef _PATHCOMP_EAR_H +#define _PATHCOMP_EAR_H + +#include +#include +#include + + // Prototype of external declaration of functions +gint pathComp_ear_alg(struct compRouteOutputList_t*); + +#endif \ No newline at end of file diff --git a/src/pathcomp/backend/pathComp_ksp.c b/src/pathcomp/backend/pathComp_ksp.c index 4ea413d5eabbccbe1f86a3bc94edca822ffc4e8d..f5e3c8fb8ea854c9acc9fb9f8bc00e3f34a3141a 100644 --- a/src/pathcomp/backend/pathComp_ksp.c +++ b/src/pathcomp/backend/pathComp_ksp.c @@ -36,401 +36,7 @@ #include "pathComp_ksp.h" // Global Variables -struct map_nodes_t *mapNodes; -struct graph_t *graph; -struct contextSet_t* contextSet; - -/////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_ksp.c - * @brief Dijkstra algorithm - * - * @param srcMapIndex - * @param dstMapIndex - * @param g - * @param s - * @param SN - * @param RP - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -void sp_comp(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct service_t* s, - struct nodes_t* SN, struct compRouteOutputItem_t* RP) { - g_assert(s); - g_assert(g); - - // Set params into mapNodes related to the source nodes of the request - mapNodes->map[srcMapIndex].distance = 0.0; - mapNodes->map[srcMapIndex].latency = 0.0; - mapNodes->map[srcMapIndex].avaiBandwidth = 0.0; - - // Initialize the set Q and S - GList* S = NULL, * Q = NULL; - gint indexVertice = -1; - - // Add the source into the Q - struct nodeItem_t* nodeItem = g_malloc0(sizeof(struct nodeItem_t)); - if (nodeItem == NULL) { - DEBUG_PC("memory allocation failed\n"); - exit(-1); - } - // initialize some nodeItem attributes - nodeItem->distance = 0.0; - nodeItem->latency = 0.0; - duplicate_node_id(&mapNodes->map[srcMapIndex].verticeId, &nodeItem->node); - Q = g_list_insert_sorted(Q, nodeItem, sort_by_distance); - - // Check whether there is spurNode (SN) and rootPath (RP) - if (SN != NULL && RP != NULL) { - struct routeElement_t* re; - for (gint j = 0; j < RP->numRouteElements; j++) - { - // Get the source and target Nodes of the routeElement within the rootPath - re = &RP->routeElement[j]; - DEBUG_PC ("root Link: aNodeId: %s (%s) --> zNodeiId: %s (%s)", re->aNodeId.nodeId, re->aEndPointId, re->zNodeId.nodeId, re->zEndPointId); - - // if ingress of the root link (aNodeId) is the spurNode, then stops - if (compare_node_id(&re->aNodeId, SN) == 0) - { - DEBUG_PC ("root Link: aNodeId: %s and spurNode: %s -- stop exploring the rootPath (RP)", re->aNodeId.nodeId, SN->nodeId); - break; - } - // Extract from Q - GList* listnode = g_list_first(Q); - struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); - Q = g_list_remove(Q, node); - - //DEBUG_RL_RA ("Exploring node %s", node->node.nodeId); - indexVertice = graph_vertice_lookup(node->node.nodeId, g); - g_assert(indexVertice >= 0); - - // Get the indexTargetedVertice - gint indexTVertice = -1; - indexTVertice = graph_targeted_vertice_lookup(indexVertice, re->zNodeId.nodeId, g); - gint done = check_link(node, indexVertice, indexTVertice, g, s, &S, &Q, mapNodes); - (void)done; - - // Add to the S list - S = g_list_append(S, node); - } - - // Check that the first node in Q set is SpurNode, otherwise something went wrong ... - if (compare_node_id(&re->aNodeId, SN) != 0) { - //DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId); - g_list_free_full(S, g_free); - g_list_free_full(Q, g_free); - return; - } - } - while (g_list_length(Q) > 0) { - //Extract from Q set - GList* listnode = g_list_first(Q); - struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); - Q = g_list_remove(Q, node); - DEBUG_PC ("Q length: %d", g_list_length (Q)); - DEBUG_PC ("DeviceId: %s", node->node.nodeId); - - // visit all the links from u within the graph - indexVertice = graph_vertice_lookup(node->node.nodeId, g); - g_assert(indexVertice >= 0); - - // Check the targeted vertices from u - for (gint i = 0; i < g->vertices[indexVertice].numTargetedVertices; i++) { - gint done = check_link(node, indexVertice, i, g, s, &S, &Q, mapNodes); - (void)done; - } - // Add node into the S Set - S = g_list_append(S, node); - //DEBUG_PC ("S length: %d", g_list_length (S)); - } - g_list_free_full(S, g_free); - g_list_free_full(Q, g_free); - return; -} - -/////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_ksp.c - * @brief KSP computation using Dijkstra algorithm - * - * @param pred - * @param g - * @param s - * @param SN - * @param RP - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, - struct nodes_t *SN, struct compRouteOutputItem_t *RP) { - g_assert(pred); - g_assert(g); - g_assert(s); - - // Check the both ingress src and dst endpoints are in the graph - gint srcMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[0].device_uuid, mapNodes); - if (srcMapIndex == -1) { - DEBUG_PC("ingress DeviceId: %s NOT in the graph", s->service_endpoints_id[0].device_uuid); - return -1; - } - - gint dstMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); - if (dstMapIndex == -1) { - DEBUG_PC("egress DeviceId: %s NOT in the graph", s->service_endpoints_id[1].device_uuid); - return -1; - } - - // Compute the shortest path route - sp_comp(srcMapIndex, dstMapIndex, g, s, SN, RP); - - // Check that a feasible solution in term of latency and bandwidth is found - gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); - struct map_t* dest_map = &mapNodes->map[map_dstIndex]; - if (!(dest_map->distance < INFINITY_COST)) { - DEBUG_PC("destination: %s NOT reachable", s->service_endpoints_id[1].device_uuid); - return -1; - } - - DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth); - // Check that the computed available bandwidth is larger than 0.0 - if (dest_map->avaiBandwidth <= (gfloat)0.0) { - DEBUG_PC("dst: %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid); - return -1; - } - DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid); - // Handle predecessors - build_predecessors(pred, s, mapNodes); - return 1; -} - -//////////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_ksp.c - * @brief K-CSPF algorithm execution (YEN algorithm) - * - * @param s - * @param path - * @param g - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_t *g) { - g_assert(s); - g_assert(path); - g_assert(g); - - // create map of devices/nodes to handle the path computation using the context - mapNodes = create_map_node(); - build_map_node(mapNodes, g); - - // predecessors to store the computed path - struct pred_t* predecessors = create_predecessors(); - - struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]); - struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]); - - // Compute the 1st KSP path - gint done = ksp_comp (predecessors, g, s, NULL, NULL); - if (done == -1) { - DEBUG_PC("NO PATH FOUND %s[%s] ---> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); - comp_route_connection_issue_handler(path, s); - g_free(mapNodes); g_free(predecessors); - return; - } - - // Construct the path from the computed predecessors - struct compRouteOutputItem_t* p = create_path_item(); - //print_predecessors(predecessors); - build_path(p, predecessors, s); - //DEBUG_PC ("Path is constructed"); - - gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes); - struct map_t* dst_map = &mapNodes->map[indexDest]; - // Get the delay and cost - memcpy(&p->cost, &dst_map->distance, sizeof(gdouble)); - memcpy(&p->availCap, &dst_map->avaiBandwidth, sizeof(dst_map->avaiBandwidth)); - memcpy(&p->delay, &dst_map->latency, sizeof(mapNodes->map[indexDest].latency)); - DEBUG_PC ("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay); - print_path(p); - - // If 1st SP satisfies the requirements from the req, STOP - gboolean feasibleRoute = check_computed_path_feasability(s, p); - if (feasibleRoute == TRUE) { - DEBUG_PC("1st K-CSPF FEASIBLE, STOP!"); - print_path (p); - path->numPaths++; - - // Copy the serviceId - DEBUG_PC("contextId: %s", s->serviceId.contextId); - copy_service_id(&path->serviceId, &s->serviceId); - - // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) - for (gint i = 0; i < s->num_service_endpoints_id; i++) { - struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]); - struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]); - copy_service_endpoint_id(oEp, iEp); - } - path->num_service_endpoints_id = s->num_service_endpoints_id; - - // Copy the computed path - struct path_t* targetedPath = &(path->paths[path->numPaths - 1]); - duplicate_path_t(p, targetedPath); - print_path_t (targetedPath); - g_free(predecessors); - g_free(p); - g_free(mapNodes); - return; - } - - DEBUG_PC("1st CSPF COMPUTATION IS NOT FEASIBLE --> TRIGGER K COMPUTATIONS"); - // Create A and B sets of paths to handle the YEN algorithm - struct path_set_t* A = create_path_set(); - struct path_set_t* B = create_path_set(); - - // Add the previously computed path into A->paths[0] - duplicate_path(p, &A->paths[0]); - - A->numPaths++; - g_free(predecessors); - g_free(p); - for (gint k = 1; k < MAX_KSP_VALUE; k++) { - DEBUG_PC("------------ kth (%d) ---------------------", k); - struct compRouteOutputItem_t* p = create_path_item(); - duplicate_path(&A->paths[k - 1], p); - // The spurNode ranges from near-end node of the first link to the near-end of the last link forming the kth path - gint i = 0; - struct compRouteOutputItem_t* rootPath = create_path_item(); - for (i = 0; i < p->numRouteElements; i++) { - struct nodes_t* spurNode = create_node(); - struct nodes_t* nextSpurNode = create_node(); - struct routeElement_t* re = &(p->routeElement[i]); - // Create predecessors to store the computed path - struct pred_t* predecessors = create_predecessors(); - // Clear previous mapNodes, i.e. create it again - g_free(mapNodes); - mapNodes = create_map_node(); - build_map_node(mapNodes, g); - struct nodes_t* n = &re->aNodeId; - duplicate_node_id(n, spurNode); - n = &re->zNodeId; - duplicate_node_id(n, nextSpurNode); - DEBUG_PC("spurNode: %s --> nextSpurNode: %s", spurNode->nodeId, nextSpurNode->nodeId); - - // rootPath contains a set of links of A[k-1] from the source Node till the SpurNode -> NextSpurNode - // Example: A[k-1] = {L1, L2, L3, L4}, i.e. " Node_a -- L1 --> Node_b -- L2 --> Node_c -- L3 --> Node_d -- L4 --> Node_e " - // E.g., for the ith iteration if the spurNode = Node_c and NextSpurNode = Node_d; then rootPath = {L1, L2, L3} - add_routeElement_path_back(re, rootPath); - DEBUG_PC("rootPath:"); - print_path(rootPath); - - // For all existing and computed paths p in A check if from the source to the NextSpurNode - // the set of links matches with those contained in the rootPath - // If YES, remove from the auxiliary graph the next link in p from NextSpurNode - // Otherwise do nothing - struct graph_t* gAux = create_graph(); - // Baseline graph - //build_graph (gAux); - duplicate_graph(g, gAux); - // Modified graph - modify_targeted_graph(gAux, A, rootPath, spurNode); - - // Trigger the computation of the path from src to dst constrained to traverse all the links from src - // to spurNode contained into rootPath over the resulting graph - if (ksp_comp(predecessors, gAux, s, spurNode, rootPath) == -1) { - DEBUG_PC("FAILED SP from %s via spurNode: %s to %s", iEp->device_uuid, spurNode->nodeId, eEp->device_uuid); - g_free(nextSpurNode); - g_free(spurNode); - g_free(gAux); - g_free(predecessors); - continue; - } - DEBUG_PC("SUCCESFUL SP from %s via spurNode: %s to %s", iEp->device_uuid, spurNode->nodeId, eEp->device_uuid); - // Create the node list from the predecessors - struct compRouteOutputItem_t* newKpath = create_path_item(); - build_path(newKpath, predecessors, s); - DEBUG_PC("new K (for k: %d) Path is built", k); - gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes); - struct map_t* dst_map = &mapNodes->map[indexDest]; - - memcpy(&newKpath->cost, &dst_map->distance, sizeof(gdouble)); - memcpy(&newKpath->availCap, &dst_map->avaiBandwidth, sizeof(dst_map->avaiBandwidth)); - memcpy(&newKpath->delay, &dst_map->latency, sizeof(mapNodes->map[indexDest].latency)); - DEBUG_PC("New PATH (@ kth: %d) ADDED to B[%d] - {Path Cost: %f, e2e latency: %f, bw: %f ", k, B->numPaths, newKpath->cost, newKpath->delay, newKpath->availCap); - // Add the computed kth SP to the heap B - duplicate_path(newKpath, &B->paths[B->numPaths]); - B->numPaths++; - DEBUG_PC("Number of B paths: %d", B->numPaths); - - g_free(newKpath); - g_free(nextSpurNode); - g_free(spurNode); - g_free(gAux); - g_free(predecessors); - } - - // If B is empty then stops - if (B->numPaths == 0) { - DEBUG_PC("B does not have any path ... the stops kth computation"); - break; - } - - // Sort the potential paths contained in B by cost and latency and available bandwidth - sort_path_set(B); - - // Add the lowest path into A[k] - DEBUG_PC("-------------------------------------------------------------"); - DEBUG_PC("To Add SP from B[0] to A[%d] --- Path Cost: %f, e2e Latency: %f", A->numPaths, B->paths[0].cost, B->paths[0].delay); - duplicate_path(&B->paths[0], &A->paths[A->numPaths]); - A->numPaths++; - DEBUG_PC("A Set size: %d", A->numPaths); - DEBUG_PC("-------------------------------------------------------------"); - - // Remove/pòp front element from the path set B (i.e. remove B[0]) - pop_front_path_set(B); - DEBUG_PC("B Set Size: %d", B->numPaths); - } - - // Copy the serviceId - copy_service_id(&path->serviceId, &s->serviceId); - // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) - for (gint m = 0; m < s->num_service_endpoints_id; m++) { - struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[m]); - struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[m]); - copy_service_endpoint_id(oEp, iEp); - } - - for (gint ksp = 1; ksp < A->numPaths; ksp++){ - if (ksp >= MAX_KSP_VALUE) { - DEBUG_PC("Number Requested paths (%d) REACHED - STOP", ksp); - break; - } - gdouble feasibleRoute = check_computed_path_feasability(s, &A->paths[ksp]); - if (feasibleRoute == TRUE) { - DEBUG_PC("A[k-th%d] available: %f, pathCost: %f; latency: %f", ksp, A->paths[ksp].availCap, A->paths[ksp].cost, A->paths[ksp].delay); - struct compRouteOutputItem_t* pathaux = &A->paths[ksp]; - path->numPaths++; - struct path_t* targetedPath = &path->paths[path->numPaths - 1]; - duplicate_path_t(pathaux, targetedPath); - print_path_t(targetedPath); - remove_path_set(A); - remove_path_set(B); - return; - } - } - remove_path_set(A); - remove_path_set(B); - // No paths found --> Issue - DEBUG_PC("K-SP failed!!!"); - comp_route_connection_issue_handler(path, s); - - return; -} +GList* contextSet; //////////////////////////////////////////////////////////////////////////////////////// /** @@ -446,20 +52,25 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ ///////////////////////////////////////////////////////////////////////////////////////// void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { g_assert(outputList); - g_assert(contextSet); - g_assert(serviceList); - + // Check at least there is a service to be processed + if (g_list_length(serviceList) == 0) { + DEBUG_PC("serviceList is Empty..."); + return; + } DEBUG_PC("----- Starting the KSP Computation ------"); // Iterate over the list of requested network connectivity services - for (gint i = 0; i < serviceList->numServiceList; i++) { - struct service_t* service = &(serviceList->services[i]); + gint i = 0; + for (GList* listnode = g_list_first(serviceList); + listnode; + listnode = g_list_next(listnode), i++){ + struct service_t* service = (struct service_t*)(listnode->data); DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); struct compRouteOutput_t* pathService = &(outputList->compRouteConnection[i]); // check endpoints of the service are different (PE devices/nodes are different) if (same_src_dst_pe_nodeid(service) == 0) { - DEBUG_PC("PEs are the same... no path computation"); + DEBUG_PC("PEs are the same... NO PATH COMPUTATION"); comp_route_connection_issue_handler(pathService, service); outputList->numCompRouteConnList++; continue; @@ -472,16 +83,17 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { outputList->numCompRouteConnList++; continue; } - alg_comp(service, pathService, g); + + alg_comp(service, pathService, g, NO_OPTIMIZATION_ARGUMENT); // last parameter 0 is related to an optimization computation argument outputList->numCompRouteConnList++; - // for each network connectivity service, a single computed path (out of the KCSP) is retuned + // for each network connectivity service, a single computed path (out of the KSP) is retuned // If path is found, then the selected resources must be pre-assigned into the context information - if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) - { + if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { continue; } - struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); + // Out of the comnputed paths for the pathservice, the first one is chosen to be locally allocated + struct path_t* path = &(pathService->paths[0]); allocate_graph_resources(path, service, g); allocate_graph_reverse_resources(path, service, g); print_graph(g); @@ -500,8 +112,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) -{ +gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) { g_assert(routeConnList); gint numSuccesPathComp = 0, numPathCompIntents = 0; @@ -517,9 +128,9 @@ gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) gettimeofday(&t0, NULL); // Allocate memory for the context - contextSet = create_contextSet(); + contextSet = NULL; // Build up the contextSet (>= 1) - build_contextSet(contextSet); + build_contextSet(&contextSet); print_contextSet(contextSet); #if 1 //Triggering the path computation for each specific network connectivity service @@ -537,6 +148,6 @@ gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) print_path_connection_list(routeConnList); #endif - g_free(contextSet); + g_list_free_full(g_steal_pointer(&contextSet), (GDestroyNotify)destroy_context); return http_code; } \ No newline at end of file diff --git a/src/pathcomp/backend/pathComp_sp.c b/src/pathcomp/backend/pathComp_sp.c index 447b0d2a6d002d12808f80c855c74f8d0b489743..b6fd885e3fec7032993ef4d058df8256cc363965 100644 --- a/src/pathcomp/backend/pathComp_sp.c +++ b/src/pathcomp/backend/pathComp_sp.c @@ -36,74 +36,7 @@ #include "pathComp_sp.h" // Global Variables -struct map_nodes_t* mapNodes; -struct graph_t* graph; -struct contextSet_t* contextSet; - -/////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_sp.c - * @brief Excecution Dijkstra algorithm - * - * @param srcMapIndex - * @param dstMapIndex - * @param g - * @param s - * - * @author Ricardo Mart�nez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct service_t* s) { - g_assert(s); - g_assert(g); - - // Set params into mapNodes related to the source nodes of the request - mapNodes->map[srcMapIndex].distance = 0.0; - mapNodes->map[srcMapIndex].latency = 0.0; - mapNodes->map[srcMapIndex].avaiBandwidth = 0.0; - - // Initialize the set Q and S - GList* S = NULL, *Q = NULL; - gint indexVertice = -1; - - // Add the source into the Q - struct nodeItem_t* nodeItem = g_malloc0(sizeof(struct nodeItem_t)); - if (nodeItem == NULL) { - DEBUG_PC("memory allocation failed\n"); - exit(-1); - } - // initialize some nodeItem attributes - nodeItem->distance = 0.0; - nodeItem->latency = 0.0; - duplicate_node_id(&mapNodes->map[srcMapIndex].verticeId, &nodeItem->node); - Q = g_list_insert_sorted(Q, nodeItem, sort_by_distance); - - while (g_list_length(Q) > 0) { - //Extract from Q set - GList* listnode = g_list_first(Q); - struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); - Q = g_list_remove(Q, node); - DEBUG_PC("Q length: %d", g_list_length(Q)); - DEBUG_PC("DeviceId: %s", node->node.nodeId); - - // visit all the links from u within the graph - indexVertice = graph_vertice_lookup(node->node.nodeId, g); - g_assert(indexVertice >= 0); - - // Check the targeted vertices from u - for (gint i = 0; i < g->vertices[indexVertice].numTargetedVertices; i++) { - gint done = check_link(node, indexVertice, i, g, s, &S, &Q, mapNodes); - (void)done; - } - // Add node into the S Set - S = g_list_append(S, node); - //DEBUG_PC ("S length: %d", g_list_length (S)); - } - g_list_free_full(S, g_free); - g_list_free_full(Q, g_free); - return; -} +GList* contextSet; /////////////////////////////////////////////////////////////////////////////////// /** @@ -113,12 +46,13 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv * @param pred * @param g * @param s + * @param mapNodes * * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s) { +gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s, struct map_nodes_t* mapNodes) { g_assert(pred); g_assert(g); g_assert(s); @@ -137,7 +71,7 @@ gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s) { } // Compute the shortest path - dijkstra(srcMapIndex, dstMapIndex, g, s); + dijkstra(srcMapIndex, dstMapIndex, g, s, mapNodes, NULL, NULL, 0x00000000); // Check that a feasible solution in term of latency and bandwidth is found gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); @@ -179,7 +113,7 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa g_assert(g); // create map of devices / nodes to handle the path computation using the context - mapNodes = create_map_node(); + struct map_nodes_t *mapNodes = create_map_node(); build_map_node(mapNodes, g); // predecessors to store the computed path @@ -189,7 +123,7 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]); // SP computation - gint done = computation(predecessors, g, s); + gint done = computation(predecessors, g, s, mapNodes); if (done == -1) { DEBUG_PC("NO PATH FOUND %s[%s] ---> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); comp_route_connection_issue_handler(path, s); @@ -204,15 +138,12 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa //DEBUG_PC ("Path is constructed"); gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes); - struct map_t* dst_map = &mapNodes->map[indexDest]; - // Get the delay and cost - memcpy(&p->cost, &dst_map->distance, sizeof(gdouble)); - memcpy(&p->availCap, &dst_map->avaiBandwidth, sizeof(dst_map->avaiBandwidth)); - memcpy(&p->delay, &dst_map->latency, sizeof(mapNodes->map[indexDest].latency)); + struct map_t* dst_map = &mapNodes->map[indexDest]; + set_path_attributes(p, dst_map); DEBUG_PC("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay); print_path(p); - gboolean feasibleRoute = check_computed_path_feasability(s, p); + gboolean feasibleRoute = check_computed_path_feasibility(s, p); if (feasibleRoute == TRUE) { DEBUG_PC("SP Feasible"); print_path(p); @@ -239,10 +170,8 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa g_free(mapNodes); return; } - DEBUG_PC("SP FAILED!!!"); comp_route_connection_issue_handler(path, s); - return; } @@ -257,48 +186,53 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa * @author Ricardo Mart�nez * @date 2022 */ -void sp_execution_services(struct compRouteOutputList_t* oPathList) -{ - g_assert(oPathList); - g_assert(contextSet); - g_assert(serviceList); +void sp_execution_services(struct compRouteOutputList_t* oPathList) { + g_assert(oPathList); + // Check at least there is a service to be processed + if (g_list_length(serviceList) == 0) { + DEBUG_PC("Lengtg requested serviceList is Empty..."); + return; + } DEBUG_PC("----- Starting the SP Computation ------"); + gint i = 0; + for (GList* listnode = g_list_first(serviceList); + listnode; + listnode = g_list_next(listnode), i++) { + //struct service_t* service = &(serviceList->services[i]); + struct service_t* service = (struct service_t*)(listnode->data); + + DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); + struct compRouteOutput_t* pathService = &(oPathList->compRouteConnection[i]); + // check endpoints of the service are different (PE devices/nodes are different) + if (same_src_dst_pe_nodeid(service) == 0) { + DEBUG_PC("PEs are the same... no path computation"); + comp_route_connection_issue_handler(pathService, service); + oPathList->numCompRouteConnList++; + continue; + } + + // get the graph associated to the contextId in the contextSet, if no then error + struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId); + if (g == NULL) { + DEBUG_PC("The targeted contextId is NOT in the ContextSet ... then NO graph"); + comp_route_connection_issue_handler(pathService, service); + oPathList->numCompRouteConnList++; + continue; + } - for (gint i = 0; i < serviceList->numServiceList; i++) { - struct service_t* service = &(serviceList->services[i]); - - DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); - struct compRouteOutput_t* pathService = &(oPathList->compRouteConnection[i]); - // check endpoints of the service are different (PE devices/nodes are different) - if (same_src_dst_pe_nodeid(service) == 0) { - DEBUG_PC("PEs are the same... no path computation"); - comp_route_connection_issue_handler(pathService, service); - oPathList->numCompRouteConnList++; - continue; - } - - // get the graph associated to the contextId in the contextSet, if no then error - struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId); - if (g == NULL) { - DEBUG_PC("The targeted contextId is NOT in the ContextSet ... then NO graph"); - comp_route_connection_issue_handler(pathService, service); - oPathList->numCompRouteConnList++; - continue; - } - - computation_shortest_path(service, pathService, g); - oPathList->numCompRouteConnList++; - - // for each network connectivity service, a single computed path (out of the KCSP) is retuned - // If path is found, then the selected resources must be pre-assigned into the context information - if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { - continue; - } - struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); - allocate_graph_resources(path, service, g); - allocate_graph_reverse_resources(path, service, g); - print_graph(g); + computation_shortest_path(service, pathService, g); + oPathList->numCompRouteConnList++; + + // for each network connectivity service, a single computed path (out of the KCSP) is retuned + // If path is found, then the selected resources must be pre-assigned into the context information + if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { + continue; + } + struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); + //allocate_graph_resources(path, service, g); // LGR: crashes in some cases with assymetric topos + //allocate_graph_reverse_resources(path, service, g); // LGR: crashes in some cases with assymetric topos + print_graph(g); } return; } @@ -314,10 +248,8 @@ void sp_execution_services(struct compRouteOutputList_t* oPathList) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList) -{ +gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList) { g_assert(routeConnList); - gint numSuccesPathComp = 0, numPathCompIntents = 0; DEBUG_PC("================================================================"); @@ -332,9 +264,9 @@ gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList) gettimeofday(&t0, NULL); // Allocate memory for the context - contextSet = create_contextSet(); + contextSet = NULL; // Build up the contextSet (>= 1) - build_contextSet(contextSet); + build_contextSet(&contextSet); print_contextSet(contextSet); #if 1 //Triggering the path computation for each specific network connectivity service @@ -352,7 +284,7 @@ gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList) print_path_connection_list(routeConnList); #endif - g_free(contextSet); + g_list_free_full(g_steal_pointer(&contextSet), (GDestroyNotify)destroy_context); return http_code; } diff --git a/src/pathcomp/backend/pathComp_tools.c b/src/pathcomp/backend/pathComp_tools.c index 5f1748b1a58a0d1b935c064ef4b92ac8ee0da389..bd4f7df8ca460e3bab3bb3d9f75e7592f19268c7 100644 --- a/src/pathcomp/backend/pathComp_tools.c +++ b/src/pathcomp/backend/pathComp_tools.c @@ -59,7 +59,6 @@ struct timeval tv_adjust (struct timeval a) { a.tv_usec -= 1000000; a.tv_sec++; } - while (a.tv_usec < 0) { a.tv_usec += 1000000; a.tv_sec--; @@ -80,8 +79,7 @@ struct timeval tv_adjust (struct timeval a) { */ //////////////////////////////////////////////////////////////////////////////////////// void duplicate_string(gchar* dst, gchar* src) { - g_assert(dst); - g_assert(src); + g_assert(dst); g_assert(src); strcpy(dst, src); dst[strlen(dst)] = '\0'; return; @@ -99,16 +97,15 @@ void duplicate_string(gchar* dst, gchar* src) { */ ///////////////////////////////////////////////////////////////////////////////////////// void print_path (struct compRouteOutputItem_t *p) { - g_assert(p); - + g_assert(p); DEBUG_PC ("=========== COMPUTED PATH ======================="); - DEBUG_PC ("Path Avail. Bw: %f, E2E Path Latency: %f, Path Cost: %f", p->availCap, p->delay, p->cost); + DEBUG_PC ("E2E Avail. Bw: %f, Latency: %f, Cost: %f, Consumed Power (in W): %f", p->availCap, p->delay, p->cost, p->power); for (gint k = 0; k < p->numRouteElements; k++) { - DEBUG_PC ("aNodeId: %s (%s) --> zNodeId: %s (%s)", p->routeElement[k].aNodeId.nodeId, p->routeElement[k].aEndPointId, + DEBUG_PC ("%s[%s] --> %s[%s]", p->routeElement[k].aNodeId.nodeId, p->routeElement[k].aEndPointId, p->routeElement[k].zNodeId.nodeId, p->routeElement[k].zEndPointId); - DEBUG_PC("linkId: %s", p->routeElement[k].linkId); - DEBUG_PC("aTopologyId: %s", p->routeElement[k].aTopologyId); - DEBUG_PC("zTopologyId: %s", p->routeElement[k].zTopologyId); + DEBUG_PC("\t linkId: %s", p->routeElement[k].linkId); + DEBUG_PC("\t aTopologyId: %s", p->routeElement[k].aTopologyId); + DEBUG_PC("\t zTopologyId: %s", p->routeElement[k].zTopologyId); } DEBUG_PC ("=================================================================="); return; @@ -128,8 +125,8 @@ void print_path (struct compRouteOutputItem_t *p) { void print_path_t(struct path_t* p) { g_assert(p); DEBUG_PC(" ============ COMPUTED OUTPUT PATH ================="); - DEBUG_PC("Path Avail Capacity: %f, Cost: %f, Latency: %f", p->path_capacity.value, - p->path_cost.cost_value, p->path_latency.fixed_latency); + DEBUG_PC("Path AvailBw: %f, Cost: %f, Latency: %f, Power: %f", p->path_capacity.value, + p->path_cost.cost_value, p->path_latency.fixed_latency, p->path_power.power); DEBUG_PC("number of links of path %d", p->numPathLinks); for (gint k = 0; k < p->numPathLinks; k++) { DEBUG_PC("Link: %s", p->pathLinks[k].linkId); @@ -144,6 +141,25 @@ void print_path_t(struct path_t* p) { return; } +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Function used allocate memory for struct path_t + * + * + * @author Ricardo Martínez + * @date 2022 + */ + //////////////////////////////////////////////////////////////////////////////////////// +struct path_t* create_path() { + struct path_t* p = g_malloc0(sizeof(struct path_t)); + if (p == NULL) { + DEBUG_PC("Memory allocation failure"); + exit(-1); + } + return(p); +} + //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c @@ -178,12 +194,9 @@ gchar* get_uuid_char(uuid_t uuid) { */ ///////////////////////////////////////////////////////////////////////////////////////// void copy_service_id(struct serviceId_t* o, struct serviceId_t* i) { - g_assert(o); - g_assert(i); - + g_assert(o); g_assert(i); memcpy(o->contextId, i->contextId, sizeof(i->contextId)); memcpy(o->service_uuid, i->service_uuid, sizeof(i->service_uuid)); - return; } @@ -200,8 +213,7 @@ void copy_service_id(struct serviceId_t* o, struct serviceId_t* i) { */ ///////////////////////////////////////////////////////////////////////////////////////// void copy_service_endpoint_id(struct service_endpoints_id_t* oEp, struct service_endpoints_id_t* iEp) { - g_assert(oEp); - g_assert(iEp); + g_assert(oEp); g_assert(iEp); // copy topology information memcpy(oEp->topology_id.contextId, iEp->topology_id.contextId, sizeof(iEp->topology_id.contextId)); @@ -216,8 +228,8 @@ void copy_service_endpoint_id(struct service_endpoints_id_t* oEp, struct service //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c - * @brief From the set of contexts, it is returned the graph associated to that contexct matching - * with the passed contextId + * @brief From the set of contexts, it is returned the graph associated to that context matching + * with the passed contextId. * * @param Set * @param contextId @@ -226,15 +238,16 @@ void copy_service_endpoint_id(struct service_endpoints_id_t* oEp, struct service * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct graph_t* get_graph_by_contextId(struct contextSet_t* Set, gchar* contextId) { - g_assert(Set); +struct graph_t* get_graph_by_contextId(GList* set, gchar* contextId) { g_assert(contextId); // iterate over the set of context. Pick the one matching with contextId, and return the graph. // If not found, return NULL struct graph_t* g = NULL; - for (gint i = 0; i < Set->num_context_set; i++) { - struct context_t* context = &(Set->contextList[i]); + for (GList *ln = g_list_first(set); + ln; + ln = g_list_next(ln)){ + struct context_t* context = (struct context_t*)(ln->data); if (strcmp(context->contextId, contextId) == 0) { g = &(context->g); return g; @@ -297,16 +310,13 @@ struct path_constraints_t * get_path_constraints(struct service_t* s) { * @file pathComp_tools.c * @brief Creates the predecessors to keep the computed path * - * * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct pred_t * create_predecessors () -{ +struct pred_t * create_predecessors () { struct pred_t *predecessors = g_malloc0 (sizeof (struct pred_t)); - if (predecessors == NULL) - { + if (predecessors == NULL) { DEBUG_PC ("memory allocation failed\n"); exit (-1); } @@ -323,11 +333,9 @@ struct pred_t * create_predecessors () * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct edges_t* create_edge() -{ +struct edges_t* create_edge() { struct edges_t* e = g_malloc0(sizeof(struct edges_t)); - if (e == NULL) - { + if (e == NULL) { DEBUG_PC("Memory allocation failed\n"); exit(-1); } @@ -376,16 +384,13 @@ void print_predecessors (struct pred_t *p) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void build_predecessors (struct pred_t *p, struct service_t *s, struct map_nodes_t *map) -{ - g_assert (p); - g_assert (s); - g_assert (map); +void build_predecessors (struct pred_t *p, struct service_t *s, struct map_nodes_t *map) { + g_assert (p); g_assert (s); g_assert (map); struct nodes_t *v = create_node(); duplicate_string(v->nodeId, s->service_endpoints_id[1].device_uuid); - struct edges_t *e = create_edge (); + struct edges_t *e = create_edge(); get_edge_from_map_by_node (e, v, map); // Get u (being source of edge e) @@ -416,9 +421,7 @@ void build_predecessors (struct pred_t *p, struct service_t *s, struct map_nodes p->numPredComp++; } print_predecessors (p); - g_free (e); - g_free(v); - g_free(srcNode); + g_free (e); g_free(v); g_free(srcNode); return; } @@ -452,11 +455,9 @@ struct nodes_t * create_node () * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct routeElement_t * create_routeElement () -{ +struct routeElement_t * create_routeElement () { struct routeElement_t *rE = g_malloc0 (sizeof (struct routeElement_t)); - if (rE == NULL) - { + if (rE == NULL) { DEBUG_PC ("memory allocation problem"); exit (-1); } @@ -475,11 +476,9 @@ struct routeElement_t * create_routeElement () * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void duplicate_node_id (struct nodes_t *src, struct nodes_t *dst) -{ +void duplicate_node_id (struct nodes_t *src, struct nodes_t *dst) { g_assert (src); - g_assert (dst); - + g_assert (dst); //DEBUG_PC ("Duplicate nodeId for %s", src->nodeId); strcpy (dst->nodeId, src->nodeId); return; @@ -497,8 +496,7 @@ void duplicate_node_id (struct nodes_t *src, struct nodes_t *dst) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint compare_node_id (struct nodes_t *a, struct nodes_t *b) -{ +gint compare_node_id (struct nodes_t *a, struct nodes_t *b) { g_assert (a); g_assert (b); return (memcmp (&a->nodeId, b->nodeId, strlen (b->nodeId))); @@ -541,8 +539,7 @@ void duplicate_routeElement (struct routeElement_t *src, struct routeElement_t * */ ///////////////////////////////////////////////////////////////////////////////////////// void duplicate_edge (struct edges_t *e1, struct edges_t *e2) { - g_assert (e1); - g_assert (e2); + g_assert (e1); g_assert (e2); duplicate_node_id (&e2->aNodeId, &e1->aNodeId); duplicate_node_id (&e2->zNodeId, &e1->zNodeId); @@ -560,7 +557,8 @@ void duplicate_edge (struct edges_t *e1, struct edges_t *e2) { memcpy(&e1->availCap, &e2->availCap, sizeof(gdouble)); memcpy (&e1->cost, &e2->cost, sizeof (gdouble)); - memcpy (&e1->delay, &e2->delay, sizeof (gdouble)); + memcpy (&e1->delay, &e2->delay, sizeof (gdouble)); + memcpy(&e1->energy, &e2->energy, sizeof(gdouble)); return; } @@ -577,19 +575,18 @@ void duplicate_edge (struct edges_t *e1, struct edges_t *e2) { */ ///////////////////////////////////////////////////////////////////////////////////////// void duplicate_path (struct compRouteOutputItem_t *a, struct compRouteOutputItem_t *b) { - g_assert (a); - g_assert (b); - memcpy (&b->availCap, &a->availCap, sizeof (gdouble)); - b->numRouteElements = a->numRouteElements; + g_assert (a); g_assert (b); + memcpy(&b->availCap, &a->availCap, sizeof (gdouble)); memcpy(&b->cost, &a->cost, sizeof(gdouble)); - memcpy (&b->delay, &a->delay, sizeof (gdouble)); + memcpy(&b->delay, &a->delay, sizeof (gdouble)); + memcpy(&b->power, &a->power, sizeof(gdouble)); + b->numRouteElements = a->numRouteElements; for (gint k = 0; k < a->numRouteElements; k++) { //DEBUG_PC ("aNodeId: %s // zNodeId: %s", a->routeElement[k].aNodeId.nodeId, a->routeElement[k].zNodeId.nodeId); // aNodeId duplication struct nodes_t *n1 = &(a->routeElement[k].aNodeId); struct nodes_t *n2 = &(b->routeElement[k].aNodeId); - duplicate_node_id (n1, n2); - + duplicate_node_id (n1, n2); //zNodeId duplication n1 = &(a->routeElement[k].zNodeId); n2 = &(b->routeElement[k].zNodeId); @@ -615,14 +612,14 @@ void duplicate_path (struct compRouteOutputItem_t *a, struct compRouteOutputItem * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void duplicate_path_t(struct compRouteOutputItem_t* a, struct path_t* b) -{ - g_assert(a); - g_assert(b); +void duplicate_path_t(struct compRouteOutputItem_t* a, struct path_t* b) { + g_assert(a); g_assert(b); + // transfer path characteristics ... memcpy(&b->path_capacity.value, &a->availCap, sizeof(gdouble)); memcpy(&b->path_cost.cost_value, &a->cost, sizeof(gdouble)); memcpy(&b->path_latency.fixed_latency, &a->delay, sizeof(gdouble)); + memcpy(&b->path_power.power, &a->power, sizeof(gdouble)); b->numPathLinks = a->numRouteElements; @@ -661,23 +658,17 @@ void duplicate_path_t(struct compRouteOutputItem_t* a, struct path_t* b) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint get_map_index_by_nodeId (gchar *nodeId, struct map_nodes_t * mapN) -{ - gint index = -1; - gint i = 0; - - for (i = 0; i < mapN->numMapNodes; i++) - { +gint get_map_index_by_nodeId (gchar *nodeId, struct map_nodes_t * mapN) { + gint i = 0; + for (i = 0; i < mapN->numMapNodes; i++) { //DEBUG_PC ("i: %d; current: %s // targeted: %s", i, mapN->map[i].verticeId.nodeId, nodeId); - if (memcmp (mapN->map[i].verticeId.nodeId, nodeId, strlen (nodeId)) == 0) - { - index = i; - //DEBUG_PC ("Index: %d", index); - return index; + if (memcmp (mapN->map[i].verticeId.nodeId, nodeId, strlen (nodeId)) == 0) { + //DEBUG_PC ("Index: %d", i); + return i; } } //DEBUG_PC ("Index: %d", index); - return index; + return -1; } //////////////////////////////////////////////////////////////////////////////////////// @@ -693,14 +684,11 @@ gint get_map_index_by_nodeId (gchar *nodeId, struct map_nodes_t * mapN) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void get_edge_from_map_by_node (struct edges_t *e, struct nodes_t* v, struct map_nodes_t *mapN) { - +void get_edge_from_map_by_node (struct edges_t *e, struct nodes_t* v, struct map_nodes_t *mapN) { //DEBUG_PC ("Get the Edge into map from node v: %s", v.nodeId); // Get the edge reaching the node v from mapNodes - gint map_vIndex = get_map_index_by_nodeId (v->nodeId, mapN); - - //DEBUG_PC ("aNodeId: %s --> zNodeId: %s", mapN->map[map_vIndex].predecessor.aNodeId.nodeId, mapN->map[map_vIndex].predecessor.zNodeId.nodeId); - + gint map_vIndex = get_map_index_by_nodeId (v->nodeId, mapN); + //DEBUG_PC ("aNodeId: %s --> zNodeId: %s", mapN->map[map_vIndex].predecessor.aNodeId.nodeId, mapN->map[map_vIndex].predecessor.zNodeId.nodeId); struct edges_t *te = &(mapN->map[map_vIndex].predecessor); duplicate_edge (e, te); return; @@ -721,7 +709,6 @@ void get_edge_from_map_by_node (struct edges_t *e, struct nodes_t* v, struct map ///////////////////////////////////////////////////////////////////////////////////////// void get_edge_from_predecessors (struct edges_t *e, struct nodes_t* n, struct pred_t *predecessors) { g_assert(predecessors); - DEBUG_PC ("Get edge outgoing node %s from predecessors list", n->nodeId); //print_predecessors (predecessors); for (gint i = 0; i < predecessors->numPredComp; i++) { @@ -751,14 +738,13 @@ void get_edge_from_predecessors (struct edges_t *e, struct nodes_t* n, struct pr */ ///////////////////////////////////////////////////////////////////////////////////////// void build_path (struct compRouteOutputItem_t *p, struct pred_t *predecessors, struct service_t *s) { - //DEBUG_PC ("\n"); // Get the source device Id of the network connectivity service struct nodes_t *v = create_node(); + // Src Node of the Service set to v duplicate_string(v->nodeId, s->service_endpoints_id[0].device_uuid); - - struct edges_t* e = create_edge(); - + // Get the edge for v in predecessors + struct edges_t* e = create_edge(); get_edge_from_predecessors (e, v, predecessors); // Get the target for e struct nodes_t u; @@ -778,14 +764,12 @@ void build_path (struct compRouteOutputItem_t *p, struct pred_t *predecessors, s duplicate_string(p->routeElement[k].contextId, s->serviceId.contextId); p->numRouteElements++; - // Get the destination device Id of the network connectivity service + // Get Dst Node of connectivity service struct nodes_t* dst = create_node(); duplicate_string(dst->nodeId, s->service_endpoints_id[1].device_uuid); - while (compare_node_id (&u, dst) != 0) - { + while (compare_node_id (&u, dst) != 0) { k++; - p->numRouteElements++; - // v = u + p->numRouteElements++; duplicate_node_id (&u, v); get_edge_from_predecessors (e, v, predecessors); // Get the target u @@ -798,10 +782,7 @@ void build_path (struct compRouteOutputItem_t *p, struct pred_t *predecessors, s duplicate_string(p->routeElement[k].linkId, e->linkId); duplicate_string(p->routeElement[k].aTopologyId, e->aTopologyId); duplicate_string(p->routeElement[k].zTopologyId, e->zTopologyId); - duplicate_string(p->routeElement[k].contextId, s->serviceId.contextId); - - // copy the contextId - //duplicate_string(p->routeElement[k].contextId, s->service_endpoints_id[0].topology_id.contextId); + duplicate_string(p->routeElement[k].contextId, s->serviceId.contextId); } g_free(e); g_free(v); g_free(pathCons); //DEBUG_PC ("Path is constructed"); @@ -819,22 +800,19 @@ void build_path (struct compRouteOutputItem_t *p, struct pred_t *predecessors, s * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void print_graph (struct graph_t *g) -{ +void print_graph (struct graph_t *g) { + g_assert(g); DEBUG_PC ("================================================================"); DEBUG_PC ("=========================== GRAPH =========================="); DEBUG_PC ("================================================================"); - - DEBUG_PC("Graph Num Vertices: %d", g->numVertices); + DEBUG_PC("Graph Num Vertices: %d", g->numVertices); - gint i = 0, j = 0, k = 0; - for (i = 0; i < g->numVertices; i++) - { + for (gint i = 0; i < g->numVertices; i++) { DEBUG_PC ("Head Vertice [%s]", g->vertices[i].verticeId.nodeId); - for (j = 0; j < g->vertices[i].numTargetedVertices; j++) + for (gint j = 0; j < g->vertices[i].numTargetedVertices; j++) { DEBUG_PC (" Tail Vertice: %s", g->vertices[i].targetedVertices[j].tVertice.nodeId); - for (k = 0; k < g->vertices[i].targetedVertices[j].numEdges; k++) + for (gint k = 0; k < g->vertices[i].targetedVertices[j].numEdges; k++) { struct edges_t *e = &(g->vertices[i].targetedVertices[j].edges[k]); DEBUG_PC ("%s(%s) --> %s(%s) [C: %f, Bw: %f b/s, Delay: %f ms]", e->aNodeId.nodeId, e->aEndPointId, e->zNodeId.nodeId, @@ -992,8 +970,7 @@ gint graph_targeted_vertice_add (gint vIndex, gchar *nodeId, struct graph_t *g) * @author Ricardo Martínez * @date 2022 */ -void remove_edge_from_graph (struct graph_t *g, struct edges_t *e) -{ +void remove_edge_from_graph (struct graph_t *g, struct edges_t *e) { // Find the ingress vertice into the graph DEBUG_PC ("Removing from Graph %s[%s]) ---> %s[%s] (linkId: %s)", e->aNodeId.nodeId, e->aEndPointId, e->zNodeId.nodeId, e->aEndPointId, e->linkId); gint verticeIndex = -1; @@ -1009,14 +986,13 @@ void remove_edge_from_graph (struct graph_t *g, struct edges_t *e) if (targetedVerticeIndex == -1) { DEBUG_PC ("%s --> %s NOT in the Graph!!", e->aNodeId.nodeId, e->zNodeId.nodeId); return; - } - + } //DEBUG_PC ("%s --> %s found in the Graph", e->aNodeId.nodeId, e->zNodeId.nodeId); // Get the edge position gint edgeIndex = -1; edgeIndex = graph_edge_lookup (verticeIndex, targetedVerticeIndex, e, g); - if (edgeIndex == -1) { + if (edgeIndex == -1) { DEBUG_PC ("%s --> %s NOT in the Graph!!", e->aNodeId.nodeId, e->zNodeId.nodeId); return; } @@ -1046,11 +1022,9 @@ void remove_edge_from_graph (struct graph_t *g, struct edges_t *e) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct path_set_t * create_path_set () -{ +struct path_set_t * create_path_set () { struct path_set_t * p = g_malloc0 (sizeof (struct path_set_t)); - if (p == NULL) - { + if (p == NULL) { DEBUG_PC ("Memory allocation problem"); exit (-1); } @@ -1068,10 +1042,8 @@ struct path_set_t * create_path_set () * @date 2021 */ ///////////////////////////////////////////////////////////////////////////////////////// -void remove_path_set(struct path_set_t* p) -{ - g_assert(p); - g_free(p); +void remove_path_set(struct path_set_t* p) { + g_assert(p); g_free(p); return; } @@ -1087,15 +1059,14 @@ void remove_path_set(struct path_set_t* p) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void build_map_node (struct map_nodes_t *mapN, struct graph_t *g) -{ +void build_map_node (struct map_nodes_t *mapN, struct graph_t *g) { //DEBUG_PC ("Construction of the Map of Nodes"); - for (gint i = 0; i < g->numVertices; i++) - { + for (gint i = 0; i < g->numVertices; i++) { duplicate_node_id (&g->vertices[i].verticeId, &mapN->map[i].verticeId); mapN->map[i].distance = INFINITY_COST; mapN->map[i].avaiBandwidth = 0.0; mapN->map[i].latency = INFINITY_COST; + mapN->map[i].power = INFINITY_COST; mapN->numMapNodes++; } //DEBUG_PC ("mapNodes formed by %d Nodes", mapN->numMapNodes); @@ -1107,22 +1078,137 @@ void build_map_node (struct map_nodes_t *mapN, struct graph_t *g) * @file pathComp_tools.c * @brief Allocate memory for path of struct compRouteOutputList_t * * - * * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct compRouteOutputList_t * create_route_list () -{ +struct compRouteOutputList_t * create_route_list () { struct compRouteOutputList_t *p = g_malloc0 (sizeof (struct compRouteOutputList_t)); - if (p == NULL) - { + if (p == NULL) { DEBUG_PC ("Memory Allocation Problem"); exit (-1); } return p; } +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Copy all the attributes defining a path + * + * @param dst_path + * @param src_path + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void copy_path(struct path_t* dst_path, struct path_t* src_path) { + g_assert(dst_path); + g_assert(src_path); + + // Path capacity + dst_path->path_capacity.unit = src_path->path_capacity.unit; + memcpy(&dst_path->path_capacity.value, &src_path->path_capacity.value, sizeof(gdouble)); + + // Path latency + memcpy(&dst_path->path_latency.fixed_latency, &src_path->path_latency.fixed_latency, sizeof(gdouble)); + + // Path cost + duplicate_string(dst_path->path_cost.cost_name, src_path->path_cost.cost_name); + memcpy(&dst_path->path_cost.cost_value, &src_path->path_cost.cost_value, sizeof(gdouble)); + memcpy(&dst_path->path_cost.cost_algorithm, &src_path->path_cost.cost_algorithm, sizeof(gdouble)); + + // Path links + dst_path->numPathLinks = src_path->numPathLinks; + for (gint i = 0; i < dst_path->numPathLinks; i++) { + struct pathLink_t* dPathLink = &(dst_path->pathLinks[i]); + struct pathLink_t* sPathLink = &(src_path->pathLinks[i]); + + duplicate_string(dPathLink->linkId, sPathLink->linkId); + duplicate_string(dPathLink->aDeviceId, sPathLink->aDeviceId); + duplicate_string(dPathLink->zDeviceId, sPathLink->zDeviceId); + duplicate_string(dPathLink->aEndPointId, sPathLink->aEndPointId); + duplicate_string(dPathLink->zEndPointId, sPathLink->zEndPointId); + + duplicate_string(dPathLink->topologyId.contextId, sPathLink->topologyId.contextId); + duplicate_string(dPathLink->topologyId.topology_uuid, sPathLink->topologyId.topology_uuid); + + dPathLink->numLinkTopologies = sPathLink->numLinkTopologies; + for (gint j = 0; j < dPathLink->numLinkTopologies; j++) { + struct linkTopology_t* dLinkTop = &(dPathLink->linkTopologies[j]); + struct linkTopology_t* sLinkTop = &(sPathLink->linkTopologies[j]); + + duplicate_string(dLinkTop->topologyId, sLinkTop->topologyId); + } + } + return; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Duplicate the route output instance + * + * @param dst_ro + * @param src_ro + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void duplicate_compRouteOuput(struct compRouteOutput_t* dst_ro, struct compRouteOutput_t* src_ro) { + g_assert(dst_ro); g_assert(src_ro); + + // Copy the serviceId + copy_service_id(&dst_ro->serviceId, &src_ro->serviceId); + dst_ro->num_service_endpoints_id = src_ro->num_service_endpoints_id; + + for (gint j = 0; j < dst_ro->num_service_endpoints_id; j++) { + struct service_endpoints_id_t* iEp = &(src_ro->service_endpoints_id[j]); + struct service_endpoints_id_t* oEp = &(dst_ro->service_endpoints_id[j]); + copy_service_endpoint_id(oEp, iEp); + } + + // Copy paths + dst_ro->numPaths = src_ro->numPaths; + for (gint j = 0; j < dst_ro->numPaths; j++) { + struct path_t* dst_path = &(dst_ro->paths[j]); + struct path_t* src_path = &(src_ro->paths[j]); + copy_path(dst_path, src_path); + } + // copy no path issue value + dst_ro->noPathIssue = src_ro->noPathIssue; + return; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Duplicate the computation route output list + * + * @param dst + * @param src + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void duplicate_route_list(struct compRouteOutputList_t* dst, struct compRouteOutputList_t* src) { + g_assert(src); g_assert(dst); + + dst->numCompRouteConnList = src->numCompRouteConnList; + dst->compRouteOK = src->compRouteOK; + memcpy(&dst->compRouteConnAvBandwidth, &src->compRouteConnAvBandwidth, sizeof(gdouble)); + memcpy(&dst->compRouteConnAvPathLength, &src->compRouteConnAvPathLength, sizeof(gdouble)); + for (gint i = 0; i < src->numCompRouteConnList; i++) { + struct compRouteOutput_t* src_ro = &(src->compRouteConnection[i]); + struct compRouteOutput_t* dst_ro = &(dst->compRouteConnection[i]); + duplicate_compRouteOuput(dst_ro, src_ro); + } + return; +} + //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c @@ -1133,8 +1219,7 @@ struct compRouteOutputList_t * create_route_list () * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct compRouteOutputItem_t *create_path_item () -{ +struct compRouteOutputItem_t *create_path_item () { struct compRouteOutputItem_t *p = g_malloc0 (sizeof (struct compRouteOutputItem_t)); if (p == NULL) { DEBUG_PC ("Memory Allocation Problem"); @@ -1146,71 +1231,86 @@ struct compRouteOutputItem_t *create_path_item () //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c - * @brief Sort the set of paths according to the metric (1st criteria) and latency (2nd criteria) + * @brief Sort the set of paths the AvailBw, Cost and Delay * * @params setP + * @params args * * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void sort_path_set(struct path_set_t* setP) { +void sort_path_set(struct path_set_t* setP, guint args) { g_assert(setP); - // Sort the paths contained in setP by shotest metric and latency - float epsilon = 0.0000001; + // Sort the paths contained in setP by: + // 1st Criteria: The path cost (maybe bound to link distance) + // 2nd Criteria: The consumed path power + // 3nd Criteria: The path latency + // 3rd Criteria: The available Bw + float epsilon = 0.1; for (gint i = 0; i < setP->numPaths; i++) { for (gint j = 0; j < (setP->numPaths - i - 1); j++) { struct compRouteOutputItem_t* path1 = &setP->paths[j]; - struct compRouteOutputItem_t* path2 = &setP->paths[j + 1]; - + struct compRouteOutputItem_t* path2 = &setP->paths[j + 1]; struct compRouteOutputItem_t* pathTmp = create_path_item(); - // 1st Criteria (avail Bw) - if ((path2->availCap - path1->availCap > 0.0) && (fabs(path1->availCap - path2->availCap) > epsilon)) { + //////////////////////// Criterias //////////////////////////////////////// + // 1st Criteria (Cost) + if (path2->cost < path1->cost) { duplicate_path(path1, pathTmp); duplicate_path(path2, path1); duplicate_path(pathTmp, path2); g_free(pathTmp); continue; } - else if ((path1->availCap - path2->availCap > 0.0) && (fabs(path1->availCap - path2->availCap) > epsilon)) { - g_free(pathTmp); - continue; - } - // likely the same available bw between path1 and path2 - else if (fabs(path1->availCap - path2->availCap) < epsilon) { - // 2nd criteria: sort path cost - if (path1->cost > path2->cost) { - duplicate_path(path1, pathTmp); - duplicate_path(path2, path1); - duplicate_path(pathTmp, path2); - g_free(pathTmp); - continue; - } - else if (path1->cost < path2->cost) { - g_free(pathTmp); - continue; - } - // 3rd criteria: same path cost, prioritize the one with lowest e2e latency - else if (path1->cost == path2->cost) { - if ((path2->delay - path1->delay > 0.0) && (fabs(path1->delay - path2->delay) > epsilon)) { + if (path2->cost == path1->cost) { + // 2nd Criteria (Energy) + if (args & ENERGY_EFFICIENT_ARGUMENT) { + if (path2->power < path1->power) { + duplicate_path(path1, pathTmp); + duplicate_path(path2, path1); + duplicate_path(pathTmp, path2); + g_free(pathTmp); + continue; + } + else { // path1->power < path2->power g_free(pathTmp); continue; } - else if ((path1->delay - path2->delay > 0.0) && (fabs(path1->delay - path2->delay) > epsilon)) { + } + else { // No enery efficient argument + // 3rd Criteria (latency) + if (path2->delay < path1->delay) { duplicate_path(path1, pathTmp); duplicate_path(path2, path1); duplicate_path(pathTmp, path2); g_free(pathTmp); continue; } - // Same bw, same cost and same latency, path1 and path2 are practically the same - else if (fabs(path1->delay - path2->delay) < epsilon) { + else if (path1->delay < path2->delay) { g_free(pathTmp); continue; } + else { // path1->delay == path2->delay + // 4th Criteria (available bw) + if (path2->availCap > path1->availCap) { + duplicate_path(path1, pathTmp); + duplicate_path(path2, path1); + duplicate_path(pathTmp, path2); + g_free(pathTmp); + continue; + } + else { + g_free(pathTmp); + continue; + } + } } - } + } + else { // path1->cost < path2->cost + g_free(pathTmp); + continue; + } } } return; @@ -1249,8 +1349,7 @@ void pop_front_path_set (struct path_set_t *setP) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void add_routeElement_path_back (struct routeElement_t *rE, struct compRouteOutputItem_t *p) -{ +void add_routeElement_path_back (struct routeElement_t *rE, struct compRouteOutputItem_t *p) { //DEBUG_PC ("p->numRouteElements: %d", p->numRouteElements); p->numRouteElements++; gint index = p->numRouteElements - 1; @@ -1268,7 +1367,6 @@ void add_routeElement_path_back (struct routeElement_t *rE, struct compRouteOutp duplicate_string(p->routeElement[index].linkId, rE->linkId); duplicate_string(p->routeElement[index].aTopologyId, rE->aTopologyId); duplicate_string(p->routeElement[index].zTopologyId, rE->zTopologyId); - return; } @@ -1332,21 +1430,19 @@ gboolean matching_path_rootPath (struct compRouteOutputItem_t *ap, struct compRo ///////////////////////////////////////////////////////////////////////////////////////// void modify_targeted_graph (struct graph_t *g, struct path_set_t *A, struct compRouteOutputItem_t * rootPath, struct nodes_t * spurNode) { //DEBUG_PC ("Modify the Targeted graph according to the Yen algorithm principles"); - for (gint j = 0; j < A->numPaths; j++) - { + for (gint j = 0; j < A->numPaths; j++) { struct compRouteOutputItem_t *ap = &A->paths[j]; - struct edges_t *e = create_edge (); + struct edges_t *e = create_edge(); gboolean ret = FALSE; ret = matching_path_rootPath (ap, rootPath, spurNode, e); if (ret == TRUE) { - //DEBUG_PC ("Removal %s [%u]--> %s [%u] from the graph", e->aNodeId.nodeId, e->aLinkId, e->zNodeId.nodeId, e->zLinkId); + DEBUG_PC ("Removal %s[%s] --> %s[%s] from the graph", e->aNodeId.nodeId, e->aEndPointId, e->zNodeId.nodeId, e->aEndPointId); remove_edge_from_graph (g, e); //DEBUG_PC ("Print Resulting Graph"); - //print_graph (g); + print_graph (g); g_free (e); } - if (ret == FALSE) - { + if (ret == FALSE) { g_free (e); continue; } @@ -1363,8 +1459,7 @@ void modify_targeted_graph (struct graph_t *g, struct path_set_t *A, struct comp * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint find_nodeId (gconstpointer data, gconstpointer userdata) -{ +gint find_nodeId (gconstpointer data, gconstpointer userdata) { /** check values */ g_assert(data != NULL); g_assert(userdata != NULL); @@ -1374,8 +1469,7 @@ gint find_nodeId (gconstpointer data, gconstpointer userdata) //DEBUG_PC ("SNodeId (%s) nodeId (%s)", SNodeId->node.nodeId, nodeId); - if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId))) - { + if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId))) { return (0); } return -1; @@ -1399,55 +1493,47 @@ gint find_nodeId (gconstpointer data, gconstpointer userdata) */ ///////////////////////////////////////////////////////////////////////////////////////// gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struct graph_t *g, - struct service_t *s, GList **S, GList **Q, struct map_nodes_t *mapNodes) { - g_assert(g); - g_assert(s); - g_assert(mapNodes); + struct service_t *s, GList **S, GList **Q, struct map_nodes_t *mapNodes, + guint arg) { + g_assert(g); g_assert(s); g_assert(mapNodes); struct targetNodes_t *v = &(g->vertices[indexGraphU].targetedVertices[indexGraphV]); - DEBUG_PC("Explored link (u ===> v):"); - DEBUG_PC("u: %s ====>", u->node.nodeId); - DEBUG_PC("====> v: %s", v->tVertice.nodeId); + DEBUG_PC("=======================CHECK Edge %s => %s =================================", u->node.nodeId, v->tVertice.nodeId); + //DEBUG_PC("\t %s => %s", u->node.nodeId, v->tVertice.nodeId); // v already explored in S? then, discard it GList *found = g_list_find_custom (*S, v->tVertice.nodeId, find_nodeId); if (found != NULL) { - DEBUG_PC ("v (%s) in S, discard to explore it!", v->tVertice.nodeId); + DEBUG_PC ("%s in S, DISCARD", v->tVertice.nodeId); return 0; } // Get the set of constraints imposed by the service struct path_constraints_t* path_constraints = get_path_constraints(s); - gdouble distance_through_u = INFINITY_COST; - gdouble latency_through_u = INFINITY_COST; - gint i = 0; - - // Check bandwidth requirement is fulfillied on edge u --> v - gint foundAvailBw = 0; - gdouble edgeAvailBw = 0.0; + gdouble distance_through_u = INFINITY_COST ,latency_through_u = INFINITY_COST, power_through_u = INFINITY_COST; + gint i = 0, foundAvailBw = 0; + // BANDWIDTH requirement to be fulfilled on EDGE u->v + gdouble edgeAvailBw = 0.0, edgeTotalBw = 0.0; for (i = 0; i < v->numEdges; i++) { struct edges_t *e = &(v->edges[i]); memcpy (&edgeAvailBw, &(e->availCap), sizeof (gdouble)); - DEBUG_PC("edge:u ===> v"); - DEBUG_PC ("%s[%s] ===>", u->node.nodeId, e->aEndPointId); - DEBUG_PC("====> %s[%s]", v->tVertice.nodeId, e->zEndPointId); - DEBUG_PC("edge available bw: %f", edgeAvailBw); - - // if network service constraint specifies "bandwidth" needs (assuming coherent units) - if (path_constraints->bw == TRUE) { - if (edgeAvailBw < path_constraints->bwConstraint) { - continue; - } - else { - foundAvailBw = 1; - break; - } + memcpy(&edgeTotalBw, &(e->totalCap), sizeof(gdouble)); + DEBUG_PC("EDGE %s[%s] => %s[%s]", u->node.nodeId, e->aEndPointId, v->tVertice.nodeId, e->zEndPointId); + //DEBUG_PC ("\t %s[%s] =>", u->node.nodeId, e->aEndPointId); + //DEBUG_PC("\t => %s[%s]", v->tVertice.nodeId, e->zEndPointId); + DEBUG_PC("\t Edge Att: AvailBw: %f, TotalBw: %f", edgeAvailBw, edgeTotalBw); + // Check Service Bw constraint + if ((path_constraints->bw == TRUE) && (edgeAvailBw < path_constraints->bwConstraint)) { + continue; + } + else { + foundAvailBw = 1; + break; } } - // if bw path constraint is specified but not sastified ... discard the edge - if ((path_constraints->bw == TRUE) && (foundAvailBw == 0)) - { - DEBUG_PC ("AvailBw: %f < path_constraint: %f -- Discard Edge", edgeAvailBw, path_constraints->bwConstraint); + // BW constraint NOT MET, then DISCARD edge + if ((path_constraints->bw == TRUE) && (foundAvailBw == 0)) { + DEBUG_PC ("Edge AvailBw: %f < path_constraint: %f -- DISCARD Edge", edgeAvailBw, path_constraints->bwConstraint); g_free(path_constraints); return 0; } @@ -1457,7 +1543,12 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc gint map_uIndex = get_map_index_by_nodeId (u->node.nodeId, mapNodes); struct map_t *u_map = &mapNodes->map[map_uIndex]; distance_through_u = u_map->distance + v->edges[indexEdge].cost; - latency_through_u = u_map->latency + v->edges[indexEdge].delay; + latency_through_u = u_map->latency + v->edges[indexEdge].delay; + // Consumed power at v through u is the sum + // 1. Power from src to u + // 2. Power-idle at node u + // 3. power consumed over the edge between u and v, i.e. energy*usedBw + power_through_u = u_map->power + g->vertices[indexGraphU].power_idle + ((edgeTotalBw - edgeAvailBw + path_constraints->bwConstraint) * (v->edges[indexEdge].energy)); gdouble availBw_through_u = 0.0; // ingress endpoint (u) is the src of the request @@ -1476,7 +1567,7 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc memcpy (&availBw_through_u, &edgeAvailBw, sizeof (gdouble)); } } - // Relax the link according to the pathCost and latency + // Relax the link according to the pathCost, latency, and energy gint map_vIndex = get_map_index_by_nodeId (v->tVertice.nodeId, mapNodes); struct map_t *v_map = &mapNodes->map[map_vIndex]; // If cost dist (u, v) > dist (src, v) relax the link @@ -1484,17 +1575,37 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc //DEBUG_PC ("dist(src, u) + dist(u, v): %f > dist (src, v): %f --> Discard Link", distance_through_u, v_map->distance); return 0; } - // If dist (src, u) + dist (u, v) = current dist(src, v), then use the latency as discarding criteria - if ((distance_through_u == v_map->distance) && (latency_through_u > v_map->latency)) { - //DEBUG_PC ("dist(src, u) + dist(u,v) = current dist(src, v), but latency (src,u) + latency (u, v) > current latency (src, v)"); - return 0; - } - // If dist (src, u) + dist (u,v) == current dist(src, v) AND latency (src, u) + latency (u, v) == current latency (src, v), the available bandwidth is the criteria - if ((distance_through_u == v_map->distance) && (latency_through_u == v_map->latency) && (availBw_through_u < v_map->avaiBandwidth)) { - return 0; - } - DEBUG_PC ("%s --> %s Relaxed", u->node.nodeId, v->tVertice.nodeId); - DEBUG_PC ("\t AvailBw: %f Mb/s, Cost: %f, Latency: %f ms", availBw_through_u, distance_through_u, latency_through_u); + // If energy consumption optimization is requested + if (arg & ENERGY_EFFICIENT_ARGUMENT) { + if (distance_through_u == v_map->distance) { + if (power_through_u > v_map->power) { + DEBUG_PC("Energy (src -> u + u -> v: %f (Watts) > Energy (src, v): %f (Watts) --> DISCARD EDGE", power_through_u, v_map->power); + return 0; + } + // same energy consumption, consider latency + if ((power_through_u == v_map->power) && (latency_through_u > v_map->latency)) { + return 0; + } + // same energy, same latency, criteria: choose the one having the largest available bw + if ((power_through_u == v_map->power) && (latency_through_u == v_map->latency) && (availBw_through_u < v_map->avaiBandwidth)) { + return 0; + } + } + } // No optimization, rely on latency and available e2e bandwidth + else { + // If dist (src, u) + dist (u, v) = current dist(src, v), then use the latency as discarding criteria + if ((distance_through_u == v_map->distance) && (latency_through_u > v_map->latency)) { + //DEBUG_PC ("dist(src, u) + dist(u,v) = current dist(src, v), but latency (src,u) + latency (u, v) > current latency (src, v)"); + return 0; + } + // If dist (src, u) + dist (u,v) == current dist(src, v) AND latency (src, u) + latency (u, v) == current latency (src, v), the available bandwidth is the criteria + if ((distance_through_u == v_map->distance) && (latency_through_u == v_map->latency) && (availBw_through_u < v_map->avaiBandwidth)) { + return 0; + } + } + DEBUG_PC ("Edge %s --> %s [RELAXED]", u->node.nodeId, v->tVertice.nodeId); + DEBUG_PC ("\t path till %s: AvailBw: %f Mb/s | Cost: %f | Latency: %f ms | Energy: %f Watts", v->tVertice.nodeId, availBw_through_u, distance_through_u, + latency_through_u, power_through_u); // Update Q list -- struct nodeItem_t *nodeItem = g_malloc0 (sizeof (struct nodeItem_t)); @@ -1505,26 +1616,32 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc nodeItem->distance = distance_through_u; memcpy(&nodeItem->distance, &distance_through_u, sizeof(gdouble)); memcpy(&nodeItem->latency, &latency_through_u, sizeof(gdouble)); + memcpy(&nodeItem->power, &power_through_u, sizeof(gdouble)); duplicate_node_id (&v->tVertice, &nodeItem->node); // add node to the Q list - *Q = g_list_insert_sorted (*Q, nodeItem, sort_by_distance); - //DEBUG_PC ("%s ADDED to Q (length: %d)", nodeItem->node.nodeId, g_list_length(*Q)); + if (arg & ENERGY_EFFICIENT_ARGUMENT) { + *Q = g_list_insert_sorted(*Q, nodeItem, sort_by_energy); + } + else { + *Q = g_list_insert_sorted (*Q, nodeItem, sort_by_distance); + } - // Update the mapNodes for the specific reached tv + // Update the mapNodes for the specific reached tv v_map->distance = distance_through_u; memcpy(&v_map->distance, &distance_through_u, sizeof(gdouble)); memcpy (&v_map->avaiBandwidth, &availBw_through_u, sizeof (gdouble)); memcpy (&v_map->latency, &latency_through_u, sizeof (gdouble)); + memcpy(&v_map->power, &power_through_u, sizeof(gdouble)); // Duplicate the predecessor edge into the mapNodes struct edges_t *e1 = &(v_map->predecessor); struct edges_t *e2 = &(v->edges[indexEdge]); - duplicate_edge (e1, e2); - DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId); - DEBUG_PC("v-pred aTopology: %s", e2->aTopologyId); - DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId); + duplicate_edge(e1, e2); + //DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId); + //DEBUG_PC("v-pred aTopology: %s", e2->aTopologyId); + //DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId); // Check whether v is dstPEId - //DEBUG_PC ("Targeted dstPEId: %s", req->dstPEId.nodeId); + //DEBUG_PC ("Targeted dstId: %s", s->service_endpoints_id[1].device_uuid); //DEBUG_PC ("nodeId added to the map: %s", v_map->verticeId.nodeId); //DEBUG_PC ("Q Length: %d", g_list_length(*Q)); g_free(path_constraints); @@ -1543,11 +1660,10 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gboolean check_computed_path_feasability (struct service_t *s, struct compRouteOutputItem_t* p) { +gboolean check_computed_path_feasibility (struct service_t *s, struct compRouteOutputItem_t* p) { float epsilon = 0.0000001; struct path_constraints_t* pathCons = get_path_constraints(s); gboolean ret = TRUE; - if (pathCons->latency == TRUE) { if ((pathCons->latencyConstraint - p->delay > 0.0) || (fabs(pathCons->latencyConstraint - p->delay) < epsilon)) { DEBUG_PC("Computed Path (latency: %f) is feasible wrt Connection Demand: %f", p->delay, pathCons->latencyConstraint); @@ -1558,8 +1674,7 @@ gboolean check_computed_path_feasability (struct service_t *s, struct compRouteO return FALSE; } } - // Other constraints... - + // Other constraints... g_free(pathCons); return ret; } @@ -1569,12 +1684,13 @@ gboolean check_computed_path_feasability (struct service_t *s, struct compRouteO * @file pathComp_tools.c * @brief Sorting the GList Q items by distance * + * @param a + * @param b * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint sort_by_distance (gconstpointer a, gconstpointer b) -{ +gint sort_by_distance (gconstpointer a, gconstpointer b) { //DEBUG_PC ("sort by distance a and b"); g_assert(a != NULL); g_assert(b != NULL); @@ -1592,13 +1708,55 @@ gint sort_by_distance (gconstpointer a, gconstpointer b) return 1; else if (node1->distance < node2->distance) return 0; - if (node1->distance == node2->distance) - { + if (node1->distance == node2->distance) { if (node1->latency > node2->latency) return 1; else if (node1->latency <= node2->latency) return 0; } + return 0; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Sorting the GList Q items by distance + * + * @param a + * @param b + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +gint sort_by_energy(gconstpointer a, gconstpointer b) { + g_assert(a != NULL); + g_assert(b != NULL); + + //DEBUG_PC ("sort by distance a and b"); + struct nodeItem_t* node1 = (struct nodeItem_t*)a; + struct nodeItem_t* node2 = (struct nodeItem_t*)b; + g_assert(node1); + g_assert(node2); + + //1st criteria: sorting by lowest distance + if (node1->distance > node2->distance) + return 1; + if (node1->distance < node2->distance) + return 0; + + // 2nd Criteria: sorting by the lowest energy + if (node1->power > node2->power) + return 1; + if (node1->power < node1->power) + return 0; + + // 3rd Criteria: by the latency + if (node1->latency > node2->latency) + return 1; + if (node1->latency <= node2->latency) + return 0; + return 0; } //////////////////////////////////////////////////////////////////////////////////////// @@ -1613,8 +1771,7 @@ gint sort_by_distance (gconstpointer a, gconstpointer b) ///////////////////////////////////////////////////////////////////////////////////////// struct graph_t * create_graph () { struct graph_t * g = g_malloc0 (sizeof (struct graph_t)); - if (g == NULL) - { + if (g == NULL) { DEBUG_PC ("Memory Allocation Problem"); exit (-1); } @@ -1633,8 +1790,7 @@ struct graph_t * create_graph () { ///////////////////////////////////////////////////////////////////////////////////////// struct map_nodes_t * create_map_node () { struct map_nodes_t * mN = g_malloc0 (sizeof (struct map_nodes_t)); - if (mN == NULL) - { + if (mN == NULL) { DEBUG_PC ("Memory allocation failed"); exit (-1); } @@ -1652,78 +1808,18 @@ struct map_nodes_t * create_map_node () { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// - struct service_t* get_service_for_computed_path(gchar* serviceUUID) { - for (gint i = 0; i < serviceList->numServiceList; i++) { - struct service_t* s = &(serviceList->services[i]); - if (strcmp(s->serviceId.service_uuid, serviceUUID) == 0) - return s; + gint i = 0; + for(GList *listnode = g_list_first(serviceList); + listnode; + listnode = g_list_next(listnode), i++) { + struct service_t* s = (struct service_t*)(listnode->data); + if (strcmp(s->serviceId.service_uuid, serviceUUID) == 0) + return s; } return NULL; } -//////////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_tools.c - * @brief Allocate memory for struct deviceList_t - * - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -struct deviceList_t* create_device_list() -{ - struct deviceList_t* dList = g_malloc0(sizeof(struct deviceList_t)); - if (dList == NULL) - { - DEBUG_PC("Memory Allocation Failure"); - exit(-1); - } - return dList; -} - -//////////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_tools.c - * @brief Allocate memory for struct linkList_t - * - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -struct linkList_t* create_link_list() { - struct linkList_t* lList = g_malloc0(sizeof(struct linkList_t)); - if (lList == NULL) - { - DEBUG_PC("Memory Allocation Failure"); - exit(-1); - } - lList->numLinks = 0; - return lList; -} - -//////////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_tools.c - * @brief Allocate memory for struct serviceList_t - * - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -struct serviceList_t* create_service_list() { - struct serviceList_t* sList = g_malloc0(sizeof(struct serviceList_t)); - if (sList == NULL) - { - DEBUG_PC("Memory Allocation Failure"); - exit(-1); - } - return sList; -} - //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c @@ -1766,8 +1862,7 @@ void print_service_type(guint type) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void print_link_port_direction(guint direction) -{ +void print_link_port_direction(guint direction) { switch (direction) { case LINK_PORT_DIRECTION_BIDIRECTIONAL: //DEBUG_PC("Bidirectional Port Direction"); @@ -1796,8 +1891,7 @@ void print_link_port_direction(guint direction) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void print_termination_direction(guint direction) -{ +void print_termination_direction(guint direction) { switch (direction) { case TERMINATION_DIRECTION_BIDIRECTIONAL: //DEBUG_PC("Bidirectional Termination Direction"); @@ -1922,26 +2016,6 @@ void print_link_forwarding_direction(guint linkFwDir) { return; } -//////////////////////////////////////////////////////////////////////////////////////// -/** - * @file pathComp_tools.c - * @brief Allocate memory for the contextSet - * - * @param - * - * @author Ricardo Martínez - * @date 2022 - */ - ///////////////////////////////////////////////////////////////////////////////////////// -struct contextSet_t* create_contextSet() { - struct contextSet_t* c = g_malloc0(sizeof(struct contextSet_t)); - if (c == NULL) { - DEBUG_PC("Memory Allocation Failure"); - exit(-1); - } - return c; -} - //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c @@ -1954,18 +2028,19 @@ struct contextSet_t* create_contextSet() { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct context_t* find_contextId_in_set(gchar* contextUuid, struct contextSet_t* set) { - - g_assert(set); - //DEBUG_PC("Checking if contextId: %s in in the ContextList??", contextUuid); - - for (gint i = 0; i < set->num_context_set; i++) { - struct context_t* c = &(set->contextList[i]); +struct context_t* find_contextId_in_set(gchar* contextUuid, GList** set) { + //DEBUG_PC("Checking if contextId: %s in in the ContextSet??", contextUuid); + gint i = 0; + for (GList *ln = g_list_first(*set); + ln; + ln = g_list_next(ln)){ + struct context_t* c = (struct context_t*)(ln->data); //DEBUG_PC("Context Item [%d] Id: %s", i, c->contextId); if (strcmp(contextUuid, c->contextId) == 0) { //DEBUG_PC("contextId: %s is FOUND in the ContextSet_List", contextUuid); return c; } + i++; } //DEBUG_PC("contextId: %s NOT FOUND in the ContextSet_List", contextUuid); return NULL; @@ -1983,11 +2058,19 @@ struct context_t* find_contextId_in_set(gchar* contextUuid, struct contextSet_t* * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct context_t* add_contextId_in_set(gchar *contextUuid, struct contextSet_t *set) { +struct context_t* add_contextId_in_set(gchar *contextUuid, GList** set) { - set->num_context_set++; - struct context_t* c = &(set->contextList[set->num_context_set - 1]); + struct context_t* c = g_malloc0(sizeof(struct context_t)); + if (c == NULL) { + DEBUG_PC("Memory Allocation Failure"); + exit(-1); + } duplicate_string(c->contextId, contextUuid); + // Add the context into the context set + //DEBUG_PC("Adding ContextId: %s", contextUuid); + //DEBUG_PC(" (BEFORE ADDING) Context Set Length: %d", g_list_length(*set)); + *set = g_list_append(*set, c); + //DEBUG_PC(" (AFTER ADDING) Context Set Length: %d", g_list_length(*set)); return c; } @@ -2004,9 +2087,7 @@ struct context_t* add_contextId_in_set(gchar *contextUuid, struct contextSet_t * */ ///////////////////////////////////////////////////////////////////////////////////////// struct vertices_t* find_vertex_in_graph_context(struct graph_t *g, gchar* deviceId) { - - for (gint i = 0; i < g->numVertices; i++) - { + for (gint i = 0; i < g->numVertices; i++) { struct vertices_t* v = &(g->vertices[i]); if (strcmp(v->verticeId.nodeId, deviceId) == 0) { return v; @@ -2027,10 +2108,11 @@ struct vertices_t* find_vertex_in_graph_context(struct graph_t *g, gchar* device * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct vertices_t* add_vertex_in_graph(struct graph_t* g, gchar* deviceId) { +struct vertices_t* add_vertex_in_graph(struct graph_t* g, struct device_t *d) { g->numVertices++; struct vertices_t* v = &(g->vertices[g->numVertices - 1]); - duplicate_string(v->verticeId.nodeId, deviceId); + duplicate_string(v->verticeId.nodeId, d->deviceId); + memcpy(&v->power_idle, &d->power_idle, sizeof(gdouble)); return v; } @@ -2040,17 +2122,24 @@ struct vertices_t* add_vertex_in_graph(struct graph_t* g, gchar* deviceId) { * @brief Construct the graphs (vertices and edges) bound to every individual context * * @param cSet + * @param activeFlag * * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void build_contextSet_deviceList(struct contextSet_t* cSet) { - // Check every device their endpoints - for (gint i = 0; i < deviceList->numDevices; i++) { - struct device_t* d = &(deviceList->devices[i]); +void build_contextSet_deviceList(GList** cSet, gint activeFlag) { + // Check every device their endpoints + for (GList* listnode = g_list_first(deviceList); + listnode; + listnode = g_list_next(listnode)) { + struct device_t* d = (struct device_t*)(listnode->data); //DEBUG_PC("Exploring DeviceId: %s", d->deviceId); + if ((activeFlag == 1) && (d->operational_status != 2)) { + // it is only considered devices with operational status enabled, i.e., set to 2 + continue; + } // Check the associated endPoints for (gint j = 0; j < d->numEndPoints; j++) { struct endPoint_t* eP = &(d->endPoints[j]); @@ -2058,18 +2147,17 @@ void build_contextSet_deviceList(struct contextSet_t* cSet) { struct endPointId_t* ePid = &(eP->endPointId); //end point id //DEBUG_PC(" EndPointId: %s || Type: %s", eP->endPointId.endpoint_uuid, d->deviceType); //DEBUG_PC(" TopologyId: %s || ContextId: %s", eP->endPointId.topology_id.topology_uuid, eP->endPointId.topology_id.contextId); - // Add contextId in ContextSet and the deviceId (+endpoint) into the vertex set struct context_t *c = find_contextId_in_set(eP->endPointId.topology_id.contextId, cSet); if (c == NULL) { - //DEBUG_PC(" contextUuid: %s MUST BE ADDED to ContextSet", eP->endPointId.topology_id.contextId); + DEBUG_PC(" contextUuid: %s MUST BE ADDED to ContextSet", eP->endPointId.topology_id.contextId); c = add_contextId_in_set(eP->endPointId.topology_id.contextId, cSet); } // Check if the deviceId and endPointUuid are already considered in the graph of the context c struct vertices_t* v = find_vertex_in_graph_context(&c->g, d->deviceId); if (v == NULL) { //DEBUG_PC(" deviceId: %s MUST BE ADDED to the Context Graph", d->deviceId); - v = add_vertex_in_graph(&c->g, d->deviceId); + v = add_vertex_in_graph(&c->g, d); } } } @@ -2132,8 +2220,10 @@ struct targetNodes_t* add_targeted_vertex_in_graph_context(struct vertices_t* v, ///////////////////////////////////////////////////////////////////////////////////////// struct endPoint_t* find_device_tied_endpoint(gchar* devId, gchar* endPointUuid) { //DEBUG_PC("devId: %s ePId: %s", devId, endPointUuid); - for (gint i = 0; i < deviceList->numDevices; i++) { - struct device_t* d = &(deviceList->devices[i]); + for (GList* ln = g_list_first(deviceList); + ln; + ln = g_list_next(ln)) { + struct device_t* d = (struct device_t*)(ln->data); if (strcmp(d->deviceId, devId) != 0) { continue; } @@ -2156,51 +2246,65 @@ struct endPoint_t* find_device_tied_endpoint(gchar* devId, gchar* endPointUuid) * * @param w * @param l + * @param activeFlag * * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void add_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l) { +void add_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l, gint activeFlag) { //DEBUG_PC("\t targetedVertex: %s", w->tVertice.nodeId); + + // Check if the activeFlag is 1. If YES, it is only added to the edges as long as the + // associated endPoint is in status ENABLED, i.e., with operational status set to 2 + // Get the endpoints (A and Z) of the link l (assumed P2P) + struct link_endpointId_t* aEndpointId = &(l->linkEndPointId[0]); + struct link_endpointId_t* zEndpointId = &(l->linkEndPointId[1]); + // Get the endPoint Information tied to the device bound to aEndPointId + struct endPoint_t* eP = find_device_tied_endpoint(aEndpointId->deviceId, aEndpointId->endPointId); + if (eP == NULL) { + DEBUG_PC("devId: %s endPointUuid: %s NOT in Device List!!--- Weird", aEndpointId->deviceId, aEndpointId->endPointId); + exit(-1); + } + // Check whether the port in that endPoint (eP) is Active upon the activeFlag being SET + if (activeFlag == 1) { + if (eP->operational_status != 2) // NOT ENABLED, then discard this link + return; + } + + // Add the edge into the graph w->numEdges++; struct edges_t* e = &(w->edges[w->numEdges - 1]); // Copy the link Id UUID duplicate_string(e->linkId, l->linkId); - - // copy the deviceId and endpointsIds (A --> Z) - struct link_endpointId_t* aEndpointId = &(l->linkEndPointId[0]); duplicate_string(e->aNodeId.nodeId, aEndpointId->deviceId); duplicate_string(e->aEndPointId, aEndpointId->endPointId); - duplicate_string(e->aTopologyId, aEndpointId->topology_id.topology_uuid); - - struct link_endpointId_t* zEndpointId = &(l->linkEndPointId[1]); + duplicate_string(e->aTopologyId, aEndpointId->topology_id.topology_uuid); duplicate_string(e->zNodeId.nodeId, zEndpointId->deviceId); duplicate_string(e->zEndPointId, zEndpointId->endPointId); duplicate_string(e->zTopologyId, zEndpointId->topology_id.topology_uuid); - - // The potential and available capacity is indeed retrieved using aEndpointId in the deviceList - struct endPoint_t* eP = find_device_tied_endpoint(aEndpointId->deviceId, aEndpointId->endPointId); - if (eP == NULL) { - DEBUG_PC("devId: %s endPointUuid: %s NOT in Device List!!--- Weird", aEndpointId->deviceId, aEndpointId->endPointId); - exit(-1); - } + //Potential(total) and available capacity e->unit = eP->potential_capacity.unit; memcpy(&e->totalCap, &eP->potential_capacity.value, sizeof(gdouble)); memcpy(&e->availCap, &eP->available_capacity.value, sizeof(gdouble)); - // Copy interdomain local/remote Ids memcpy(e->interDomain_localId, eP->inter_domain_plug_in.inter_domain_plug_in_local_id, strlen(eP->inter_domain_plug_in.inter_domain_plug_in_local_id)); memcpy(e->interDomain_remoteId, eP->inter_domain_plug_in.inter_domain_plug_in_remote_id, strlen(eP->inter_domain_plug_in.inter_domain_plug_in_remote_id)); - // cost value memcpy(&e->cost, &l->cost_characteristics.cost_value, sizeof(gdouble)); - - // latency + // latency ms memcpy(&e->delay, &l->latency_characteristics.fixed_latency, sizeof(gdouble)); + // energy J/bits ~ power + memcpy(&e->energy, &eP->energyConsumption, sizeof(gfloat)); + + //DEBUG_PC("Edge - Total/Available Capacity: %f/%f; Cost: %f; Delay: %f, Energy: %f", eP->potential_capacity.value, eP->available_capacity.value, + // l->cost_characteristics.cost_value, l->latency_characteristics.fixed_latency, l->energy_link); + + //DEBUG_PC("Graph Edge - Total/Available Capacity: %f/%f; Cost: %f; Delay: %f, Energy: %f", e->totalCap, e->availCap, + // e->cost, e->delay, e->energy); return; } @@ -2216,8 +2320,7 @@ void add_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l) * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -struct edges_t* find_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l) { - +struct edges_t* find_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l) { for (gint i = 0; i < w->numEdges; i++) { struct edges_t* e = &(w->edges[i]); if (strcmp(e->linkId, l->linkId) == 0) { @@ -2234,32 +2337,37 @@ struct edges_t* find_edge_in_targetedVertice_set(struct targetNodes_t* w, struct * contents/info of the link list * * @param set + * @param activeFlag * * @author Ricardo Martínez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void build_contextSet_linklList(struct contextSet_t* set) { - g_assert(set); - +void build_contextSet_linklList(GList** set, gint activeFlag) { // for each link in linkList: // 1st- Retrieve endpoints A --> B feauture (context Id, device Id, endpoint Id) // 2st - In the graph associated to the contextId, check wheter A (deviceId) is in the vertices list - // o No, this is weird ... exist + // o No, this is weird ... exit // o Yes, get the other link endpoint (i.e., B) and check whether it exists. If NOT add it, considering // all the attributes; Otherwise, check whether the link is different from existing edges between A and B + gdouble epsilon = 0.1; + gint j = 0; + for (GList* ln = g_list_first(linkList); + ln; + ln = g_list_next(ln)) { + struct link_t* l = (struct link_t*)(ln->data); + j++; - for (gint j = 0; j < linkList->numLinks; j++) { - struct link_t* l = &(linkList->links[j]); - // link assumed to be P2P A --> B; I.e. 2 endPoints; 1st specifies A and 2nd specifie B + // link assumed to be P2P A --> B; i.e. 2 endPoints; 1st specifies A and 2nd specifie B struct link_endpointId_t* aEndpointId = &(l->linkEndPointId[0]); struct topology_id_t* topologyId = &(aEndpointId->topology_id); // get the contextId gchar contextUuid[UUID_CHAR_LENGTH]; duplicate_string(contextUuid, topologyId->contextId); - //DEBUG_PC("Link: %s in Context: %s", l->linkId, contextUuid); + DEBUG_PC("Link: %s in ContextId: %s", l->linkId, contextUuid); // Check first contextUuid exists in the cSet + //DEBUG_PC("Length of Context: %d", g_list_length(set)); struct context_t* c = find_contextId_in_set(contextUuid, set); if (c == NULL) { DEBUG_PC("ContextId: %s does NOT exist... weird", contextUuid); @@ -2273,28 +2381,29 @@ void build_contextSet_linklList(struct contextSet_t* set) { struct graph_t* g = &(c->g); // get the graph associated to the context c struct vertices_t* v = find_vertex_in_graph_context(g, aDeviceId); if (v == NULL) { - DEBUG_PC("aDeviceId: %s IS NOT IN Vertices of contextId: %s", aDeviceId, contextUuid); + DEBUG_PC("%s NOT a VERTEX of contextId: %s ... WEIRD", aDeviceId, contextUuid); exit(-1); } // get the bEndpointId struct link_endpointId_t* bEndpointId = &(l->linkEndPointId[1]); gchar bDeviceId[UUID_CHAR_LENGTH]; duplicate_string(bDeviceId, bEndpointId->deviceId); + DEBUG_PC("[%d] -- Link: %s [%s ==> %s]", j-1, l->linkId, aDeviceId, bDeviceId); // Check whether device B is in the targeted Vertices from A (i.e., v)? // If not, add B in the targeted vertices B + create the edge and add it // If B exist, check whether the explored link/edge is already in the list of edges struct targetNodes_t* w = find_targeted_vertex_in_graph_context(v, bDeviceId); if (w == NULL) { - //DEBUG_PC("B device [%s] is PEER of A device [%s]", bDeviceId, v->verticeId.nodeId); + DEBUG_PC("[%s] is PEER of [%s]", bDeviceId, v->verticeId.nodeId); w = add_targeted_vertex_in_graph_context(v, bDeviceId); - add_edge_in_targetedVertice_set(w, l); + add_edge_in_targetedVertice_set(w, l, activeFlag); } else { // w exists, it is needed to check whether the edge (link) should be added struct edges_t* e = find_edge_in_targetedVertice_set(w, l); if (e == NULL) { // Add the link into the list - add_edge_in_targetedVertice_set(w, l); + add_edge_in_targetedVertice_set(w, l, activeFlag); } else { DEBUG_PC("The link already exists ..."); @@ -2316,21 +2425,47 @@ void build_contextSet_linklList(struct contextSet_t* set) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void build_contextSet(struct contextSet_t* cSet) { - g_assert(cSet); - g_assert(deviceList); - g_assert(linkList); +void build_contextSet(GList** cSet) { + gint activeFlag = 0; // this means that all the devices/links (regardless they are active or not) are considered // devices are tied to contexts, i.e. depending on the contextId of the devices - build_contextSet_deviceList(cSet); + build_contextSet_deviceList(cSet, activeFlag); + + DEBUG_PC("Length for the Context Set: %d", g_list_length(*cSet)); // Once the diverse contexts are created and the devices/endpoints asigned to the // respective graph tied to each context, it is needed to create the edges - build_contextSet_linklList(cSet); + build_contextSet_linklList(cSet, activeFlag); return; } +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Create the set of (distinct) contexts with the deviceList and linkList with + * operational status active + * + * @param cSet + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void build_contextSet_active(GList** cSet) { + gint activeFlag = 1; // this means that all the devices (regardless they are active or not) are considered + + // devices are tied to contexts, i.e. depending on the contextId of the devices + build_contextSet_deviceList(cSet, activeFlag); + + DEBUG_PC("Length for the Context Set: %d", g_list_length(*cSet)); + + // Once the diverse contexts are created and the devices/endpoints asigned to the + // respective graph tied to each context, it is needed to create the edges + build_contextSet_linklList(cSet, activeFlag); + return; +} + //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_tools.c @@ -2342,11 +2477,14 @@ void build_contextSet(struct contextSet_t* cSet) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -void print_contextSet(struct contextSet_t* set) { - g_assert(set); +void print_contextSet(GList* set) { - for (gint i = 0; i < set->num_context_set; i++) { - struct context_t* c = &(set->contextList[i]); + DEBUG_PC("Printing the ContextSet w/ number of Elements: %d", g_list_length(set)); + + for (GList* ln = g_list_first(set); + ln; + ln = g_list_next(ln)) { + struct context_t* c = (struct context_t*)(ln->data); DEBUG_PC("-------------------------------------------------------------"); DEBUG_PC(" Context Id: %s", c->contextId); DEBUG_PC("-------------------------------------------------------------"); @@ -2422,8 +2560,7 @@ gint same_src_dst_pe_nodeid(struct service_t* s) ///////////////////////////////////////////////////////////////////////////////////////// void comp_route_connection_issue_handler (struct compRouteOutput_t *path, struct service_t *s) { - g_assert(path); - g_assert(s); + g_assert(path); g_assert(s); // Increase the number of computed routes/paths despite there was an issue to be reported path->numPaths++; @@ -2472,8 +2609,7 @@ void destroy_compRouteOutputList (struct compRouteOutputList_t *ro) */ ///////////////////////////////////////////////////////////////////////////////////////// void duplicate_graph (struct graph_t *originalGraph, struct graph_t *destGraph) { - g_assert (originalGraph); - g_assert (destGraph); + g_assert (originalGraph); g_assert (destGraph); destGraph->numVertices = originalGraph->numVertices; for (gint i = 0; i < originalGraph->numVertices; i++) { @@ -2481,6 +2617,7 @@ void duplicate_graph (struct graph_t *originalGraph, struct graph_t *destGraph) struct vertices_t *dVertex = &(destGraph->vertices[i]); dVertex->numTargetedVertices = oVertex->numTargetedVertices; duplicate_node_id (&oVertex->verticeId, &dVertex->verticeId); + memcpy(&dVertex->power_idle, &oVertex->power_idle, sizeof(gdouble)); for (gint j = 0; j < oVertex->numTargetedVertices; j++) { struct targetNodes_t *oTargetedVertex = &(oVertex->targetedVertices[j]); @@ -2596,9 +2733,7 @@ struct edges_t* get_reverse_edge_from_the_graph(struct edges_t* e, struct graph_ ///////////////////////////////////////////////////////////////////////////////////////// void allocate_graph_resources (struct path_t *p, struct service_t *s, struct graph_t *g) { - g_assert (p); - g_assert (s); - g_assert (g); + g_assert (p); g_assert (s); g_assert (g); // Retrieve the requested bw by the service struct path_constraints_t* pathCons = get_path_constraints(s); @@ -2617,8 +2752,7 @@ void allocate_graph_resources (struct path_t *p, struct service_t *s, struct gra memcpy(&e->availCap, &resBw, sizeof(gdouble)); DEBUG_PC("Final e/link avail Bw: %f", e->availCap); } - g_free(pathCons); - + g_free(pathCons); return; } @@ -2633,14 +2767,12 @@ void allocate_graph_resources (struct path_t *p, struct service_t *s, struct gra * @parma g * * @author Ricardo Martínez - * @date 2021 + * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// void allocate_graph_reverse_resources(struct path_t* p, struct service_t * s, struct graph_t* g) { - g_assert(p); - g_assert(s); - g_assert(g); + g_assert(p); g_assert(s); g_assert(g); struct path_constraints_t* pathCons = get_path_constraints(s); for (gint i = 0; i < p->numPathLinks; i++) { @@ -2674,20 +2806,20 @@ void allocate_graph_reverse_resources(struct path_t* p, struct service_t * s, st * @param routeList * * @author Ricardo Martínez - * @date 2021 + * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// void print_path_connection_list(struct compRouteOutputList_t* routeList) { g_assert(routeList); for (gint i = 0; i < routeList->numCompRouteConnList; i++) { - DEBUG_PC("==================== Service Item: %d ===================", i); + DEBUG_PC("==================== Service instance: %d ===================", i); struct compRouteOutput_t* rO = &(routeList->compRouteConnection[i]); DEBUG_PC("num service endpoints: %d", rO->num_service_endpoints_id); struct serviceId_t* s = &(rO->serviceId); DEBUG_PC("ContextId: %s, ServiceId: %s", s->contextId, s->service_uuid); - DEBUG_PC("ingress --- %s [%s]", rO->service_endpoints_id[0].device_uuid, + DEBUG_PC("ingress - %s[%s]", rO->service_endpoints_id[0].device_uuid, rO->service_endpoints_id[0].endpoint_uuid); - DEBUG_PC("egress --- %s [%s]", rO->service_endpoints_id[1].device_uuid, + DEBUG_PC("egress - %s [%s]", rO->service_endpoints_id[1].device_uuid, rO->service_endpoints_id[1].endpoint_uuid); if (rO->noPathIssue == NO_PATH_CONS_ISSUE) { @@ -2713,7 +2845,7 @@ void print_path_connection_list(struct compRouteOutputList_t* routeList) { * @param d * * @author Ricardo Martínez - * @date 2021 + * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// void update_stats_path_comp(struct compRouteOutputList_t* routeConnList, struct timeval d, gint numSuccesPathComp, gint numPathCompIntents) { @@ -2729,8 +2861,11 @@ void update_stats_path_comp(struct compRouteOutputList_t* routeConnList, struct DEBUG_PC("Succesfully Comp: %d | Path Comp Requests: %d", numSuccesPathComp, numPathCompIntents); DEBUG_PC("AV. PATH COMP ALG. TIME: %f ms", av_alg_comp_time); - for (gint i = 0; i < serviceList->numServiceList; i++) { - struct service_t* s = &(serviceList->services[i]); + gint i = 0; + for (GList* listnode = g_list_first(serviceList); + listnode; + listnode = g_list_next(listnode), i++) { + struct service_t* s = (struct service_t*)(listnode->data); char* eptr; for (gint j = 0; j < s->num_service_constraints; j++) { struct constraint_t* constraints = &(s->constraints[j]); @@ -2739,6 +2874,7 @@ void update_stats_path_comp(struct compRouteOutputList_t* routeConnList, struct } } } + for (gint k = 0; k < routeConnList->numCompRouteConnList; k++) { struct compRouteOutput_t* rO = &(routeConnList->compRouteConnection[k]); if (rO->noPathIssue == NO_PATH_CONS_ISSUE) { @@ -2764,5 +2900,521 @@ void update_stats_path_comp(struct compRouteOutputList_t* routeConnList, struct gdouble avBlockedBwRatio = (gdouble)(1.0 - avServedRatio); DEBUG_PC("AV. BBE: %f", avBlockedBwRatio); return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Eliminate active service path + * + * @param actServPath + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void destroy_active_service_path(struct activeServPath_t* actServPath) { + g_assert(actServPath); + g_free(actServPath); + return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Eliminate active service + * + * @param actService + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void destroy_active_service(struct activeService_t* actService) { + g_assert(actService); + g_list_free_full(g_steal_pointer(&actService->activeServPath), (GDestroyNotify)destroy_active_service_path); + g_free(actService); + return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Eliminate a requested service + * + * @param s + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void destroy_requested_service(struct service_t* s) { + g_assert(s); + g_free(s); + return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Eliminate a device + * + * @param d + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void destroy_device(struct device_t* d) { + g_assert(d); + g_free(d); + return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Eliminate a link from the linkList + * + * @param d + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void destroy_link(struct link_t* l) { + g_assert(l); + g_free(l); + return; +} +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Eliminate a context from the contextSet + * + * @param d + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void destroy_context(struct context_t* c) { + g_assert(c); + g_free(c); + return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief Excecution Dijkstra algorithm + * + * @param srcMapIndex + * @param dstMapIndex + * @param g + * @param s + * @param mapNodes + * @param SN + * @param RP + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct service_t* s, + struct map_nodes_t* mapNodes, struct nodes_t* SN, struct compRouteOutputItem_t* RP, + guint arg) { + g_assert(s);g_assert(g); + + // Set params into mapNodes related to the source nodes of the request + mapNodes->map[srcMapIndex].distance = 0.0; + mapNodes->map[srcMapIndex].latency = 0.0; + mapNodes->map[srcMapIndex].avaiBandwidth = 0.0; + mapNodes->map[srcMapIndex].power = 0.0; + + // Initialize the set Q and S + GList *S = NULL, *Q = NULL; + gint indexVertice = -1; + + // Add the source into the Q + struct nodeItem_t* nodeItem = g_malloc0(sizeof(struct nodeItem_t)); + if (nodeItem == NULL) { + DEBUG_PC("memory allocation failed\n"); + exit(-1); + } + // initialize some nodeItem attributes + nodeItem->distance = 0.0; + nodeItem->latency = 0.0; + nodeItem->power = 0.0; + duplicate_node_id(&mapNodes->map[srcMapIndex].verticeId, &nodeItem->node); + + // Select the optimization process + if (arg & ENERGY_EFFICIENT_ARGUMENT) + Q = g_list_insert_sorted(Q, nodeItem, sort_by_energy); + // more "if" according to different optimization criteria ... + else + Q = g_list_insert_sorted(Q, nodeItem, sort_by_distance); + + // Check whether there is spurNode (SN) and rootPath (RP) + if (SN != NULL && RP != NULL) { + struct routeElement_t* re; + for (gint j = 0; j < RP->numRouteElements; j++) { + // Get the source and target Nodes of the routeElement within the rootPath + re = &RP->routeElement[j]; + DEBUG_PC("root Link: aNodeId: %s (%s) --> zNodeiId: %s (%s)", re->aNodeId.nodeId, re->aEndPointId, re->zNodeId.nodeId, re->zEndPointId); + + // if ingress of the root link (aNodeId) is the spurNode, then stops + if (compare_node_id(&re->aNodeId, SN) == 0) { + DEBUG_PC("Ingress Node rootLink %s = spurNode %s; STOP exploring rootPath (RP)", re->aNodeId.nodeId, SN->nodeId); + break; + } + // Extract from Q + GList* listnode = g_list_first(Q); + struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); + Q = g_list_remove(Q, node); + + indexVertice = graph_vertice_lookup(node->node.nodeId, g); + g_assert(indexVertice >= 0); + + // Get the indexTargetedVertice + gint indexTVertice = -1; + indexTVertice = graph_targeted_vertice_lookup(indexVertice, re->zNodeId.nodeId, g); + gint done = check_link(node, indexVertice, indexTVertice, g, s, &S, &Q, mapNodes, arg); + (void)done; + // Add to the S list + S = g_list_append(S, node); + } + // Check that the first node in Q set is SpurNode, otherwise something went wrong ... + if (compare_node_id(&re->aNodeId, SN) != 0) { + DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId); + g_list_free_full(g_steal_pointer(&S), g_free); + g_list_free_full(g_steal_pointer(&Q), g_free); + return; + } + } + while (g_list_length(Q) > 0) { + //Extract from Q set + GList* listnode = g_list_first(Q); + struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); + Q = g_list_remove(Q, node); + DEBUG_PC("Q length: %d", g_list_length(Q)); + DEBUG_PC("Explored DeviceId: %s", node->node.nodeId); + + // scan all the links from u within the graph + indexVertice = graph_vertice_lookup(node->node.nodeId, g); + g_assert(indexVertice >= 0); + + // Check the targeted vertices from u + for (gint i = 0; i < g->vertices[indexVertice].numTargetedVertices; i++) { + gint done = check_link(node, indexVertice, i, g, s, &S, &Q, mapNodes, arg); + (void)done; + } + // Add node into the S Set + S = g_list_append(S, node); + //DEBUG_PC ("S length: %d", g_list_length (S)); + } + g_list_free_full(g_steal_pointer(&S), g_free); + g_list_free_full(g_steal_pointer(&Q), g_free); + return; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief KSP computation using Dijkstra algorithm + * + * @param pred + * @param g + * @param s + * @param SN + * @param RP + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, + struct nodes_t* SN, struct compRouteOutputItem_t* RP, + struct map_nodes_t* mapNodes, guint arg) { + g_assert(pred); g_assert(g); g_assert(s); + + DEBUG_PC("SOURCE: %s --> DESTINATION: %s", s->service_endpoints_id[0].device_uuid, + s->service_endpoints_id[1].device_uuid); + + // Check the both ingress src and dst endpoints are in the graph + gint srcMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[0].device_uuid, mapNodes); + if (srcMapIndex == -1) { + DEBUG_PC("ingress DeviceId: %s NOT in G", s->service_endpoints_id[0].device_uuid); + return -1; + } + + gint dstMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); + if (dstMapIndex == -1) { + DEBUG_PC("egress DeviceId: %s NOT in G", s->service_endpoints_id[1].device_uuid); + return -1; + } + + //DEBUG_PC("srcMapIndex: %d (node: %s)", srcMapIndex, mapNodes->map[srcMapIndex].verticeId.nodeId); + //DEBUG_PC("dstMapIndex: %d (node: %s)", dstMapIndex, mapNodes->map[dstMapIndex].verticeId.nodeId); + + // Compute the shortest path route + dijkstra(srcMapIndex, dstMapIndex, g, s, mapNodes, SN, RP, arg); + + // Check that a feasible solution in term of latency and bandwidth is found + gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); + struct map_t* dest_map = &mapNodes->map[map_dstIndex]; + if (!(dest_map->distance < INFINITY_COST)) { + DEBUG_PC("DESTINATION: %s NOT reachable", s->service_endpoints_id[1].device_uuid); + return -1; + } + + DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth); + // Check that the computed available bandwidth is larger than 0.0 + if (dest_map->avaiBandwidth <= (gfloat)0.0) { + DEBUG_PC("DESTINATION %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid); + return -1; + } + DEBUG_PC("DESTINATION %s REACHABLE", s->service_endpoints_id[1].device_uuid); + // Handle predecessors + build_predecessors(pred, s, mapNodes); + return 1; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief set the path parameters (e.g., latency, cost, power, ...) to an under-constructed + * path from the computed map vertex + * + * @param p + * @param mapV + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void set_path_attributes(struct compRouteOutputItem_t* p, struct map_t* mapV) { + g_assert(p); g_assert(mapV); + memcpy(&p->cost, &mapV->distance, sizeof(gdouble)); + memcpy(&p->availCap, &mapV->avaiBandwidth, sizeof(mapV->avaiBandwidth)); + memcpy(&p->delay, &mapV->latency, sizeof(mapV->latency)); + memcpy(&p->power, &mapV->power, sizeof(gdouble)); + return; +} + +//////////////////////////////////////////////////////////////////////////////////////// +/** + * @file pathComp_tools.c + * @brief K-CSPF algorithm execution (YEN algorithm) + * + * @param s + * @param path + * @param g + * @param optimization_flag + * + * @author Ricardo Martínez + * @date 2022 + */ + ///////////////////////////////////////////////////////////////////////////////////////// +void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g, guint arg) { + g_assert(s); g_assert(path); g_assert(g); + + // Check if the service specifies a nuumber of K paths to be explored/computed for the + // service. If not, compute that number; otherwise set the max number of explored + // computed paths to MAX_KSP_VALUE + guint maxK = 0; + if(s->kPaths_inspected == 0) { + maxK = MAX_KSP_VALUE; + } + else { + maxK = s->kPaths_inspected; + } + DEBUG_PC("The KSP considers K: %d", maxK); + + // create map of devices/nodes to handle the path computation using the context + struct map_nodes_t* mapNodes = create_map_node(); + build_map_node(mapNodes, g); + + // predecessors to store the computed path + struct pred_t* predecessors = create_predecessors(); + struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]); + struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]); + + DEBUG_PC("======================================================================================="); + DEBUG_PC("STARTING PATH COMP FOR %s[%s] --> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); + + // Compute the 1st KSP path + gint done = ksp_comp(predecessors, g, s, NULL, NULL, mapNodes, arg); + if (done == -1) { + DEBUG_PC("NO PATH for %s[%s] --> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); + comp_route_connection_issue_handler(path, s); + g_free(mapNodes); g_free(predecessors); + return; + } + + // Construct the path from the computed predecessors + struct compRouteOutputItem_t* p = create_path_item(); + //print_predecessors(predecessors); + build_path(p, predecessors, s); + gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes); + struct map_t* dst_map = &mapNodes->map[indexDest]; + // Get the delay and cost + set_path_attributes(p, dst_map); + + // Add the computed path, it may be a not feasible path, but at the end it is + // checked all the feasible paths, and select the first one + print_path(p); + + // Copy the serviceId + copy_service_id(&path->serviceId, &s->serviceId); + // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) + for (gint i = 0; i < s->num_service_endpoints_id; i++) { + struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]); + struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]); + copy_service_endpoint_id(oEp, iEp); + } + path->num_service_endpoints_id = s->num_service_endpoints_id; + + DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", maxK); + // Create A and B sets of paths to handle the YEN algorithm + struct path_set_t *A = create_path_set(), *B = create_path_set(); + // Add 1st Computed path into A->paths[0] + duplicate_path(p, &A->paths[0]); + A->numPaths++; + g_free(predecessors); g_free(p); + for (gint k = 1; k < maxK; k++) { + DEBUG_PC("*************************** kth (%d) ***********************************", k); + struct compRouteOutputItem_t* p = create_path_item(); + duplicate_path(&A->paths[k - 1], p); + // The spurNode ranges from near-end node of the first link to the near-end of the last link forming the kth path + gint i = 0; + struct compRouteOutputItem_t* rootPath = create_path_item(); + for (i = 0; i < p->numRouteElements; i++) { + struct nodes_t *spurNode = create_node(), *nextSpurNode = create_node(); + struct routeElement_t* re = &(p->routeElement[i]); + // Create predecessors to store the computed path + struct pred_t* predecessors = create_predecessors(); + // Clear previous mapNodes, i.e. create it again + g_free(mapNodes); + mapNodes = create_map_node(); + build_map_node(mapNodes, g); + struct nodes_t* n = &re->aNodeId; + duplicate_node_id(n, spurNode); + n = &re->zNodeId; + duplicate_node_id(n, nextSpurNode); + DEBUG_PC("spurNode: %s --> nextSpurNode: %s", spurNode->nodeId, nextSpurNode->nodeId); + + // rootPath contains a set of links of A[k-1] from the source Node till the SpurNode -> NextSpurNode + // Example: A[k-1] = {L1, L2, L3, L4}, i.e. " Node_a -- L1 --> Node_b -- L2 --> Node_c -- L3 --> Node_d -- L4 --> Node_e " + // E.g., for the ith iteration if the spurNode = Node_c and NextSpurNode = Node_d; then rootPath = {L1, L2, L3} + add_routeElement_path_back(re, rootPath); + DEBUG_PC("\n"); + DEBUG_PC("^^^^^^^rootPath^^^^^^^"); + print_path(rootPath); + + // For all existing and computed paths p in A check if from the source to the NextSpurNode + // the set of links matches with those contained in the rootPath + // If YES, remove from the auxiliary graph the next link in p from NextSpurNode + // Otherwise do nothing + struct graph_t* gAux = create_graph(); + duplicate_graph(g, gAux); + // Modified graph + modify_targeted_graph(gAux, A, rootPath, spurNode); + + // Trigger the computation of the path from src to dst constrained to traverse all the links from src + // to spurNode contained into rootPath over the resulting graph + if (ksp_comp(predecessors, gAux, s, spurNode, rootPath, mapNodes, arg) == -1) { + DEBUG_PC("FAILED SP from %s via spurNode: %s to %s", iEp->device_uuid, spurNode->nodeId, eEp->device_uuid); + g_free(nextSpurNode); g_free(spurNode); + g_free(gAux); g_free(predecessors); + continue; + } + DEBUG_PC("SUCCESFUL SP from %s via spurNode: %s to %s", iEp->device_uuid, spurNode->nodeId, eEp->device_uuid); + // Create the node list from the predecessors + struct compRouteOutputItem_t* newKpath = create_path_item(); + build_path(newKpath, predecessors, s); + DEBUG_PC("new K (for k: %d) Path is built", k); + gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes); + struct map_t* dst_map = &mapNodes->map[indexDest]; + set_path_attributes(newKpath, dst_map); + DEBUG_PC("New PATH (@ kth: %d) ADDED to B[%d] - {Path Cost: %f, e2e latency: %f, bw: %f, Power: %f ", k, B->numPaths, newKpath->cost, + newKpath->delay, newKpath->availCap, newKpath->power); + // Add the computed kth SP to the heap B + duplicate_path(newKpath, &B->paths[B->numPaths]); + B->numPaths++; + DEBUG_PC("Number of B paths: %d", B->numPaths); + + g_free(newKpath); g_free(nextSpurNode); g_free(spurNode); + g_free(gAux); g_free(predecessors); + } + // If B is empty then stops + if (B->numPaths == 0) { + DEBUG_PC("B does not have any path ... the stops kth computation"); + break; + } + + // Sort the potential B paths according to different optimization parameters + sort_path_set(B, arg); + // Add the lowest path into A[k] + DEBUG_PC("-------------------------------------------------------------"); + DEBUG_PC("Append SP for B[0] to A[%d] --- Cost: %f, Latency: %f, Power: %f", A->numPaths, B->paths[0].cost, + B->paths[0].delay, B->paths[0].power); + duplicate_path(&B->paths[0], &A->paths[A->numPaths]); + A->numPaths++; + DEBUG_PC("A Set size: %d", A->numPaths); + DEBUG_PC("-------------------------------------------------------------"); + + // Remove/Pop front element from the path set B (i.e. remove B[0]) + pop_front_path_set(B); + DEBUG_PC("B Set Size: %d", B->numPaths); + } + + // Copy the serviceId + copy_service_id(&path->serviceId, &s->serviceId); + // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) + for (gint m = 0; m < s->num_service_endpoints_id; m++) { + struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[m]); + struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[m]); + copy_service_endpoint_id(oEp, iEp); + } + path->num_service_endpoints_id = s->num_service_endpoints_id; + + // Print all the paths i A + for (gint h = 0; h < A->numPaths; h++) { + DEBUG_PC("================== A[%d] =======================", h); + print_path(&A->paths[h]); + } + DEBUG_PC("Number of paths: %d", path->numPaths); + // For all the computed paths in A, pick the one being feasible wrt the service constraints + for (gint ksp = 0; ksp < A->numPaths; ksp++) { + if (ksp >= s->kPaths_returned) { + DEBUG_PC("Number Requested/returned paths (%d) REACHED - STOP", ksp); + break; + } + gdouble feasibleRoute = check_computed_path_feasibility(s, &A->paths[ksp]); + if (feasibleRoute == TRUE) { + DEBUG_PC("A[%d] available: %f, pathCost: %f; latency: %f, Power: %f", ksp, A->paths[ksp].availCap, + A->paths[ksp].cost, A->paths[ksp].delay, A->paths[ksp].power); + struct compRouteOutputItem_t* pathaux = &A->paths[ksp]; + path->numPaths++; + struct path_t* targetedPath = &path->paths[path->numPaths - 1]; + duplicate_path_t(pathaux, targetedPath); + print_path_t(targetedPath); + //remove_path_set(A); + //remove_path_set(B); + //return; + } + } + remove_path_set(A); + remove_path_set(B); + // At least 1 out (K) paths was found, then K-SP succeded + if (path->numPaths > 0) { + DEBUG_PC("K-SP succeeded"); + return; + } + // No paths found --> Issue + DEBUG_PC("K-SP failed!!!"); + comp_route_connection_issue_handler(path, s); + return; } diff --git a/src/pathcomp/backend/pathComp_tools.h b/src/pathcomp/backend/pathComp_tools.h index b6bcea04c8aa01b6cf730460e0075327f872f344..49280d543a52ede118a1baee988484671bc76f8d 100644 --- a/src/pathcomp/backend/pathComp_tools.h +++ b/src/pathcomp/backend/pathComp_tools.h @@ -23,17 +23,22 @@ #include // External variables -extern struct map_nodes_t* mapNodes; -extern struct graph_t* graph; -extern struct contextSet_t* contextSet; -extern struct linkList_t* linkList; -extern struct deviceList_t* deviceList; -extern struct serviceList_t* serviceList; +extern GList* contextSet; +extern GList* linkList; +extern GList* deviceList; +extern GList* serviceList; +extern GList* activeServList; + +////////////////////////////////////////////////////////// +// Optimization computation argument +////////////////////////////////////////////////////////// +#define NO_OPTIMIZATION_ARGUMENT 0x00000000 +#define ENERGY_EFFICIENT_ARGUMENT 0x00000001 #define INFINITY_COST 0xFFFFFFFF #define MAX_NUM_PRED 100 -#define MAX_KSP_VALUE 3 +#define MAX_KSP_VALUE 5 // HTTP RETURN CODES #define HTTP_CODE_OK 200 @@ -54,8 +59,9 @@ struct nodes_t { struct nodeItem_t { struct nodes_t node; - gdouble distance; - gdouble latency; + gdouble distance; // traversed distance + gdouble latency; // incured latency + gdouble power; //consumed power }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -80,7 +86,8 @@ struct edges_t { gdouble totalCap, availCap; gdouble cost; - gdouble delay; + gdouble delay; + gdouble energy; // inter-domain local and remote Ids gchar interDomain_localId[MAX_INTER_DOMAIN_PLUG_IN_SIZE]; @@ -107,7 +114,8 @@ struct map_t { struct edges_t predecessor; gdouble distance; gdouble avaiBandwidth; - gdouble latency; + gdouble latency; + gdouble power; }; #define MAX_MAP_NODE_SIZE 100 @@ -116,8 +124,9 @@ struct map_nodes_t { gint numMapNodes; }; -#define MAX_NUM_VERTICES 20 // 100 # LGR: reduced from 100 to 20 to divide by 5 the memory used -#define MAX_NUM_EDGES 40 // 100 # LGR: reduced from 100 to 40 to divide by 2.5 the memory used +#define MAX_NUM_VERTICES 100 // 100 # LGR: reduced from 100 to 20 to divide by 5 the memory used +#define MAX_NUM_EDGES 5 // 100 # LGR: reduced from 100 to 5 to divide by 20 the memory used + // Structures for the graph composition struct targetNodes_t { // remote / targeted node @@ -131,6 +140,7 @@ struct vertices_t { struct targetNodes_t targetedVertices[MAX_NUM_VERTICES]; gint numTargetedVertices; struct nodes_t verticeId; + gdouble power_idle; // power idle of the device (due to the fans, etc.) }; struct graph_t { @@ -147,15 +157,6 @@ struct context_t { struct graph_t g; }; -//////////////////////////////////////////////////// -// Structure for the Set of Contexts -/////////////////////////////////////////////////// -#define MAX_NUMBER_CONTEXT 1 // 100 # LGR: reduced from 100 to 1 to divide by 100 the memory used -struct contextSet_t { - struct context_t contextList[MAX_NUMBER_CONTEXT]; - gint num_context_set; -}; - #define MAX_ALG_ID_LENGTH 10 //////////////////////////////////////////////////// // External Variables @@ -241,33 +242,25 @@ struct endPoint_t { struct capacity_t available_capacity; // inter-domain identifiers struct inter_domain_plug_in_t inter_domain_plug_in; + gfloat energyConsumption; // in nJ/bit + gint operational_status; // 0 Undefined, 1 Disabled, 2 Enabled }; /////////////////////////////////////////////////////////////////// // Structure for the device contents /////////////////////////////////////////////////////////////////// #define MAX_DEV_TYPE_SIZE 128 -#define MAX_DEV_ENDPOINT_LENGTH 40 // 10 # LGR: controllers might have large number of endpoints +#define MAX_DEV_ENDPOINT_LENGTH 100 // 10 # LGR: controllers might have large number of endpoints struct device_t { + gdouble power_idle; // power idle (baseline) of the switch in Watts + gint operational_status; // 0 - Undefined, 1 - Disabled, 2 - Enabled gchar deviceId[UUID_CHAR_LENGTH]; // device ID using UUID (128 bits) - gchar deviceType[MAX_DEV_TYPE_SIZE]; // Specifies the device type - // define the endpoints attached to the device gint numEndPoints; struct endPoint_t endPoints[MAX_DEV_ENDPOINT_LENGTH]; }; -/////////////////////////////////////////////////////////////////// -// Structure for the device List -/////////////////////////////////////////////////////////////////// -#define MAX_NUM_DEVICE 200 -struct deviceList_t { - // device information - gint numDevices; - struct device_t devices[MAX_NUM_DEVICE]; -}; - /////////////////////////////////////////////////////////////////// // Structure for the link EndPoint Id /////////////////////////////////////////////////////////////////// @@ -294,6 +287,13 @@ struct latency_characteristics_t { gdouble fixed_latency; }; +/////////////////////////////////////////////////////////////////// +// Structure for the latency characteristics of the link +/////////////////////////////////////////////////////////////////// +struct power_characteristics_t { + gdouble power; +}; + /////////////////////////////////////////////////////////////////// // Structure for the link /////////////////////////////////////////////////////////////////// @@ -304,10 +304,10 @@ struct latency_characteristics_t { #define LINK_FORWARDING_DIRECTION_UNKNOWN 2 struct link_t { gchar linkId[UUID_CHAR_LENGTH]; // link Id using UUID (128 bits) - + //gdouble energy_link; // in nJ/bit + //gint operational_status; // 0 Undefined, 1 Disabled, 2 Enabled gint numLinkEndPointIds; struct link_endpointId_t linkEndPointId[MAX_NUM_LINK_ENDPOINT_IDS]; - guint forwarding_direction; struct capacity_t potential_capacity; struct capacity_t available_capacity; @@ -315,15 +315,6 @@ struct link_t { struct latency_characteristics_t latency_characteristics; }; -/////////////////////////////////////////////////////////////////// -// Structure for the link List -/////////////////////////////////////////////////////////////////// -#define MAX_NUM_LIST 2000 -struct linkList_t { - gint numLinks; - struct link_t links[MAX_NUM_LIST]; -}; - //////////////////////////////////////////////////// // Structure for service Identifier /////////////////////////////////////////////////// @@ -362,15 +353,12 @@ struct constraint_t { #define MAX_NUM_SERVICE_ENPOINTS_ID 2 #define MAX_NUM_SERVICE_CONSTRAINTS 10 -struct service_t { - // Indentifier used to determine the used Algorithm Id, e.g., KSP - gchar algId[MAX_ALG_ID_LENGTH]; - - // PATHS expected for the output - guint kPaths; +struct service_t { + gchar algId[MAX_ALG_ID_LENGTH]; // Indentifier used to determine the used Algorithm Id, e.g., KSP + guint kPaths_inspected; // PATHS expected to be inspected + guint kPaths_returned; // Maximum number of PATHS to be returned struct serviceId_t serviceId; - guint service_type; // unknown, l2nm, l3nm, tapi // endpoints of the network connectivity service, assumed p2p @@ -403,10 +391,27 @@ struct path_constraints_t { //////////////////////////////////////////////////// // Structure for the handling the service requests /////////////////////////////////////////////////// -#define MAX_SERVICE_LIST 100 -struct serviceList_t { - struct service_t services[MAX_SERVICE_LIST]; - gint numServiceList; +//#define MAX_SERVICE_LIST 100 +//struct serviceList_t { +// struct service_t services[MAX_SERVICE_LIST]; +// gint numServiceList; +//}; + +//////////////////////////////////////////////////// +// Structure for the handling the active services +/////////////////////////////////////////////////// +struct activeServPath_t { + struct topology_id_t topology_id; + gchar deviceId[UUID_CHAR_LENGTH]; + gchar endPointId[UUID_CHAR_LENGTH]; +}; + +struct activeService_t { + struct serviceId_t serviceId; + guint service_type; // unknown, l2nm, l3nm, tapi + struct service_endpoints_id_t service_endpoints_id[MAX_NUM_SERVICE_ENPOINTS_ID]; + guint num_service_endpoints_id; + GList* activeServPath; }; //////////////////////////////////////////////////////////////////////////////////////////// @@ -425,8 +430,7 @@ struct pathLink_t { gchar zEndPointId[UUID_CHAR_LENGTH]; struct topology_id_t topologyId; - - struct linkTopology_t linkTopologies[2]; // a p2p link (at most) can connect to devices (endpoints) attached to 2 different topologies + struct linkTopology_t linkTopologies[2]; // A p2p link (at most) can connect to devices (endpoints) attached to 2 different topologies gint numLinkTopologies; }; @@ -454,13 +458,13 @@ struct routeElement_t { gchar contextId[UUID_CHAR_LENGTH]; }; -struct compRouteOutputItem_t { - // Potential(total) and available capacity +struct compRouteOutputItem_t { gint unit; gdouble totalCap, availCap; gdouble cost; gdouble delay; + gdouble power; struct routeElement_t routeElement[MAX_ROUTE_ELEMENTS]; gint numRouteElements; @@ -477,6 +481,7 @@ struct path_t { struct capacity_t path_capacity; struct latency_characteristics_t path_latency; struct cost_characteristics_t path_cost; + struct power_characteristics_t path_power; struct pathLink_t pathLinks[MAX_NUM_PATH_LINKS]; guint numPathLinks; @@ -484,18 +489,14 @@ struct path_t { #define NO_PATH_CONS_ISSUE 1 // No path due to a constraint issue #define MAX_NUM_COMPUTED_PATHS 10 -struct compRouteOutput_t -{ +struct compRouteOutput_t { // object describing the service identifier: serviceId and contextId struct serviceId_t serviceId; - // array describing the service endpoints ids struct service_endpoints_id_t service_endpoints_id[MAX_NUM_SERVICE_ENPOINTS_ID]; guint num_service_endpoints_id; - struct path_t paths[MAX_NUM_COMPUTED_PATHS]; - gint numPaths; - + gint numPaths; // if the transport connectivity service cannot be computed, this value is set to 0 determining the constraints were not fulfilled gint noPathIssue; }; @@ -504,8 +505,7 @@ struct compRouteOutput_t // Structure to handle the response list with all the computed network connectivity services //////////////////////////////////////////////////////////////////////////////////////////// #define MAX_COMP_CONN_LIST 100 -struct compRouteOutputList_t -{ +struct compRouteOutputList_t { struct compRouteOutput_t compRouteConnection[MAX_COMP_CONN_LIST]; gint numCompRouteConnList; @@ -526,6 +526,7 @@ struct compRouteOutputList_t // Prototype of external declaration of functions void print_path (struct compRouteOutputItem_t *); void print_path_t(struct path_t*); +struct path_t* create_path(); void duplicate_string(gchar *, gchar *); @@ -533,7 +534,7 @@ gchar* get_uuid_char(uuid_t); void copy_service_id(struct serviceId_t*, struct serviceId_t *); void copy_service_endpoint_id(struct service_endpoints_id_t *, struct service_endpoints_id_t *); -struct graph_t* get_graph_by_contextId(struct contextSet_t *, gchar *); +struct graph_t* get_graph_by_contextId(GList*, gchar *); struct pred_t * create_predecessors (); struct edges_t* create_edge(); @@ -561,31 +562,29 @@ gint graph_targeted_vertice_add (gint, gchar *, struct graph_t *); void remove_edge_from_graph (struct graph_t *, struct edges_t *); struct path_set_t * create_path_set (); -void sort_path_set (struct path_set_t *); +void sort_path_set (struct path_set_t *, guint); void pop_front_path_set (struct path_set_t *); void remove_path_set(struct path_set_t*); void build_map_node(struct map_nodes_t *, struct graph_t *); struct compRouteOutputList_t * create_route_list(); +void duplicate_route_list(struct compRouteOutputList_t *, struct compRouteOutputList_t *); struct compRouteOutputItem_t * create_path_item (); void add_routeElement_path_back (struct routeElement_t *, struct compRouteOutputItem_t *); gboolean matching_path_rootPath (struct compRouteOutputItem_t *, struct compRouteOutputItem_t *, struct nodes_t *, struct edges_t *); void modify_targeted_graph (struct graph_t *, struct path_set_t *, struct compRouteOutputItem_t *, struct nodes_t *); gint find_nodeId (gconstpointer, gconstpointer); -gint check_link (struct nodeItem_t *, gint, gint, struct graph_t *, struct service_t *, GList **, GList **, struct map_nodes_t *); -gboolean check_computed_path_feasability (struct service_t *, struct compRouteOutputItem_t * ); +gint check_link (struct nodeItem_t *, gint, gint, struct graph_t *, struct service_t *, GList **, GList **, struct map_nodes_t *, guint arg); +gboolean check_computed_path_feasibility (struct service_t *, struct compRouteOutputItem_t * ); gint sort_by_distance (gconstpointer, gconstpointer); +gint sort_by_energy(gconstpointer, gconstpointer); struct graph_t * create_graph (); struct map_nodes_t * create_map_node (); struct service_t * get_service_for_computed_path(gchar *); -struct deviceList_t* create_device_list(); -struct linkList_t* create_link_list(); -struct serviceList_t* create_service_list(); - void print_service_type(guint); void print_link_port_direction(guint); void print_termination_direction(guint); @@ -593,9 +592,9 @@ void print_termination_state(guint); void print_capacity_unit(guint); void print_link_forwarding_direction(guint); -struct contextSet_t* create_contextSet(); -void build_contextSet(struct contextSet_t *); -void print_contextSet(struct contextSet_t *); +void build_contextSet(GList **); +void build_contextSet_active(GList **); +void print_contextSet(GList *); gint same_src_dst_pe_nodeid (struct service_t *); void comp_route_connection_issue_handler (struct compRouteOutput_t *, struct service_t *); @@ -610,4 +609,12 @@ struct timeval tv_adjust(struct timeval); void print_path_connection_list(struct compRouteOutputList_t*); void update_stats_path_comp(struct compRouteOutputList_t*, struct timeval, gint, gint); -#endif \ No newline at end of file +void destroy_active_service(struct activeService_t*); +void destroy_requested_service(struct service_t*); +void destroy_device(struct device_t*); +void destroy_link(struct link_t*); +void destroy_context(struct context_t*); +void dijkstra(gint, gint, struct graph_t*, struct service_t*, struct map_nodes_t*, struct nodes_t*, struct compRouteOutputItem_t*, guint); +void set_path_attributes(struct compRouteOutputItem_t*, struct map_t*); +void alg_comp(struct service_t*, struct compRouteOutput_t*, struct graph_t*, guint); +#endif diff --git a/src/pathcomp/frontend/Config.py b/src/pathcomp/frontend/Config.py index f17a9f5377b5abcbd9001d1d3773e26998cb3211..714eb7278074ac860caa76dc3ed8b4a40ae9f192 100644 --- a/src/pathcomp/frontend/Config.py +++ b/src/pathcomp/frontend/Config.py @@ -26,8 +26,9 @@ PATHCOMP_BACKEND_BASEURL = str(os.environ.get('PATHCOMP_BACKEND_BASEURL', DEFAUL # - first check env vars PATHCOMP_BACKEND_HOST & PATHCOMP_BACKEND_PORT # - if not set, check env vars PATHCOMPSERVICE_SERVICE_HOST & PATHCOMPSERVICE_SERVICE_PORT_HTTP # - if not set, use DEFAULT_PATHCOMP_BACKEND_HOST & DEFAULT_PATHCOMP_BACKEND_PORT + backend_host = DEFAULT_PATHCOMP_BACKEND_HOST -backend_host = os.environ.get('PATHCOMPSERVICE_SERVICE_HOST', backend_host) +#backend_host = os.environ.get('PATHCOMPSERVICE_SERVICE_HOST', backend_host) PATHCOMP_BACKEND_HOST = str(os.environ.get('PATHCOMP_BACKEND_HOST', backend_host)) backend_port = DEFAULT_PATHCOMP_BACKEND_PORT diff --git a/src/pathcomp/frontend/Dockerfile b/src/pathcomp/frontend/Dockerfile index 352de75f31366b65e62e2f6357d1bd5f28bd2b0f..9384b3e19edd5e82b0efcb9706c41105a31321e3 100644 --- a/src/pathcomp/frontend/Dockerfile +++ b/src/pathcomp/frontend/Dockerfile @@ -62,8 +62,14 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow -COPY src/context/. context/ -COPY src/device/. device/ +COPY src/context/__init__.py context/__init__.py +COPY src/context/client/. context/client/ +COPY src/device/__init__.py device/__init__.py +COPY src/device/client/. device/client/ +COPY src/service/__init__.py service/__init__.py +COPY src/service/client/. service/client/ +COPY src/slice/__init__.py slice/__init__.py +COPY src/slice/client/. slice/client/ COPY src/pathcomp/. pathcomp/ # Start the service diff --git a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py index 6fc33dbd45a92405fb2fa115e12cb460a9111d54..52f1cd3d584e14ca5dee1bc5e0511e014bdc8e73 100644 --- a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py +++ b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py @@ -13,9 +13,9 @@ # limitations under the License. import grpc, logging, threading -from common.Constants import DEFAULT_CONTEXT_NAME, INTERDOMAIN_TOPOLOGY_NAME +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method -from common.proto.context_pb2 import ContextId, Empty +from common.proto.context_pb2 import ContextId, Empty, TopologyId from common.proto.pathcomp_pb2 import PathCompReply, PathCompRequest from common.proto.pathcomp_pb2_grpc import PathCompServiceServicer from common.tools.context_queries.Device import get_devices_in_topology @@ -23,6 +23,7 @@ from common.tools.context_queries.Link import get_links_in_topology from common.tools.context_queries.InterDomain import is_inter_domain from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id +from common.tools.object_factory.Topology import json_topology_id from context.client.ContextClient import ContextClient from pathcomp.frontend.service.algorithms.Factory import get_algorithm @@ -30,7 +31,7 @@ LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool('PathComp', 'RPC') -ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) +#ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) class PathCompServiceServicerImpl(PathCompServiceServicer): def __init__(self) -> None: @@ -44,18 +45,23 @@ class PathCompServiceServicerImpl(PathCompServiceServicer): context_client = ContextClient() + context_id = json_context_id(DEFAULT_CONTEXT_NAME) if (len(request.services) == 1) and is_inter_domain(context_client, request.services[0].service_endpoint_ids): - devices = get_devices_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) - links = get_links_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) + #devices = get_devices_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) + #links = get_links_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) + topology_id = json_topology_id(INTERDOMAIN_TOPOLOGY_NAME, context_id) else: # TODO: improve filtering of devices and links # TODO: add contexts, topologies, and membership of devices/links in topologies - devices = context_client.ListDevices(Empty()) - links = context_client.ListLinks(Empty()) + #devices = context_client.ListDevices(Empty()) + #links = context_client.ListLinks(Empty()) + topology_id = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id) + + topology_details = context_client.GetTopologyDetails(TopologyId(**topology_id)) algorithm = get_algorithm(request) - algorithm.add_devices(devices) - algorithm.add_links(links) + algorithm.add_devices(topology_details.devices) + algorithm.add_links(topology_details.links) algorithm.add_service_requests(request) #LOGGER.debug('device_list = {:s}' .format(str(algorithm.device_list ))) diff --git a/src/pathcomp/frontend/service/__main__.py b/src/pathcomp/frontend/service/__main__.py index e3f7d36196be4319cf8364d8569d5289bec2dd89..00da647752e870acc132fc8a96e506ef7327ffa3 100644 --- a/src/pathcomp/frontend/service/__main__.py +++ b/src/pathcomp/frontend/service/__main__.py @@ -53,7 +53,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py index a6d39ee36949e075323613fceb71da5c77354fe5..144246620e85dd1aaf507efe75e22b62ce942587 100644 --- a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py @@ -14,12 +14,10 @@ import operator from typing import Dict, List, Optional, Set, Tuple -from common.proto.context_pb2 import Connection, Link, Service -from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompReply, PathCompRequest +from common.proto.context_pb2 import Link +from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompRequest from common.tools.grpc.Tools import grpc_message_to_json_string -from pathcomp.frontend.service.algorithms.tools.ComputeSubServices import convert_explicit_path_hops_to_connections -from pathcomp.frontend.service.algorithms.tools.EroPathToHops import eropath_to_hops -from ._Algorithm import _Algorithm +from ._Algorithm import _Algorithm, SRC_END from .KShortestPathAlgorithm import KShortestPathAlgorithm Service_Id = Tuple[str, str] # (context_uuid, service_uuid) @@ -100,7 +98,7 @@ class KDisjointPathAlgorithm(_Algorithm): def get_link_from_endpoint(self, endpoint : Dict) -> Tuple[Dict, Link]: device_uuid = endpoint['device_id'] endpoint_uuid = endpoint['endpoint_uuid'] - item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid)) + item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid, SRC_END)) if item is None: MSG = 'Link for Endpoint({:s}, {:s}) not found' self.logger.warning(MSG.format(device_uuid, endpoint_uuid)) @@ -141,7 +139,7 @@ class KDisjointPathAlgorithm(_Algorithm): Path = List[Dict] Path_NoPath = Optional[Path] # None = no path, list = path - self.json_reply : Dict[Tuple[str, str], List[Path_NoPath]] = dict() + service_to_paths : Dict[Tuple[str, str], List[Path_NoPath]] = dict() for num_path in range(self.num_disjoint): algorithm.service_list = list() @@ -189,66 +187,25 @@ class KDisjointPathAlgorithm(_Algorithm): for response in response_list: service_id = response['serviceId'] service_key = (service_id['contextId'], service_id['service_uuid']) - json_reply_service = self.json_reply.setdefault(service_key, list()) + json_reply_service = service_to_paths.setdefault(service_key, list()) no_path_issue = response.get('noPath', {}).get('issue') - if no_path_issue is not None: - json_reply_service.append(None) - continue + if no_path_issue is not None: continue - path_endpoints = response['path'][0]['devices'] + path_endpoints = response['path'][0] json_reply_service.append(path_endpoints) - algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints) + algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints['devices']) + + self.json_reply = dict() + response_list = self.json_reply.setdefault('response-list', []) + for service_key,paths in service_to_paths.items(): + response = {'serviceId': { + 'contextId': service_key[0], + 'service_uuid': service_key[1], + }} + response['path'] = paths + if len(paths) < self.num_disjoint: + response['noPath'] = {'issue': 1} + response_list.append(response) self.logger.debug('self.json_reply = {:s}'.format(str(self.json_reply))) - - def get_reply(self) -> PathCompReply: - reply = PathCompReply() - grpc_services : Dict[Tuple[str, str], Service] = {} - grpc_connections : Dict[Tuple[int, str], Connection] = {} - for service_key,paths in self.json_reply.items(): - context_uuid, service_uuid = service_key - - grpc_services[service_key] = self.add_service_to_reply(reply, context_uuid, service_uuid) - - for num_path,service_path_ero in enumerate(paths): - self.logger.warning('num_path={:d}'.format(num_path)) - self.logger.warning('service_path_ero={:s}'.format(str(service_path_ero))) - if service_path_ero is None: continue - path_hops = eropath_to_hops(service_path_ero, self.endpoint_to_link_dict) - self.logger.warning('path_hops={:s}'.format(str(path_hops))) - connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid) - self.logger.warning('connections={:s}'.format(str(connections))) - - for connection in connections: - connection_uuid,device_layer,path_hops,_ = connection - - service_key = (context_uuid, connection_uuid) - grpc_service = grpc_services.get(service_key) - if grpc_service is not None: continue - grpc_service = self.add_service_to_reply( - reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops) - grpc_services[service_key] = grpc_service - - for connection in connections: - connection_uuid,device_layer,path_hops,dependencies = connection - - service_key = (context_uuid, connection_uuid) - grpc_service = grpc_services.get(service_key) - if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key))) - - connection_uuid = '{:s}:{:d}'.format(connection_uuid, num_path) - grpc_connection = grpc_connections.get(connection_uuid) - if grpc_connection is not None: continue - grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops) - grpc_connections[connection_uuid] = grpc_connection - - for sub_service_uuid in dependencies: - sub_service_key = (context_uuid, sub_service_uuid) - grpc_sub_service = grpc_services.get(sub_service_key) - if grpc_sub_service is None: - raise Exception('Service({:s}) not found'.format(str(sub_service_key))) - grpc_sub_service_id = grpc_connection.sub_service_ids.add() - grpc_sub_service_id.CopyFrom(grpc_sub_service.service_id) - - return reply diff --git a/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py index 920d72e828f6f84bc064f1c7357105907ffdac4c..e0fbbe08a1c01402573333f89b1118b6618cc7ce 100644 --- a/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py @@ -26,4 +26,5 @@ class KShortestPathAlgorithm(_Algorithm): for service_request in self.service_list: service_request['algId' ] = self.algorithm_id service_request['syncPaths'] = self.sync_paths - service_request['kPaths' ] = self.k_return + service_request['kPaths_inspection'] = self.k_inspection + service_request['kPaths_return' ] = self.k_return diff --git a/src/pathcomp/frontend/service/algorithms/_Algorithm.py b/src/pathcomp/frontend/service/algorithms/_Algorithm.py index b6316774921171eb8ed6cf3faafd4b607bdcb831..0eb01c1341421e379850f89d5671d9156c8a9fd6 100644 --- a/src/pathcomp/frontend/service/algorithms/_Algorithm.py +++ b/src/pathcomp/frontend/service/algorithms/_Algorithm.py @@ -15,17 +15,20 @@ import json, logging, requests from typing import Dict, List, Optional, Tuple, Union from common.proto.context_pb2 import ( - ConfigRule, Connection, Device, DeviceList, EndPointId, Link, LinkList, Service, ServiceStatusEnum, - ServiceTypeEnum) + Connection, Device, DeviceList, EndPointId, Link, LinkList, Service, ServiceStatusEnum, ServiceTypeEnum) from common.proto.pathcomp_pb2 import PathCompReply, PathCompRequest -from common.tools.object_factory.ConfigRule import json_config_rule_set from pathcomp.frontend.Config import BACKEND_URL -from pathcomp.frontend.service.algorithms.tools.ConstantsMappings import DEVICE_LAYER_TO_SERVICE_TYPE, DeviceLayerEnum from .tools.EroPathToHops import eropath_to_hops +from .tools.ComposeConfigRules import ( + compose_device_config_rules, compose_l2nm_config_rules, compose_l3nm_config_rules, compose_tapi_config_rules) from .tools.ComposeRequest import compose_device, compose_link, compose_service from .tools.ComputeSubServices import ( convert_explicit_path_hops_to_connections, convert_explicit_path_hops_to_plain_connection) +SRC_END = 'src' +DST_END = 'dst' +SENSE = [SRC_END, DST_END] + class _Algorithm: def __init__(self, algorithm_id : str, sync_paths : bool, class_name=__name__) -> None: # algorithm_id: algorithm to be executed @@ -45,7 +48,7 @@ class _Algorithm: self.endpoint_name_mapping : Dict[Tuple[str, str], str] = dict() self.link_list : List[Dict] = list() self.link_dict : Dict[str, Tuple[Dict, Link]] = dict() - self.endpoint_to_link_dict : Dict[Tuple[str, str], Tuple[Dict, Link]] = dict() + self.endpoint_to_link_dict : Dict[Tuple[str, str, str], Tuple[Dict, Link]] = dict() self.service_list : List[Dict] = list() self.service_dict : Dict[Tuple[str, str], Tuple[Dict, Service]] = dict() @@ -61,6 +64,7 @@ class _Algorithm: _device_uuid = grpc_device.device_id.device_uuid.uuid _device_name = grpc_device.name self.device_name_mapping[_device_name] = _device_uuid + self.device_name_mapping[_device_uuid] = _device_uuid device_endpoint_dict : Dict[str, Tuple[Dict, EndPointId]] = dict() for json_endpoint,grpc_endpoint in zip(json_device['device_endpoints'], grpc_device.device_endpoints): @@ -72,12 +76,16 @@ class _Algorithm: _endpoint_name = grpc_endpoint.name self.endpoint_name_mapping[(_device_uuid, _endpoint_name)] = _endpoint_uuid self.endpoint_name_mapping[(_device_name, _endpoint_name)] = _endpoint_uuid + self.endpoint_name_mapping[(_device_uuid, _endpoint_uuid)] = _endpoint_uuid + self.endpoint_name_mapping[(_device_name, _endpoint_uuid)] = _endpoint_uuid self.endpoint_dict[device_uuid] = device_endpoint_dict def add_links(self, grpc_links : Union[List[Link], LinkList]) -> None: if isinstance(grpc_links, LinkList): grpc_links = grpc_links.links for grpc_link in grpc_links: + if 'mgmt' in grpc_link.name.lower(): continue + json_link = compose_link(grpc_link) if len(json_link['link_endpoint_ids']) != 2: continue self.link_list.append(json_link) @@ -85,11 +93,11 @@ class _Algorithm: link_uuid = json_link['link_Id'] self.link_dict[link_uuid] = (json_link, grpc_link) - for link_endpoint_id in json_link['link_endpoint_ids']: + for i,link_endpoint_id in enumerate(json_link['link_endpoint_ids']): link_endpoint_id = link_endpoint_id['endpoint_id'] device_uuid = link_endpoint_id['device_id'] endpoint_uuid = link_endpoint_id['endpoint_uuid'] - endpoint_key = (device_uuid, endpoint_uuid) + endpoint_key = (device_uuid, endpoint_uuid, SENSE[i]) link_tuple = (json_link, grpc_link) self.endpoint_to_link_dict[endpoint_key] = link_tuple @@ -148,9 +156,8 @@ class _Algorithm: return connection def add_service_to_reply( - self, reply : PathCompReply, context_uuid : str, service_uuid : str, - device_layer : Optional[DeviceLayerEnum] = None, path_hops : List[Dict] = [], - config_rules : List = [] + self, reply : PathCompReply, context_uuid : str, service_uuid : str, service_type : ServiceTypeEnum, + path_hops : List[Dict] = [], config_rules : List = [] ) -> Service: # TODO: implement support for multi-point services # Control deactivated to enable disjoint paths with multiple redundant endpoints on each side @@ -159,44 +166,43 @@ class _Algorithm: service_key = (context_uuid, service_uuid) tuple_service = self.service_dict.get(service_key) - if tuple_service is not None: - service = reply.services.add() - service.CopyFrom(tuple_service[1]) + + service = reply.services.add() + service.service_id.context_id.context_uuid.uuid = context_uuid + service.service_id.service_uuid.uuid = service_uuid + service.service_type = service_type + + if service_type == ServiceTypeEnum.SERVICETYPE_L2NM: + compose_l2nm_config_rules(config_rules, service.service_config.config_rules) + elif service_type == ServiceTypeEnum.SERVICETYPE_L3NM: + compose_l3nm_config_rules(config_rules, service.service_config.config_rules) + elif service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: + compose_tapi_config_rules(config_rules, service.service_config.config_rules) else: - service = reply.services.add() - service.service_id.context_id.context_uuid.uuid = context_uuid - service.service_id.service_uuid.uuid = service_uuid - - if device_layer is not None: - service_type = DEVICE_LAYER_TO_SERVICE_TYPE.get(device_layer.value) - if service_type is None: - MSG = 'Unable to map DeviceLayer({:s}) to ServiceType' - raise Exception(MSG.format(str(device_layer))) - service.service_type = service_type - - if service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: - json_tapi_settings = { - 'capacity_value' : 50.0, - 'capacity_unit' : 'GHz', - 'layer_proto_name': 'PHOTONIC_MEDIA', - 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', - 'direction' : 'UNIDIRECTIONAL', - } - config_rule = ConfigRule(**json_config_rule_set('/settings', json_tapi_settings)) - service.service_config.config_rules.append(config_rule) - else: - service.service_config.config_rules.extend(config_rules) + MSG = 'Unhandled generic Config Rules for service {:s} {:s}' + self.logger.warning(MSG.format(str(service_uuid), str(ServiceTypeEnum.Name(service_type)))) - service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED + compose_device_config_rules( + config_rules, service.service_config.config_rules, path_hops, + self.device_name_mapping, self.endpoint_name_mapping) - if path_hops is not None and len(path_hops) > 0: - ingress_endpoint_id = service.service_endpoint_ids.add() - ingress_endpoint_id.device_id.device_uuid.uuid = path_hops[0]['device'] - ingress_endpoint_id.endpoint_uuid.uuid = path_hops[0]['ingress_ep'] + if path_hops is not None and len(path_hops) > 0: + ingress_endpoint_id = service.service_endpoint_ids.add() + ingress_endpoint_id.device_id.device_uuid.uuid = path_hops[0]['device'] + ingress_endpoint_id.endpoint_uuid.uuid = path_hops[0]['ingress_ep'] - egress_endpoint_id = service.service_endpoint_ids.add() - egress_endpoint_id.device_id.device_uuid.uuid = path_hops[-1]['device'] - egress_endpoint_id.endpoint_uuid.uuid = path_hops[-1]['egress_ep'] + egress_endpoint_id = service.service_endpoint_ids.add() + egress_endpoint_id.device_id.device_uuid.uuid = path_hops[-1]['device'] + egress_endpoint_id.endpoint_uuid.uuid = path_hops[-1]['egress_ep'] + + if tuple_service is None: + service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED + else: + service.name = tuple_service[1].name + service.service_status.CopyFrom(tuple_service[1].service_status) + service.timestamp.CopyFrom(tuple_service[1].timestamp) + for constraint in tuple_service[1].service_constraints: + service.service_constraints.add().CopyFrom(constraint) return service @@ -206,53 +212,66 @@ class _Algorithm: grpc_services : Dict[Tuple[str, str], Service] = {} grpc_connections : Dict[str, Connection] = {} for response in response_list: - service_id = response['serviceId'] - context_uuid = service_id['contextId'] - service_uuid = service_id['service_uuid'] - service_key = (context_uuid, service_uuid) - upper_service = self.add_service_to_reply(reply, context_uuid, service_uuid) - grpc_services[service_key] = upper_service + orig_service_id = response['serviceId'] + context_uuid = orig_service_id['contextId'] + main_service_uuid = orig_service_id['service_uuid'] + orig_service_key = (context_uuid, main_service_uuid) + _,grpc_orig_service = self.service_dict[orig_service_key] + main_service_type = grpc_orig_service.service_type no_path_issue = response.get('noPath', {}).get('issue') if no_path_issue is not None: # no path found: leave connection with no endpoints # no_path_issue == 1 => no path due to a constraint + grpc_services[orig_service_key] = grpc_orig_service continue + orig_config_rules = grpc_orig_service.service_config.config_rules + for service_path_ero in response['path']: + self.logger.debug('service_path_ero["devices"] = {:s}'.format(str(service_path_ero['devices']))) + _endpoint_to_link_dict = {k:v[0] for k,v in self.endpoint_to_link_dict.items()} + self.logger.debug('self.endpoint_to_link_dict = {:s}'.format(str(_endpoint_to_link_dict))) path_hops = eropath_to_hops(service_path_ero['devices'], self.endpoint_to_link_dict) + self.logger.debug('path_hops = {:s}'.format(str(path_hops))) try: - connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid) + _device_dict = {k:v[0] for k,v in self.device_dict.items()} + self.logger.debug('self.device_dict = {:s}'.format(str(_device_dict))) + connections = convert_explicit_path_hops_to_connections( + path_hops, self.device_dict, main_service_uuid, main_service_type) + self.logger.debug('EXTRAPOLATED connections = {:s}'.format(str(connections))) except: # pylint: disable=bare-except - # if not able to extrapolate sub-services and sub-connections, - # assume single service and single connection - connections = convert_explicit_path_hops_to_plain_connection(path_hops, service_uuid) + MSG = ' '.join([ + 'Unable to Extrapolate sub-services and sub-connections.', + 'Assuming single-service and single-connection.', + ]) + self.logger.exception(MSG) + connections = convert_explicit_path_hops_to_plain_connection( + path_hops, main_service_uuid, main_service_type) + self.logger.debug('BASIC connections = {:s}'.format(str(connections))) for connection in connections: - connection_uuid,device_layer,path_hops,_ = connection + connection_uuid,service_type,path_hops,_ = connection service_key = (context_uuid, connection_uuid) - grpc_service = grpc_services.get(service_key) - if grpc_service is None: - config_rules = upper_service.service_config.config_rules - grpc_service = self.add_service_to_reply( - reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops, - config_rules=config_rules) - grpc_services[service_key] = grpc_service + if service_key in grpc_services: continue + grpc_service = self.add_service_to_reply( + reply, context_uuid, connection_uuid, service_type, path_hops=path_hops, + config_rules=orig_config_rules) + grpc_services[service_key] = grpc_service for connection in connections: - connection_uuid,device_layer,path_hops,dependencies = connection + connection_uuid,_,path_hops,dependencies = connection service_key = (context_uuid, connection_uuid) grpc_service = grpc_services.get(service_key) if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key))) - grpc_connection = grpc_connections.get(connection_uuid) - if grpc_connection is not None: continue + #if connection_uuid in grpc_connections: continue grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops) - grpc_connections[connection_uuid] = grpc_connection + #grpc_connections[connection_uuid] = grpc_connection - for service_uuid in dependencies: - sub_service_key = (context_uuid, service_uuid) + for sub_service_uuid in dependencies: + sub_service_key = (context_uuid, sub_service_uuid) grpc_sub_service = grpc_services.get(sub_service_key) if grpc_sub_service is None: raise Exception('Service({:s}) not found'.format(str(sub_service_key))) @@ -262,11 +281,11 @@ class _Algorithm: # ... "path-capacity": {"total-size": {"value": 200, "unit": 0}}, # ... "path-latency": {"fixed-latency-characteristic": "10.000000"}, # ... "path-cost": {"cost-name": "", "cost-value": "5.000000", "cost-algorithm": "0.000000"}, - #path_capacity = service_path['path-capacity']['total-size'] + #path_capacity = service_path_ero['path-capacity']['total-size'] #path_capacity_value = path_capacity['value'] #path_capacity_unit = CapacityUnit(path_capacity['unit']) - #path_latency = service_path['path-latency']['fixed-latency-characteristic'] - #path_cost = service_path['path-cost'] + #path_latency = service_path_ero['path-latency']['fixed-latency-characteristic'] + #path_cost = service_path_ero['path-cost'] #path_cost_name = path_cost['cost-name'] #path_cost_value = path_cost['cost-value'] #path_cost_algorithm = path_cost['cost-algorithm'] diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py new file mode 100644 index 0000000000000000000000000000000000000000..91367e23f29a02aa3e9605fcd0d2864b9191d800 --- /dev/null +++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeConfigRules.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 itertools, json, re +from typing import Dict, List, Optional, Tuple +from common.proto.context_pb2 import ConfigRule +from common.tools.object_factory.ConfigRule import json_config_rule_set + +SETTINGS_RULE_NAME = '/settings' + +DEV_EP_SETTINGS = re.compile(r'\/device\[([^\]]+)\]\/endpoint\[([^\]]+)\]\/settings') + +L2NM_SETTINGS_FIELD_DEFAULTS = { + 'encapsulation_type': 'dot1q', + 'vlan_id' : 100, + 'mtu' : 1450, +} + +L3NM_SETTINGS_FIELD_DEFAULTS = { + 'encapsulation_type': 'dot1q', + 'vlan_id' : 100, + 'mtu' : 1450, +} + +TAPI_SETTINGS_FIELD_DEFAULTS = { + 'capacity_value' : 50.0, + 'capacity_unit' : 'GHz', + 'layer_proto_name': 'PHOTONIC_MEDIA', + 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', + 'direction' : 'UNIDIRECTIONAL', +} + +def find_custom_config_rule(config_rules : List, resource_name : str) -> Optional[Dict]: + resource_value : Optional[Dict] = None + for config_rule in config_rules: + if config_rule.WhichOneof('config_rule') != 'custom': continue + if config_rule.custom.resource_key != resource_name: continue + resource_value = json.loads(config_rule.custom.resource_value) + return resource_value + +def compose_config_rules( + main_service_config_rules : List, subservice_config_rules : List, field_defaults : Dict +) -> None: + settings = find_custom_config_rule(main_service_config_rules, SETTINGS_RULE_NAME) + if settings is None: return + + json_settings = {} + for field_name,default_value in field_defaults.items(): + json_settings[field_name] = settings.get(field_name, default_value) + + config_rule = ConfigRule(**json_config_rule_set('/settings', json_settings)) + subservice_config_rules.append(config_rule) + +def compose_l2nm_config_rules(main_service_config_rules : List, subservice_config_rules : List) -> None: + compose_config_rules(main_service_config_rules, subservice_config_rules, L2NM_SETTINGS_FIELD_DEFAULTS) + +def compose_l3nm_config_rules(main_service_config_rules : List, subservice_config_rules : List) -> None: + compose_config_rules(main_service_config_rules, subservice_config_rules, L3NM_SETTINGS_FIELD_DEFAULTS) + +def compose_tapi_config_rules(main_service_config_rules : List, subservice_config_rules : List) -> None: + compose_config_rules(main_service_config_rules, subservice_config_rules, TAPI_SETTINGS_FIELD_DEFAULTS) + +def compose_device_config_rules( + config_rules : List, subservice_config_rules : List, path_hops : List, + device_name_mapping : Dict[str, str], endpoint_name_mapping : Dict[Tuple[str, str], str] +) -> None: + + endpoints_traversed = set() + for path_hop in path_hops: + device_uuid_or_name = path_hop['device'] + endpoints_traversed.add((device_uuid_or_name, path_hop['ingress_ep'])) + endpoints_traversed.add((device_uuid_or_name, path_hop['egress_ep'])) + + for config_rule in config_rules: + if config_rule.WhichOneof('config_rule') != 'custom': continue + match = DEV_EP_SETTINGS.match(config_rule.custom.resource_key) + if match is None: continue + + device_uuid_or_name = match.group(1) + device_name_or_uuid = device_name_mapping[device_uuid_or_name] + device_keys = {device_uuid_or_name, device_name_or_uuid} + + endpoint_uuid_or_name = match.group(2) + endpoint_name_or_uuid_1 = endpoint_name_mapping[(device_uuid_or_name, endpoint_uuid_or_name)] + endpoint_name_or_uuid_2 = endpoint_name_mapping[(device_name_or_uuid, endpoint_uuid_or_name)] + endpoint_keys = {endpoint_uuid_or_name, endpoint_name_or_uuid_1, endpoint_name_or_uuid_2} + + device_endpoint_keys = set(itertools.product(device_keys, endpoint_keys)) + if len(device_endpoint_keys.intersection(endpoints_traversed)) == 0: continue + subservice_config_rules.append(config_rule) diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py index ee85f0bb083500c655e78798bbcd2bd00e8a4501..e2c6dc13804703d89242b27156763ce887aa4884 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py @@ -118,11 +118,11 @@ def compose_link(grpc_link : Link) -> Dict: for link_endpoint_id in grpc_link.link_endpoint_ids ] - forwarding_direction = LinkForwardingDirection.BIDIRECTIONAL.value + forwarding_direction = LinkForwardingDirection.UNIDIRECTIONAL.value total_potential_capacity = compose_capacity(200, CapacityUnit.MBPS.value) available_capacity = compose_capacity(200, CapacityUnit.MBPS.value) cost_characteristics = compose_cost_characteristics('linkcost', '1', '0') - latency_characteristics = compose_latency_characteristics('2') + latency_characteristics = compose_latency_characteristics('1') return { 'link_Id': link_uuid, 'link_endpoint_ids': endpoint_ids, 'forwarding_direction': forwarding_direction, diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py b/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py index b92a19b52c4887e01f7f1bc58de897c783683eeb..8ffdfaf3ed9d35b52e9c262a980e6e8e8fd234af 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py @@ -30,56 +30,89 @@ # ] # # connections=[ -# (UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e'), , [ +# (UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e'), ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, [ # {'device': 'TN-OLS', 'ingress_ep': '833760219d0f', 'egress_ep': 'cf176771a4b9'} # ], []), -# (UUID('c2e57966-5d82-4705-a5fe-44cf6487219e'), , [ +# (UUID('c2e57966-5d82-4705-a5fe-44cf6487219e'), ServiceTypeEnum.SERVICETYPE_L2NM, [ # {'device': 'CS1-GW1', 'ingress_ep': '10/1', 'egress_ep': '1/2'}, # {'device': 'TN-R2', 'ingress_ep': '1/2', 'egress_ep': '2/1'}, # {'device': 'TN-R3', 'ingress_ep': '2/1', 'egress_ep': '1/1'}, # {'device': 'CS2-GW1', 'ingress_ep': '1/1', 'egress_ep': '10/1'} # ], [UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e')]), -# (UUID('1e205c82-f6ea-4977-9e97-dc27ef1f4802'), , [ +# (UUID('1e205c82-f6ea-4977-9e97-dc27ef1f4802'), ServiceTypeEnum.SERVICETYPE_L2NM, [ # {'device': 'DC1-GW', 'ingress_ep': 'int', 'egress_ep': 'eth1'}, # {'device': 'DC2-GW', 'ingress_ep': 'eth1', 'egress_ep': 'int'} # ], [UUID('c2e57966-5d82-4705-a5fe-44cf6487219e')]) # ] -import queue, uuid -from typing import Dict, List, Tuple -from common.proto.context_pb2 import Device -from .ConstantsMappings import DEVICE_TYPE_TO_LAYER, DeviceLayerEnum +import logging, queue, uuid +from typing import Dict, List, Optional, Tuple +from common.DeviceTypes import DeviceTypeEnum +from common.proto.context_pb2 import Device, ServiceTypeEnum +from .ResourceGroups import IGNORED_DEVICE_TYPES, get_resource_classification +from .ServiceTypes import get_service_type + +LOGGER = logging.getLogger(__name__) def convert_explicit_path_hops_to_connections( - path_hops : List[Dict], device_dict : Dict[str, Tuple[Dict, Device]], main_connection_uuid : str -) -> List[Tuple[str, DeviceLayerEnum, List[str], List[str]]]: + path_hops : List[Dict], device_dict : Dict[str, Tuple[Dict, Device]], + main_service_uuid : str, main_service_type : ServiceTypeEnum +) -> List[Tuple[str, int, List[str], List[str]]]: + + LOGGER.debug('path_hops={:s}'.format(str(path_hops))) connection_stack = queue.LifoQueue() - connections : List[Tuple[str, DeviceLayerEnum, List[str], List[str]]] = list() - old_device_layer = None - last_device_uuid = None + connections : List[Tuple[str, int, List[str], List[str]]] = list() + prv_device_uuid = None + prv_res_class : Tuple[Optional[int], Optional[DeviceTypeEnum], Optional[str]] = None, None, None + for path_hop in path_hops: + LOGGER.debug('path_hop={:s}'.format(str(path_hop))) device_uuid = path_hop['device'] - if last_device_uuid == device_uuid: continue + if prv_device_uuid == device_uuid: continue device_tuple = device_dict.get(device_uuid) if device_tuple is None: raise Exception('Device({:s}) not found'.format(str(device_uuid))) - json_device,_ = device_tuple - device_type = json_device['device_type'] - device_layer = DEVICE_TYPE_TO_LAYER.get(device_type) - if device_layer is None: raise Exception('Undefined Layer for DeviceType({:s})'.format(str(device_type))) + _,grpc_device = device_tuple - if old_device_layer is None: + res_class = get_resource_classification(grpc_device, device_dict) + LOGGER.debug(' prv_res_class={:s}'.format(str(prv_res_class))) + LOGGER.debug(' res_class={:s}'.format(str(res_class))) + if res_class[1] in IGNORED_DEVICE_TYPES: + LOGGER.debug(' ignored') + continue + + if prv_res_class[0] is None: # path ingress - connection_stack.put((main_connection_uuid, device_layer, [path_hop], [])) - elif old_device_layer > device_layer: - # underlying connection begins + LOGGER.debug(' path ingress') + connection_stack.put((main_service_uuid, main_service_type, [path_hop], [])) + elif prv_res_class[0] > res_class[0]: + # create underlying connection + LOGGER.debug(' create underlying connection') connection_uuid = str(uuid.uuid4()) - connection_stack.put((connection_uuid, device_layer, [path_hop], [])) - elif old_device_layer == device_layer: - # same connection continues - connection_stack.queue[-1][2].append(path_hop) - elif old_device_layer < device_layer: + prv_service_type = connection_stack.queue[-1][1] + service_type = get_service_type(res_class[1], prv_service_type) + connection_stack.put((connection_uuid, service_type, [path_hop], [])) + elif prv_res_class[0] == res_class[0]: + # same resource group kind + LOGGER.debug(' same resource group kind') + if prv_res_class[1] == res_class[1] and prv_res_class[2] == res_class[2]: + # same device type and device controller: connection continues + LOGGER.debug(' connection continues') + connection_stack.queue[-1][2].append(path_hop) + else: + # different device type or device controller: chain connections + LOGGER.debug(' chain connections') + connection = connection_stack.get() + connections.append(connection) + connection_stack.queue[-1][3].append(connection[0]) + + connection_uuid = str(uuid.uuid4()) + prv_service_type = connection_stack.queue[-1][1] + service_type = get_service_type(res_class[1], prv_service_type) + connection_stack.put((connection_uuid, service_type, [path_hop], [])) + elif prv_res_class[0] < res_class[0]: # underlying connection ended + LOGGER.debug(' underlying connection ended') connection = connection_stack.get() connections.append(connection) connection_stack.queue[-1][3].append(connection[0]) @@ -87,26 +120,28 @@ def convert_explicit_path_hops_to_connections( else: raise Exception('Uncontrolled condition') - old_device_layer = device_layer - last_device_uuid = device_uuid + prv_device_uuid = device_uuid + prv_res_class = res_class # path egress + LOGGER.debug(' path egress') connections.append(connection_stack.get()) + LOGGER.debug('connections={:s}'.format(str(connections))) assert connection_stack.empty() return connections def convert_explicit_path_hops_to_plain_connection( - path_hops : List[Dict], main_connection_uuid : str -) -> List[Tuple[str, DeviceLayerEnum, List[str], List[str]]]: + path_hops : List[Dict], main_service_uuid : str, main_service_type : ServiceTypeEnum +) -> List[Tuple[str, int, List[str], List[str]]]: - connection : Tuple[str, DeviceLayerEnum, List[str], List[str]] = \ - (main_connection_uuid, DeviceLayerEnum.PACKET_DEVICE, [], []) + connection : Tuple[str, int, List[str], List[str]] = \ + (main_service_uuid, main_service_type, [], []) - last_device_uuid = None + prv_device_uuid = None for path_hop in path_hops: device_uuid = path_hop['device'] - if last_device_uuid == device_uuid: continue + if prv_device_uuid == device_uuid: continue connection[2].append(path_hop) - last_device_uuid = device_uuid + prv_device_uuid = device_uuid return [connection] diff --git a/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py b/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py index cd1956a873dd2170c7a75db0c677db34162449ee..bd06e6ba19b3da9e2d38d5b83e1d7d3a806ff14f 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py @@ -13,8 +13,6 @@ # limitations under the License. from enum import IntEnum -from common.DeviceTypes import DeviceTypeEnum -from common.proto.context_pb2 import ServiceTypeEnum class CapacityUnit(IntEnum): TB = 0 @@ -66,50 +64,3 @@ class LinkForwardingDirection(IntEnum): BIDIRECTIONAL = 0 UNIDIRECTIONAL = 1 UNKNOWN = 2 - -class DeviceLayerEnum(IntEnum): - APPLICATION_CONTROLLER = 41 # Layer 4 domain controller - APPLICATION_DEVICE = 40 # Layer 4 domain device - PACKET_CONTROLLER = 31 # Layer 3 domain controller - PACKET_DEVICE = 30 # Layer 3 domain device - MAC_LAYER_CONTROLLER = 21 # Layer 2 domain controller - MAC_LAYER_DEVICE = 20 # Layer 2 domain device - OPTICAL_CONTROLLER = 1 # Layer 0 domain controller - OPTICAL_DEVICE = 0 # Layer 0 domain device - -DEVICE_TYPE_TO_LAYER = { - DeviceTypeEnum.EMULATED_DATACENTER.value : DeviceLayerEnum.APPLICATION_DEVICE, - DeviceTypeEnum.DATACENTER.value : DeviceLayerEnum.APPLICATION_DEVICE, - DeviceTypeEnum.NETWORK.value : DeviceLayerEnum.APPLICATION_DEVICE, - - DeviceTypeEnum.EMULATED_PACKET_ROUTER.value : DeviceLayerEnum.PACKET_DEVICE, - DeviceTypeEnum.PACKET_ROUTER.value : DeviceLayerEnum.PACKET_DEVICE, - DeviceTypeEnum.EMULATED_PACKET_SWITCH.value : DeviceLayerEnum.MAC_LAYER_DEVICE, - DeviceTypeEnum.PACKET_SWITCH.value : DeviceLayerEnum.MAC_LAYER_DEVICE, - - DeviceTypeEnum.EMULATED_P4_SWITCH.value : DeviceLayerEnum.MAC_LAYER_DEVICE, - DeviceTypeEnum.P4_SWITCH.value : DeviceLayerEnum.MAC_LAYER_DEVICE, - - DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM.value : DeviceLayerEnum.MAC_LAYER_CONTROLLER, - DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM.value : DeviceLayerEnum.MAC_LAYER_CONTROLLER, - - DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value : DeviceLayerEnum.OPTICAL_CONTROLLER, - DeviceTypeEnum.OPEN_LINE_SYSTEM.value : DeviceLayerEnum.OPTICAL_CONTROLLER, - DeviceTypeEnum.XR_CONSTELLATION.value : DeviceLayerEnum.OPTICAL_CONTROLLER, - - DeviceTypeEnum.EMULATED_OPTICAL_ROADM.value : DeviceLayerEnum.OPTICAL_DEVICE, - DeviceTypeEnum.OPTICAL_ROADM.value : DeviceLayerEnum.OPTICAL_DEVICE, - DeviceTypeEnum.EMULATED_OPTICAL_TRANSPONDER.value : DeviceLayerEnum.OPTICAL_DEVICE, - DeviceTypeEnum.OPTICAL_TRANSPONDER.value : DeviceLayerEnum.OPTICAL_DEVICE, -} - -DEVICE_LAYER_TO_SERVICE_TYPE = { - DeviceLayerEnum.APPLICATION_DEVICE.value : ServiceTypeEnum.SERVICETYPE_L3NM, - DeviceLayerEnum.PACKET_DEVICE.value : ServiceTypeEnum.SERVICETYPE_L3NM, - - DeviceLayerEnum.MAC_LAYER_CONTROLLER.value : ServiceTypeEnum.SERVICETYPE_L2NM, - DeviceLayerEnum.MAC_LAYER_DEVICE.value : ServiceTypeEnum.SERVICETYPE_L2NM, - - DeviceLayerEnum.OPTICAL_CONTROLLER.value : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, - DeviceLayerEnum.OPTICAL_DEVICE.value : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, -} diff --git a/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py b/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py index c8a902999ddfb5011fd7ec09fa99ff6fa697ea40..670757d76b7d21ecf28f6ead4e8bc4e21951d18e 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py +++ b/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py @@ -43,13 +43,17 @@ # import logging -from typing import Dict, List +from typing import Dict, List, Tuple +from common.proto.context_pb2 import Link LOGGER = logging.getLogger(__name__) -def eropath_to_hops(ero_path : List[Dict], endpoint_to_link_dict : Dict) -> List[Dict]: +def eropath_to_hops( + ero_path : List[Dict], endpoint_to_link_dict : Dict[Tuple[str, str, str], Tuple[Dict, Link]] +) -> List[Dict]: try: path_hops = [] + num_ero_hops = len(ero_path) for endpoint in ero_path: device_uuid = endpoint['device_id'] endpoint_uuid = endpoint['endpoint_uuid'] @@ -59,23 +63,17 @@ def eropath_to_hops(ero_path : List[Dict], endpoint_to_link_dict : Dict) -> List continue last_hop = path_hops[-1] - if (last_hop['device'] == device_uuid): - if ('ingress_ep' not in last_hop) or ('egress_ep' in last_hop): continue - last_hop['egress_ep'] = endpoint_uuid - continue + if last_hop['device'] != device_uuid: raise Exception('Malformed path') + last_hop['egress_ep'] = endpoint_uuid + + if num_ero_hops - 1 == len(path_hops): break - endpoint_key = (last_hop['device'], last_hop['egress_ep']) - link_tuple = endpoint_to_link_dict.get(endpoint_key) - ingress = next(iter([ - ep_id for ep_id in link_tuple[0]['link_endpoint_ids'] - if (ep_id['endpoint_id']['device_id'] == device_uuid) and\ - (ep_id['endpoint_id']['endpoint_uuid'] != endpoint_uuid) - ]), None) - if ingress['endpoint_id']['device_id'] != device_uuid: raise Exception('Malformed path') + link_tuple = endpoint_to_link_dict[(device_uuid, endpoint_uuid, 'src')] + if link_tuple is None: raise Exception('Malformed path') + ingress = link_tuple[0]['link_endpoint_ids'][-1] path_hops.append({ 'device': ingress['endpoint_id']['device_id'], - 'ingress_ep': ingress['endpoint_id']['endpoint_uuid'], - 'egress_ep': endpoint_uuid, + 'ingress_ep': ingress['endpoint_id']['endpoint_uuid'] }) return path_hops except: diff --git a/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py b/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py new file mode 100644 index 0000000000000000000000000000000000000000..c1591dbeb7c71c950135b92446849569bcd781f8 --- /dev/null +++ b/src/pathcomp/frontend/service/algorithms/tools/ResourceGroups.py @@ -0,0 +1,96 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json +from typing import Dict, Optional, Tuple +from common.DeviceTypes import DeviceTypeEnum +from common.proto.context_pb2 import Device +from common.tools.grpc.Tools import grpc_message_to_json_string + +DEVICE_TYPE_TO_DEEPNESS = { + DeviceTypeEnum.EMULATED_DATACENTER.value : 90, + DeviceTypeEnum.DATACENTER.value : 90, + DeviceTypeEnum.NETWORK.value : 90, + + DeviceTypeEnum.TERAFLOWSDN_CONTROLLER.value : 80, + DeviceTypeEnum.EMULATED_PACKET_ROUTER.value : 70, + DeviceTypeEnum.PACKET_ROUTER.value : 70, + + DeviceTypeEnum.EMULATED_PACKET_SWITCH.value : 60, + DeviceTypeEnum.PACKET_SWITCH.value : 60, + DeviceTypeEnum.EMULATED_P4_SWITCH.value : 60, + DeviceTypeEnum.P4_SWITCH.value : 60, + + DeviceTypeEnum.EMULATED_XR_CONSTELLATION.value : 40, + DeviceTypeEnum.XR_CONSTELLATION.value : 40, + + DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM.value : 40, + DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM.value : 40, + + DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value : 30, + DeviceTypeEnum.OPEN_LINE_SYSTEM.value : 30, + + DeviceTypeEnum.EMULATED_PACKET_RADIO_ROUTER.value : 10, + DeviceTypeEnum.PACKET_RADIO_ROUTER.value : 10, + DeviceTypeEnum.EMULATED_OPTICAL_TRANSPONDER.value : 10, + DeviceTypeEnum.OPTICAL_TRANSPONDER.value : 10, + DeviceTypeEnum.EMULATED_OPTICAL_ROADM.value : 10, + DeviceTypeEnum.OPTICAL_ROADM.value : 10, + + DeviceTypeEnum.EMULATED_OPTICAL_SPLITTER.value : 0, +} + +IGNORED_DEVICE_TYPES = {DeviceTypeEnum.EMULATED_OPTICAL_SPLITTER} + +def get_device_controller_uuid( + device : Device +) -> Optional[str]: + controller_uuid = device.controller_id.device_uuid.uuid + if len(controller_uuid) > 0: return controller_uuid + #for config_rule in device.device_config.config_rules: + # if config_rule.WhichOneof('config_rule') != 'custom': continue + # if config_rule.custom.resource_key != '_controller': continue + # device_controller_id = json.loads(config_rule.custom.resource_value) + # return device_controller_id['uuid'] + return None + +def _map_device_type(device : Device) -> DeviceTypeEnum: + device_type = DeviceTypeEnum._value2member_map_.get(device.device_type) # pylint: disable=no-member + if device_type is None: + MSG = 'Unsupported DeviceType({:s}) for Device({:s})' + raise Exception(MSG.format(str(device.device_type), grpc_message_to_json_string(device))) + return device_type + +def _map_resource_to_deepness(device_type : DeviceTypeEnum) -> int: + deepness = DEVICE_TYPE_TO_DEEPNESS.get(device_type.value) + if deepness is None: raise Exception('Unsupported DeviceType({:s})'.format(str(device_type.value))) + return deepness + +def get_device_type( + device : Device, device_dict : Dict[str, Tuple[Dict, Device]], device_controller_uuid : Optional[str] +) -> DeviceTypeEnum: + if device_controller_uuid is None: return _map_device_type(device) + device_controller_tuple = device_dict.get(device_controller_uuid) + if device_controller_tuple is None: raise Exception('Device({:s}) not found'.format(str(device_controller_uuid))) + _,device = device_controller_tuple + return _map_device_type(device) + +def get_resource_classification( + device : Device, device_dict : Dict[str, Tuple[Dict, Device]] +) -> Tuple[int, DeviceTypeEnum, Optional[str]]: + device_controller_uuid = get_device_controller_uuid(device) + device_type = get_device_type(device, device_dict, device_controller_uuid) + resource_deepness = _map_resource_to_deepness(device_type) + return resource_deepness, device_type, device_controller_uuid diff --git a/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py b/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py new file mode 100644 index 0000000000000000000000000000000000000000..463b8039b6c8c611b579bdb74933c06fb0f99507 --- /dev/null +++ b/src/pathcomp/frontend/service/algorithms/tools/ServiceTypes.py @@ -0,0 +1,53 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 common.DeviceTypes import DeviceTypeEnum +from common.proto.context_pb2 import ServiceTypeEnum + +PACKET_DEVICE_TYPES = { + DeviceTypeEnum.TERAFLOWSDN_CONTROLLER, + DeviceTypeEnum.PACKET_ROUTER, DeviceTypeEnum.EMULATED_PACKET_ROUTER, + DeviceTypeEnum.PACKET_SWITCH, DeviceTypeEnum.EMULATED_PACKET_SWITCH, +} + +L2_DEVICE_TYPES = { + DeviceTypeEnum.PACKET_SWITCH, DeviceTypeEnum.EMULATED_PACKET_SWITCH, + DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM, DeviceTypeEnum.EMULATED_MICROWAVE_RADIO_SYSTEM, + DeviceTypeEnum.PACKET_RADIO_ROUTER, DeviceTypeEnum.EMULATED_PACKET_RADIO_ROUTER, + DeviceTypeEnum.P4_SWITCH, DeviceTypeEnum.EMULATED_P4_SWITCH, +} + +OPTICAL_DEVICE_TYPES = { + DeviceTypeEnum.OPEN_LINE_SYSTEM, DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM, + DeviceTypeEnum.XR_CONSTELLATION, DeviceTypeEnum.EMULATED_XR_CONSTELLATION, + DeviceTypeEnum.OPTICAL_ROADM, DeviceTypeEnum.EMULATED_OPTICAL_ROADM, + DeviceTypeEnum.OPTICAL_TRANSPONDER, DeviceTypeEnum.EMULATED_OPTICAL_TRANSPONDER, +} + +SERVICE_TYPE_L2NM = {ServiceTypeEnum.SERVICETYPE_L2NM} +SERVICE_TYPE_L3NM = {ServiceTypeEnum.SERVICETYPE_L3NM} +SERVICE_TYPE_LXNM = {ServiceTypeEnum.SERVICETYPE_L3NM, ServiceTypeEnum.SERVICETYPE_L2NM} +SERVICE_TYPE_TAPI = {ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE} + +def get_service_type(device_type : DeviceTypeEnum, prv_service_type : ServiceTypeEnum) -> ServiceTypeEnum: + if device_type in PACKET_DEVICE_TYPES and prv_service_type in SERVICE_TYPE_LXNM: return prv_service_type + if device_type in L2_DEVICE_TYPES: return ServiceTypeEnum.SERVICETYPE_L2NM + if device_type in OPTICAL_DEVICE_TYPES: return ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE + + str_fields = ', '.join([ + 'device_type={:s}'.format(str(device_type)), + 'prv_service_type={:s}'.format(str(prv_service_type)), + ]) + raise Exception('Undefined Service Type for ({:s})'.format(str_fields)) diff --git a/src/pathcomp/frontend/tests/Objects_A_B_C.py b/src/pathcomp/frontend/tests/Objects_A_B_C.py index f26d74ce4c665663735bae69dcfb5a4e14311bfa..5290123b62251a58d8e0a7f273ea23c38ee2cc8a 100644 --- a/src/pathcomp/frontend/tests/Objects_A_B_C.py +++ b/src/pathcomp/frontend/tests/Objects_A_B_C.py @@ -80,21 +80,36 @@ DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', ' LINK_A2_C3_ID, LINK_A2_C3 = compose_link(DEVICE_A2_ENDPOINTS[2], DEVICE_C3_ENDPOINTS[2]) LINK_C1_B2_ID, LINK_C1_B2 = compose_link(DEVICE_C1_ENDPOINTS[2], DEVICE_B2_ENDPOINTS[2]) +LINK_C3_A2_ID, LINK_C3_A2 = compose_link(DEVICE_C3_ENDPOINTS[2], DEVICE_A2_ENDPOINTS[2]) +LINK_B2_C1_ID, LINK_B2_C1 = compose_link(DEVICE_B2_ENDPOINTS[2], DEVICE_C1_ENDPOINTS[2]) + # ----- IntraDomain A Links -------------------------------------------------------------------------------------------- LINK_A1_A2_ID, LINK_A1_A2 = compose_link(DEVICE_A1_ENDPOINTS[0], DEVICE_A2_ENDPOINTS[0]) LINK_A1_A3_ID, LINK_A1_A3 = compose_link(DEVICE_A1_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[0]) LINK_A2_A3_ID, LINK_A2_A3 = compose_link(DEVICE_A2_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[1]) +LINK_A2_A1_ID, LINK_A2_A1 = compose_link(DEVICE_A2_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[0]) +LINK_A3_A1_ID, LINK_A3_A1 = compose_link(DEVICE_A3_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[1]) +LINK_A3_A2_ID, LINK_A3_A2 = compose_link(DEVICE_A3_ENDPOINTS[1], DEVICE_A2_ENDPOINTS[1]) + # ----- IntraDomain B Links -------------------------------------------------------------------------------------------- LINK_B1_B2_ID, LINK_B1_B2 = compose_link(DEVICE_B1_ENDPOINTS[0], DEVICE_B2_ENDPOINTS[0]) LINK_B1_B3_ID, LINK_B1_B3 = compose_link(DEVICE_B1_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[0]) LINK_B2_B3_ID, LINK_B2_B3 = compose_link(DEVICE_B2_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[1]) +LINK_B2_B1_ID, LINK_B2_B1 = compose_link(DEVICE_B2_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[0]) +LINK_B3_B1_ID, LINK_B3_B1 = compose_link(DEVICE_B3_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[1]) +LINK_B3_B2_ID, LINK_B3_B2 = compose_link(DEVICE_B3_ENDPOINTS[1], DEVICE_B2_ENDPOINTS[1]) + # ----- IntraDomain C Links -------------------------------------------------------------------------------------------- LINK_C1_C2_ID, LINK_C1_C2 = compose_link(DEVICE_C1_ENDPOINTS[0], DEVICE_C2_ENDPOINTS[0]) LINK_C1_C3_ID, LINK_C1_C3 = compose_link(DEVICE_C1_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[0]) LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[1]) +LINK_C2_C1_ID, LINK_C2_C1 = compose_link(DEVICE_C2_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[0]) +LINK_C3_C1_ID, LINK_C3_C1 = compose_link(DEVICE_C3_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[1]) +LINK_C3_C2_ID, LINK_C3_C2 = compose_link(DEVICE_C3_ENDPOINTS[1], DEVICE_C2_ENDPOINTS[1]) + # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[ json_constraint_sla_capacity(10.0), @@ -108,31 +123,38 @@ DEVICES = [ DEVICE_A1, DEVICE_A2, DEVICE_A3, DEVICE_B1, DEVICE_B2, DEVICE_B3, DEVICE_C1, DEVICE_C2, DEVICE_C3, ] LINKS = [ LINK_A2_C3, LINK_C1_B2, + LINK_C3_A2, LINK_B2_C1, + LINK_A1_A2, LINK_A1_A3, LINK_A2_A3, + LINK_A2_A1, LINK_A3_A1, LINK_A3_A2, + LINK_B1_B2, LINK_B1_B3, LINK_B2_B3, - LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, ] + LINK_B2_B1, LINK_B3_B1, LINK_B3_B2, + + LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, + LINK_C2_C1, LINK_C3_C1, LINK_C3_C2, ] SERVICES = [ SERVICE_A1_B1] -OBJECTS_PER_TOPOLOGY = [ - (TOPOLOGY_ADMIN_ID, - [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, - DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, - DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], - [ LINK_A2_C3_ID, LINK_C1_B2_ID, - LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, - LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, - LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], - ), - (TOPOLOGY_A_ID, - [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, ], - [ LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, ], - ), - (TOPOLOGY_B_ID, - [ DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, ], - [ LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, ], - ), - (TOPOLOGY_C_ID, - [ DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], - [ LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], - ), -] +#OBJECTS_PER_TOPOLOGY = [ +# (TOPOLOGY_ADMIN_ID, +# [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, +# DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, +# DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], +# [ LINK_A2_C3_ID, LINK_C1_B2_ID, +# LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, +# LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, +# LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], +# ), +# (TOPOLOGY_A_ID, +# [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, ], +# [ LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, ], +# ), +# (TOPOLOGY_B_ID, +# [ DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, ], +# [ LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, ], +# ), +# (TOPOLOGY_C_ID, +# [ DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], +# [ LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], +# ), +#] diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py index 9ee784e1f76026416bca9824aa8e54e2c4f874f2..053dfd4c45e3822914745905c71f9b64300e1a2f 100644 --- a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py +++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py @@ -118,6 +118,11 @@ LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1 LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0]) LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0]) +LINK_CS1GW1_DC1GW_ID, LINK_CS1GW1_DC1GW = compose_link(DEV_CS1GW1_EPS[0], DEV_DC1GW_EPS[0]) +LINK_CS1GW2_DC1GW_ID, LINK_CS1GW2_DC1GW = compose_link(DEV_CS1GW2_EPS[0], DEV_DC1GW_EPS[1]) +LINK_CS2GW1_DC2GW_ID, LINK_CS2GW1_DC2GW = compose_link(DEV_CS2GW1_EPS[0], DEV_DC2GW_EPS[0]) +LINK_CS2GW2_DC2GW_ID, LINK_CS2GW2_DC2GW = compose_link(DEV_CS2GW2_EPS[0], DEV_DC2GW_EPS[1]) + # InterDomain CSGW-TN LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0]) LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0]) @@ -128,6 +133,15 @@ LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4 LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1]) LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1]) +LINK_TNR1_CS1GW1_ID, LINK_TNR1_CS1GW1 = compose_link(DEV_TNR1_EPS[0], DEV_CS1GW1_EPS[1]) +LINK_TNR2_CS1GW2_ID, LINK_TNR2_CS1GW2 = compose_link(DEV_TNR2_EPS[0], DEV_CS1GW2_EPS[1]) +LINK_TNR2_CS1GW1_ID, LINK_TNR2_CS1GW1 = compose_link(DEV_TNR2_EPS[1], DEV_CS1GW1_EPS[2]) +LINK_TNR1_CS1GW2_ID, LINK_TNR1_CS1GW2 = compose_link(DEV_TNR1_EPS[1], DEV_CS1GW2_EPS[2]) +LINK_TNR3_CS2GW1_ID, LINK_TNR3_CS2GW1 = compose_link(DEV_TNR3_EPS[0], DEV_CS2GW1_EPS[1]) +LINK_TNR4_CS2GW2_ID, LINK_TNR4_CS2GW2 = compose_link(DEV_TNR4_EPS[0], DEV_CS2GW2_EPS[1]) +LINK_TNR4_CS2GW1_ID, LINK_TNR4_CS2GW1 = compose_link(DEV_TNR4_EPS[1], DEV_CS2GW1_EPS[2]) +LINK_TNR3_CS2GW2_ID, LINK_TNR3_CS2GW2 = compose_link(DEV_TNR3_EPS[1], DEV_CS2GW2_EPS[2]) + # IntraDomain TN LINK_TNR1_TNR2_ID, LINK_TNR1_TNR2 = compose_link(DEV_TNR1_EPS[2], DEV_TNR2_EPS[3]) LINK_TNR2_TNR3_ID, LINK_TNR2_TNR3 = compose_link(DEV_TNR2_EPS[2], DEV_TNR3_EPS[3]) @@ -136,6 +150,13 @@ LINK_TNR4_TNR1_ID, LINK_TNR4_TNR1 = compose_link(DEV_TNR4_EPS[2], DEV_TNR1_EPS[3 LINK_TNR1_TNR3_ID, LINK_TNR1_TNR3 = compose_link(DEV_TNR1_EPS[4], DEV_TNR3_EPS[4]) LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4]) +LINK_TNR2_TNR1_ID, LINK_TNR2_TNR1 = compose_link(DEV_TNR2_EPS[3], DEV_TNR1_EPS[2]) +LINK_TNR3_TNR2_ID, LINK_TNR3_TNR2 = compose_link(DEV_TNR3_EPS[3], DEV_TNR2_EPS[2]) +LINK_TNR4_TNR3_ID, LINK_TNR4_TNR3 = compose_link(DEV_TNR4_EPS[3], DEV_TNR3_EPS[2]) +LINK_TNR1_TNR4_ID, LINK_TNR1_TNR4 = compose_link(DEV_TNR1_EPS[3], DEV_TNR4_EPS[2]) +LINK_TNR3_TNR1_ID, LINK_TNR3_TNR1 = compose_link(DEV_TNR3_EPS[4], DEV_TNR1_EPS[4]) +LINK_TNR4_TNR2_ID, LINK_TNR4_TNR2 = compose_link(DEV_TNR4_EPS[4], DEV_TNR2_EPS[4]) + # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[ @@ -151,41 +172,44 @@ DEVICES = [ DEV_DC1GW, DEV_DC2GW, DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4, ] LINKS = [ LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2, + LINK_CS1GW1_DC1GW, LINK_CS1GW2_DC1GW, LINK_CS2GW1_DC2GW, LINK_CS2GW2_DC2GW, + LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1, LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3, LINK_TNR1_TNR2, LINK_TNR2_TNR3, LINK_TNR3_TNR4, LINK_TNR4_TNR1, LINK_TNR1_TNR3, LINK_TNR2_TNR4, + LINK_TNR2_TNR1, LINK_TNR3_TNR2, LINK_TNR4_TNR3, LINK_TNR1_TNR4, LINK_TNR3_TNR1, LINK_TNR4_TNR2, ] SERVICES = [ SERVICE_DC1GW_DC2GW ] -OBJECTS_PER_TOPOLOGY = [ - (TOPO_ADMIN_ID, - [ DEV_DC1GW_ID, DEV_DC2GW_ID, - DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID, - DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, - ], - [ LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID, - LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID, - LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID, - LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, - LINK_TNR2_TNR4_ID, - ], - ), - (TOPO_DC1_ID, - [DEV_DC1GW_ID], - []), - (TOPO_DC2_ID, - [DEV_DC2GW_ID], - []), - (TOPO_CS1_ID, - [DEV_CS1GW1_ID, DEV_CS1GW2_ID], - []), - (TOPO_CS2_ID, - [DEV_CS2GW1_ID, DEV_CS2GW2_ID], - []), - (TOPO_TN_ID, - [ DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, - ], - [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, - LINK_TNR2_TNR4_ID, - ]), -] +#OBJECTS_PER_TOPOLOGY = [ +# (TOPO_ADMIN_ID, +# [ DEV_DC1GW_ID, DEV_DC2GW_ID, +# DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID, +# DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, +# ], +# [ LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID, +# LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID, +# LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID, +# LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, +# LINK_TNR2_TNR4_ID, +# ], +# ), +# (TOPO_DC1_ID, +# [DEV_DC1GW_ID], +# []), +# (TOPO_DC2_ID, +# [DEV_DC2GW_ID], +# []), +# (TOPO_CS1_ID, +# [DEV_CS1GW1_ID, DEV_CS1GW2_ID], +# []), +# (TOPO_CS2_ID, +# [DEV_CS2GW1_ID, DEV_CS2GW2_ID], +# []), +# (TOPO_TN_ID, +# [ DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, +# ], +# [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, +# LINK_TNR2_TNR4_ID, +# ]), +#] diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py index 71510d088746bd791e4671686dd5114874dd5a2a..2c8428568c001a53cbf2c08aa13b61ad14a1bd51 100644 --- a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py +++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py @@ -130,6 +130,11 @@ LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1 LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0]) LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0]) +LINK_CS1GW1_DC1GW_ID, LINK_CS1GW1_DC1GW = compose_link(DEV_CS1GW1_EPS[0], DEV_DC1GW_EPS[0]) +LINK_CS1GW2_DC1GW_ID, LINK_CS1GW2_DC1GW = compose_link(DEV_CS1GW2_EPS[0], DEV_DC1GW_EPS[1]) +LINK_CS2GW1_DC2GW_ID, LINK_CS2GW1_DC2GW = compose_link(DEV_CS2GW1_EPS[0], DEV_DC2GW_EPS[0]) +LINK_CS2GW2_DC2GW_ID, LINK_CS2GW2_DC2GW = compose_link(DEV_CS2GW2_EPS[0], DEV_DC2GW_EPS[1]) + # InterDomain CSGW-TN LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0]) LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0]) @@ -140,12 +145,26 @@ LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4 LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1]) LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1]) +LINK_TNR1_CS1GW1_ID, LINK_TNR1_CS1GW1 = compose_link(DEV_TNR1_EPS[0], DEV_CS1GW1_EPS[1]) +LINK_TNR2_CS1GW2_ID, LINK_TNR2_CS1GW2 = compose_link(DEV_TNR2_EPS[0], DEV_CS1GW2_EPS[1]) +LINK_TNR2_CS1GW1_ID, LINK_TNR2_CS1GW1 = compose_link(DEV_TNR2_EPS[1], DEV_CS1GW1_EPS[2]) +LINK_TNR1_CS1GW2_ID, LINK_TNR1_CS1GW2 = compose_link(DEV_TNR1_EPS[1], DEV_CS1GW2_EPS[2]) +LINK_TNR3_CS2GW1_ID, LINK_TNR3_CS2GW1 = compose_link(DEV_TNR3_EPS[0], DEV_CS2GW1_EPS[1]) +LINK_TNR4_CS2GW2_ID, LINK_TNR4_CS2GW2 = compose_link(DEV_TNR4_EPS[0], DEV_CS2GW2_EPS[1]) +LINK_TNR4_CS2GW1_ID, LINK_TNR4_CS2GW1 = compose_link(DEV_TNR4_EPS[1], DEV_CS2GW1_EPS[2]) +LINK_TNR3_CS2GW2_ID, LINK_TNR3_CS2GW2 = compose_link(DEV_TNR3_EPS[1], DEV_CS2GW2_EPS[2]) + # IntraDomain TN LINK_TNR1_TOLS_ID, LINK_TNR1_TOLS = compose_link(DEV_TNR1_EPS[2], DEV_TOLS_EPS[0]) LINK_TNR2_TOLS_ID, LINK_TNR2_TOLS = compose_link(DEV_TNR2_EPS[2], DEV_TOLS_EPS[1]) LINK_TNR3_TOLS_ID, LINK_TNR3_TOLS = compose_link(DEV_TNR3_EPS[2], DEV_TOLS_EPS[2]) LINK_TNR4_TOLS_ID, LINK_TNR4_TOLS = compose_link(DEV_TNR4_EPS[2], DEV_TOLS_EPS[3]) +LINK_TOLS_TNR1_ID, LINK_TOLS_TNR1 = compose_link(DEV_TOLS_EPS[0], DEV_TNR1_EPS[2]) +LINK_TOLS_TNR2_ID, LINK_TOLS_TNR2 = compose_link(DEV_TOLS_EPS[1], DEV_TNR2_EPS[2]) +LINK_TOLS_TNR3_ID, LINK_TOLS_TNR3 = compose_link(DEV_TOLS_EPS[2], DEV_TNR3_EPS[2]) +LINK_TOLS_TNR4_ID, LINK_TOLS_TNR4 = compose_link(DEV_TOLS_EPS[3], DEV_TNR4_EPS[2]) + # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[ @@ -162,41 +181,47 @@ DEVICES = [ DEV_DC1GW, DEV_DC2GW, DEV_TOLS, ] LINKS = [ LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2, + LINK_CS1GW1_DC1GW, LINK_CS1GW2_DC1GW, LINK_CS2GW1_DC2GW, LINK_CS2GW2_DC2GW, + LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1, LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3, + LINK_TNR1_CS1GW1, LINK_TNR2_CS1GW2, LINK_TNR2_CS1GW1, LINK_TNR1_CS1GW2, + LINK_TNR3_CS2GW1, LINK_TNR4_CS2GW2, LINK_TNR4_CS2GW1, LINK_TNR3_CS2GW2, + LINK_TNR1_TOLS, LINK_TNR2_TOLS, LINK_TNR3_TOLS, LINK_TNR4_TOLS, + LINK_TOLS_TNR1, LINK_TOLS_TNR2, LINK_TOLS_TNR3, LINK_TOLS_TNR4, ] SERVICES = [ SERVICE_DC1GW_DC2GW ] -OBJECTS_PER_TOPOLOGY = [ - (TOPO_ADMIN_ID, - [ DEV_DC1GW_ID, DEV_DC2GW_ID, - DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID, - DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, - DEV_TOLS_ID, - ], - [ LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID, - LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID, - LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID, - LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID, - ], - ), - (TOPO_DC1_ID, - [DEV_DC1GW_ID], - []), - (TOPO_DC2_ID, - [DEV_DC2GW_ID], - []), - (TOPO_CS1_ID, - [DEV_CS1GW1_ID, DEV_CS1GW2_ID], - []), - (TOPO_CS2_ID, - [DEV_CS2GW1_ID, DEV_CS2GW2_ID], - []), - (TOPO_TN_ID, - [ DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, - DEV_TOLS_ID, - ], - [ LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID, - ]), -] +#OBJECTS_PER_TOPOLOGY = [ +# (TOPO_ADMIN_ID, +# [ DEV_DC1GW_ID, DEV_DC2GW_ID, +# DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID, +# DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, +# DEV_TOLS_ID, +# ], +# [ LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID, +# LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID, +# LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID, +# LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID, +# ], +# ), +# (TOPO_DC1_ID, +# [DEV_DC1GW_ID], +# []), +# (TOPO_DC2_ID, +# [DEV_DC2GW_ID], +# []), +# (TOPO_CS1_ID, +# [DEV_CS1GW1_ID, DEV_CS1GW2_ID], +# []), +# (TOPO_CS2_ID, +# [DEV_CS2GW1_ID, DEV_CS2GW2_ID], +# []), +# (TOPO_TN_ID, +# [ DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, +# DEV_TOLS_ID, +# ], +# [ LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID, +# ]), +#] diff --git a/src/dbscanserving/proto/__init__.py b/src/pathcomp/frontend/tests/test_pathcomp/__init__.py similarity index 100% rename from src/dbscanserving/proto/__init__.py rename to src/pathcomp/frontend/tests/test_pathcomp/__init__.py diff --git a/src/pathcomp/frontend/tests/test_pathcomp/__main__.py b/src/pathcomp/frontend/tests/test_pathcomp/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..ba1cc4a2c1838248882b983c1ed25c27b395aa9a --- /dev/null +++ b/src/pathcomp/frontend/tests/test_pathcomp/__main__.py @@ -0,0 +1,33 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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, sys +from common.proto.context_pb2 import ServiceTypeEnum +from pathcomp.frontend.service.algorithms.tools.ComputeSubServices import convert_explicit_path_hops_to_connections +from .data import path_hops, device_dict + +logging.basicConfig(level=logging.DEBUG) +LOGGER = logging.getLogger(__name__) + +def main(): + service_uuid = 'dc-2-dc-svc' + service_type = ServiceTypeEnum.SERVICETYPE_L2NM + connections = convert_explicit_path_hops_to_connections(path_hops, device_dict, service_uuid, service_type) + str_connections = '\n'.join([' ' + str(connection) for connection in connections]) + LOGGER.debug('connections = [\n{:s}\n]'.format(str_connections)) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/pathcomp/frontend/tests/test_pathcomp/data.py b/src/pathcomp/frontend/tests/test_pathcomp/data.py new file mode 100644 index 0000000000000000000000000000000000000000..aeac5e38a222fb2dfc3f7ae98b2737b47f855ee4 --- /dev/null +++ b/src/pathcomp/frontend/tests/test_pathcomp/data.py @@ -0,0 +1,70 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json +from typing import Dict, Tuple +from common.DeviceTypes import DeviceTypeEnum +from common.proto.context_pb2 import ConfigActionEnum, Device + +path_hops = [ + {'device': 'DC1', 'ingress_ep': 'int', 'egress_ep': 'eth1' }, + {'device': 'PE1', 'ingress_ep': '1/1', 'egress_ep': '1/2' }, + {'device': 'MW1-2', 'ingress_ep': '172.18.0.1:1', 'egress_ep': '172.18.0.2:1' }, + {'device': 'HUB1', 'ingress_ep': '1/1', 'egress_ep': 'XR-T1' }, + {'device': 'splitter', 'ingress_ep': 'common', 'egress_ep': 'leaf1' }, + {'device': 'OLS', 'ingress_ep': 'node_1_port_13-input', 'egress_ep': 'node_4_port_13-output'}, + {'device': 'LEAF2', 'ingress_ep': 'XR-T1', 'egress_ep': '1/1' }, + {'device': 'PE4', 'ingress_ep': '1/1', 'egress_ep': '1/2' }, + {'device': 'DC2', 'ingress_ep': 'eth2', 'egress_ep': 'int' } +] + +device_data = { + 'TFS' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.TERAFLOWSDN_CONTROLLER }, + 'IPM' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.XR_CONSTELLATION }, + 'OLS' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.OPEN_LINE_SYSTEM }, + 'MW1-2' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM }, + 'MW3-4' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.MICROWAVE_RADIO_SYSTEM }, + + 'DC1' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.EMULATED_DATACENTER }, + 'DC2' : {'controller_uuid': None, 'device_type': DeviceTypeEnum.EMULATED_DATACENTER }, + + 'PE1' : {'controller_uuid': 'TFS', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + 'PE2' : {'controller_uuid': 'TFS', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + 'PE3' : {'controller_uuid': 'TFS', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + 'PE4' : {'controller_uuid': 'TFS', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + + 'HUB1' : {'controller_uuid': 'IPM', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + 'LEAF1' : {'controller_uuid': 'IPM', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + 'LEAF2' : {'controller_uuid': 'IPM', 'device_type': DeviceTypeEnum.PACKET_ROUTER }, + + 'splitter': {'controller_uuid': None, 'device_type': DeviceTypeEnum.EMULATED_OPTICAL_SPLITTER}, +} + +def process_device(device_uuid, json_device) -> Tuple[Dict, Device]: + grpc_device = Device() + grpc_device.device_id.device_uuid.uuid = device_uuid # pylint: disable=no-member + grpc_device.device_type = json_device['device_type'].value + controller_uuid = json_device.get('controller_uuid') + if controller_uuid is not None: + config_rule = grpc_device.device_config.config_rules.add() # pylint: disable=no-member + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = '_controller' + config_rule.custom.resource_value = json.dumps({'uuid': controller_uuid}) + return json_device, grpc_device + +device_dict = { + device_uuid:process_device(device_uuid, json_device) + for device_uuid,json_device in device_data.items() +} diff --git a/src/pathcomp/frontend/tests/test_unitary.py b/src/pathcomp/frontend/tests/test_unitary.py index 8088259b80b8ade2669568b74f004dcfa631dd9c..f4e3cbf0f60285b960625a677854c4b7ab4decb9 100644 --- a/src/pathcomp/frontend/tests/test_unitary.py +++ b/src/pathcomp/frontend/tests/test_unitary.py @@ -13,12 +13,15 @@ # limitations under the License. import copy, logging, os -from common.proto.context_pb2 import Context, ContextId, DeviceId, Link, LinkId, Topology, Device, TopologyId +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId from common.proto.pathcomp_pb2 import PathCompRequest +from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario from common.tools.grpc.Tools import grpc_message_to_json from common.tools.object_factory.Constraint import ( json_constraint_custom, json_constraint_endpoint_location_region, json_constraint_endpoint_priority, json_constraint_sla_availability, json_constraint_sla_capacity, json_constraint_sla_latency) +from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Device import json_device_id from common.tools.object_factory.EndPoint import json_endpoint_id from common.tools.object_factory.Service import json_service_l3nm_planned @@ -26,9 +29,9 @@ from context.client.ContextClient import ContextClient from pathcomp.frontend.client.PathCompClient import PathCompClient # Scenarios: -#from .Objects_A_B_C import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES -#from .Objects_DC_CSGW_TN import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES -from .Objects_DC_CSGW_TN_OLS import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES +#from .Objects_A_B_C import CONTEXTS, DEVICES, LINKS, SERVICES, TOPOLOGIES +#from .Objects_DC_CSGW_TN import CONTEXTS, DEVICES, LINKS, SERVICES, TOPOLOGIES +from .Objects_DC_CSGW_TN_OLS import CONTEXTS, DEVICES, LINKS, SERVICES, TOPOLOGIES # configure backend environment variables before overwriting them with fixtures to use real backend pathcomp DEFAULT_PATHCOMP_BACKEND_SCHEME = 'http' @@ -58,31 +61,29 @@ from .PrepareTestScenario import ( # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -def test_prepare_environment( - context_client : ContextClient): # pylint: disable=redefined-outer-name - - for context in CONTEXTS : context_client.SetContext (Context (**context )) - for topology in TOPOLOGIES: context_client.SetTopology(Topology(**topology)) - for device in DEVICES : context_client.SetDevice (Device (**device )) - for link in LINKS : context_client.SetLink (Link (**link )) - - for topology_id, device_ids, link_ids in OBJECTS_PER_TOPOLOGY: - topology = Topology() - topology.CopyFrom(context_client.GetTopology(TopologyId(**topology_id))) +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) +DESCRIPTORS = { + 'dummy_mode': True, + 'contexts' : CONTEXTS, + 'topologies': TOPOLOGIES, + 'devices' : DEVICES, + 'links' : LINKS, +} - device_ids_in_topology = {device_id.device_uuid.uuid for device_id in topology.device_ids} - func_device_id_not_added = lambda device_id: device_id['device_uuid']['uuid'] not in device_ids_in_topology - func_device_id_json_to_grpc = lambda device_id: DeviceId(**device_id) - device_ids_to_add = list(map(func_device_id_json_to_grpc, filter(func_device_id_not_added, device_ids))) - topology.device_ids.extend(device_ids_to_add) +def test_prepare_environment( + context_client : ContextClient, # pylint: disable=redefined-outer-name +) -> None: + validate_empty_scenario(context_client) - link_ids_in_topology = {link_id.link_uuid.uuid for link_id in topology.link_ids} - func_link_id_not_added = lambda link_id: link_id['link_uuid']['uuid'] not in link_ids_in_topology - func_link_id_json_to_grpc = lambda link_id: LinkId(**link_id) - link_ids_to_add = list(map(func_link_id_json_to_grpc, filter(func_link_id_not_added, link_ids))) - topology.link_ids.extend(link_ids_to_add) + descriptor_loader = DescriptorLoader(descriptors=DESCRIPTORS, context_client=context_client) + results = descriptor_loader.process() + check_descriptor_load_results(results, descriptor_loader) + descriptor_loader.validate() - context_client.SetTopology(topology) + # Verify the scenario has no services/slices + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 def test_request_service_shortestpath( pathcomp_client : PathCompClient): # pylint: disable=redefined-outer-name @@ -266,9 +267,15 @@ def test_request_service_kdisjointpath( def test_cleanup_environment( - context_client : ContextClient): # pylint: disable=redefined-outer-name - - for link in LINKS : context_client.RemoveLink (LinkId (**link ['link_id' ])) - for device in DEVICES : context_client.RemoveDevice (DeviceId (**device ['device_id' ])) - for topology in TOPOLOGIES: context_client.RemoveTopology(TopologyId(**topology['topology_id'])) - for context in CONTEXTS : context_client.RemoveContext (ContextId (**context ['context_id' ])) + context_client : ContextClient, # pylint: disable=redefined-outer-name +) -> None: + # Verify the scenario has no services/slices + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 + + # Load descriptors and validate the base scenario + descriptor_loader = DescriptorLoader(descriptors=DESCRIPTORS, context_client=context_client) + descriptor_loader.validate() + descriptor_loader.unload() + validate_empty_scenario(context_client) diff --git a/src/policy/pom.xml b/src/policy/pom.xml index 6ea28421abedf6916e998b6cfdebe23c34908c4a..267006311f82c11bce4db29f2d114f30c1832f88 100644 --- a/src/policy/pom.xml +++ b/src/policy/pom.xml @@ -179,6 +179,11 @@ test + + io.quarkus + quarkus-smallrye-metrics + + diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java index c10e5dc8b91ee9dcc2ae8aa74526faeb4e4bfcec..30e888d9fab1aae535dca345c7c56e28218bd2c2 100644 --- a/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java +++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java @@ -20,6 +20,9 @@ import context.ContextOuterClass.ServiceId; import io.quarkus.grpc.GrpcService; import io.smallrye.mutiny.Uni; import javax.inject.Inject; +import org.eclipse.microprofile.metrics.MetricUnits; +import org.eclipse.microprofile.metrics.annotation.Counted; +import org.eclipse.microprofile.metrics.annotation.Timed; import policy.Policy; import policy.Policy.PolicyRuleBasic; import policy.Policy.PolicyRuleDevice; @@ -41,6 +44,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_policyAddService_counter") + @Timed(name = "policy_policyAddService_histogram", unit = MetricUnits.MILLISECONDS) public Uni policyAddService(PolicyRuleService request) { final var policyRuleService = serializer.deserialize(request); @@ -51,6 +56,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_policyUpdateService_counter") + @Timed(name = "policy_policyUpdateService_histogram", unit = MetricUnits.MILLISECONDS) public Uni policyUpdateService(PolicyRuleService request) { final var policyRuleService = serializer.deserialize(request); @@ -61,6 +68,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_policyAddDevice_counter") + @Timed(name = "policy_policyAddDevice_histogram", unit = MetricUnits.MILLISECONDS) public Uni policyAddDevice(PolicyRuleDevice request) { final var policyRuleDevice = serializer.deserialize(request); @@ -71,6 +80,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_policyUpdateDevice_counter") + @Timed(name = "policy_policyUpdateDevice_histogram", unit = MetricUnits.MILLISECONDS) public Uni policyUpdateDevice(PolicyRuleDevice request) { final var policyRuleDevice = serializer.deserialize(request); @@ -81,6 +92,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_policyDelete_counter") + @Timed(name = "policy_policyDelete_histogram", unit = MetricUnits.MILLISECONDS) public Uni policyDelete(PolicyRuleId request) { final var policyRuleId = serializer.deserialize(request); @@ -88,6 +101,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_getPolicyService_counter") + @Timed(name = "policy_getPolicyService_histogram", unit = MetricUnits.MILLISECONDS) public Uni getPolicyService(PolicyRuleId request) { final var policyRuleBasic = PolicyRuleBasic.newBuilder().setPolicyRuleId(request).build(); @@ -96,6 +111,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_getPolicyDevice_counter") + @Timed(name = "policy_getPolicyDevice_histogram", unit = MetricUnits.MILLISECONDS) public Uni getPolicyDevice(PolicyRuleId request) { final var policyRuleBasic = PolicyRuleBasic.newBuilder().setPolicyRuleId(request).build(); @@ -104,6 +121,8 @@ public class PolicyGatewayImpl implements PolicyGateway { } @Override + @Counted(name = "policy_getPolicyByServiceId_counter") + @Timed(name = "policy_getPolicyByServiceId_histogram", unit = MetricUnits.MILLISECONDS) public Uni getPolicyByServiceId(ServiceId request) { return Uni.createFrom().item(() -> Policy.PolicyRuleServiceList.newBuilder().build()); } diff --git a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java index 529ec633426e41f3218857642aa6751ac574ab23..52d594ea4200c2ce4d775edf2f06cf7a9c9f9097 100644 --- a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java +++ b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java @@ -1124,8 +1124,12 @@ public class Serializer { return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PLANNED; case PENDING_REMOVAL: return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL; + case SLA_VIOLATED: + return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_SLA_VIOLATED; case UNDEFINED: return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_UNDEFINED; + case UPDATING: + return ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_UPDATING; default: return ContextOuterClass.ServiceStatusEnum.UNRECOGNIZED; } @@ -1140,6 +1144,10 @@ public class Serializer { return ServiceStatusEnum.PLANNED; case SERVICESTATUS_PENDING_REMOVAL: return ServiceStatusEnum.PENDING_REMOVAL; + case SERVICESTATUS_SLA_VIOLATED: + return ServiceStatusEnum.SLA_VIOLATED; + case SERVICESTATUS_UPDATING: + return ServiceStatusEnum.UPDATING; case SERVICESTATUS_UNDEFINED: case UNRECOGNIZED: default: @@ -2245,6 +2253,8 @@ public class Serializer { return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352; case XR: return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_XR; + case IETF_L2VPN: + return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN; case UNDEFINED: default: return ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_UNDEFINED; @@ -2266,6 +2276,8 @@ public class Serializer { return DeviceDriverEnum.ONF_TR_352; case DEVICEDRIVER_XR: return DeviceDriverEnum.XR; + case DEVICEDRIVER_IETF_L2VPN: + return DeviceDriverEnum.IETF_L2VPN; case DEVICEDRIVER_UNDEFINED: case UNRECOGNIZED: default: diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceDriverEnum.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceDriverEnum.java index daee299ddf64327c0d782e640cd1e924e139dccb..ad763e35dfeef71c2f9f73dbf51785a3e03c0e0d 100644 --- a/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceDriverEnum.java +++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceDriverEnum.java @@ -23,5 +23,6 @@ public enum DeviceDriverEnum { P4, IETF_NETWORK_TOPOLOGY, ONF_TR_352, - XR + XR, + IETF_L2VPN } diff --git a/src/policy/src/main/resources/application.yml b/src/policy/src/main/resources/application.yml index e908f5e36265fb2c3050f1b7e4247847463fc385..38a222d7934751e9eac28854300d55bd631a669c 100644 --- a/src/policy/src/main/resources/application.yml +++ b/src/policy/src/main/resources/application.yml @@ -37,6 +37,7 @@ quarkus: group: tfs name: controller/policy registry: labs.etsi.org:5050 + tag: 0.1.0 kubernetes: name: policyservice @@ -52,14 +53,18 @@ quarkus: period: 10s ports: http: - host-port: 8080 + host-port: 9192 container-port: 8080 - grpc: - host-port: 6060 - container-port: 6060 env: vars: context-service-host: "contextservice" monitoring-service-host: "monitoringservice" service-service-host: "serviceservice" + resources: + requests: + cpu: 50m + memory: 512Mi + limits: + cpu: 500m + memory: 2048Mi diff --git a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java index d284840b8dedb0320d49a5d5c6a1943c10d2afed..f06c30204b874cd6be30cd1a906c5087412e9640 100644 --- a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java +++ b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java @@ -1910,6 +1910,12 @@ class SerializerTest { Arguments.of( ServiceStatusEnum.PENDING_REMOVAL, ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL), + Arguments.of( + ServiceStatusEnum.SLA_VIOLATED, + ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_SLA_VIOLATED), + Arguments.of( + ServiceStatusEnum.UPDATING, + ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_UPDATING), Arguments.of( ServiceStatusEnum.UNDEFINED, ContextOuterClass.ServiceStatusEnum.SERVICESTATUS_UNDEFINED)); @@ -3600,6 +3606,9 @@ class SerializerTest { DeviceDriverEnum.ONF_TR_352, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352), Arguments.of(DeviceDriverEnum.XR, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_XR), + Arguments.of( + DeviceDriverEnum.IETF_L2VPN, + ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN), Arguments.of( DeviceDriverEnum.UNDEFINED, ContextOuterClass.DeviceDriverEnum.DEVICEDRIVER_UNDEFINED)); } diff --git a/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java b/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java index fbbba62a2baa1c2fe2b3c3fe090883d6542996e4..53252341b30dc093c79d5a54baf98b82e6a24b75 100644 --- a/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java +++ b/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java @@ -177,6 +177,10 @@ public final class ContextOuterClass { * DEVICEDRIVER_XR = 6; */ DEVICEDRIVER_XR(6), + /** + * DEVICEDRIVER_IETF_L2VPN = 7; + */ + DEVICEDRIVER_IETF_L2VPN(7), UNRECOGNIZED(-1), ; @@ -212,6 +216,10 @@ public final class ContextOuterClass { * DEVICEDRIVER_XR = 6; */ public static final int DEVICEDRIVER_XR_VALUE = 6; + /** + * DEVICEDRIVER_IETF_L2VPN = 7; + */ + public static final int DEVICEDRIVER_IETF_L2VPN_VALUE = 7; public final int getNumber() { @@ -245,6 +253,7 @@ public final class ContextOuterClass { case 4: return DEVICEDRIVER_IETF_NETWORK_TOPOLOGY; case 5: return DEVICEDRIVER_ONF_TR_352; case 6: return DEVICEDRIVER_XR; + case 7: return DEVICEDRIVER_IETF_L2VPN; default: return null; } } diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml index 40516e5cc3fdd1fb993a1248ad36ea7551edfc40..f1079230f5e5efb75fb14d6cd6f3ad3fb5c9d2e3 100644 --- a/src/policy/target/kubernetes/kubernetes.yml +++ b/src/policy/target/kubernetes/kubernetes.yml @@ -4,21 +4,24 @@ # 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 +# 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: v1 kind: Service metadata: annotations: - app.quarkus.io/commit-id: e369fc6b4de63303f91e1fd3de0b6a591a86c0f5 - app.quarkus.io/build-timestamp: 2022-11-18 - 12:56:37 +0000 + app.quarkus.io/commit-id: 23832f2975e3c8967e9685f7e3a5f5458d04527a + app.quarkus.io/build-timestamp: 2023-04-04 - 11:56:04 +0000 + prometheus.io/scrape: "true" + prometheus.io/path: /q/metrics + prometheus.io/port: "8080" + prometheus.io/scheme: http labels: app.kubernetes.io/name: policyservice app: policyservice @@ -26,9 +29,9 @@ metadata: spec: ports: - name: http - port: 8080 + port: 9192 targetPort: 8080 - - name: grpc + - name: grpc-server port: 6060 targetPort: 6060 selector: @@ -39,8 +42,12 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - app.quarkus.io/commit-id: e369fc6b4de63303f91e1fd3de0b6a591a86c0f5 - app.quarkus.io/build-timestamp: 2022-11-22 - 14:10:01 +0000 + app.quarkus.io/commit-id: 23832f2975e3c8967e9685f7e3a5f5458d04527a + app.quarkus.io/build-timestamp: 2023-04-04 - 11:56:04 +0000 + prometheus.io/scrape: "true" + prometheus.io/path: /q/metrics + prometheus.io/port: "8080" + prometheus.io/scheme: http labels: app: policyservice app.kubernetes.io/name: policyservice @@ -53,8 +60,12 @@ spec: template: metadata: annotations: - app.quarkus.io/commit-id: e369fc6b4de63303f91e1fd3de0b6a591a86c0f5 - app.quarkus.io/build-timestamp: 2022-11-22 - 14:10:01 +0000 + app.quarkus.io/commit-id: 23832f2975e3c8967e9685f7e3a5f5458d04527a + app.quarkus.io/build-timestamp: 2023-04-04 - 11:56:04 +0000 + prometheus.io/scrape: "true" + prometheus.io/path: /q/metrics + prometheus.io/port: "8080" + prometheus.io/scheme: http labels: app: policyservice app.kubernetes.io/name: policyservice @@ -89,7 +100,7 @@ spec: name: http protocol: TCP - containerPort: 6060 - name: grpc + name: grpc-server protocol: TCP readinessProbe: failureThreshold: 3 @@ -101,3 +112,10 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 + resources: + limits: + cpu: 500m + memory: 2048Mi + requests: + cpu: 50m + memory: 512Mi diff --git a/src/service/client/ServiceClient.py b/src/service/client/ServiceClient.py index 30ff4f4838dd52d7010f08a7814ff208afbe92f4..e8ea478a3109d3e006120db9f22966724773b78b 100644 --- a/src/service/client/ServiceClient.py +++ b/src/service/client/ServiceClient.py @@ -65,3 +65,10 @@ class ServiceClient: response = self.stub.DeleteService(request) LOGGER.debug('DeleteService result: {:s}'.format(grpc_message_to_json_string(response))) return response + + @RETRY_DECORATOR + def RecomputeConnections(self, request : Service) -> Empty: + LOGGER.debug('RecomputeConnections request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.RecomputeConnections(request) + LOGGER.debug('RecomputeConnections result: {:s}'.format(grpc_message_to_json_string(response))) + return response diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py index 0b2e0760161c109a2ba6a5feecc931e8bcf5c14f..6d23fd4cee53d1639c9eefbd943d45dab497b253 100644 --- a/src/service/service/ServiceServiceServicerImpl.py +++ b/src/service/service/ServiceServiceServicerImpl.py @@ -12,19 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, json, logging +import grpc, json, logging, random, uuid from typing import Optional from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method -from common.method_wrappers.ServiceExceptions import AlreadyExistsException, InvalidArgumentException -from common.proto.context_pb2 import Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum +from common.method_wrappers.ServiceExceptions import ( + AlreadyExistsException, InvalidArgumentException, NotFoundException, NotImplementedException, + OperationFailedException) +from common.proto.context_pb2 import Connection, Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum from common.proto.pathcomp_pb2 import PathCompRequest from common.proto.service_pb2_grpc import ServiceServiceServicer +from common.tools.context_queries.Service import get_service_by_id from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string from context.client.ContextClient import ContextClient from pathcomp.frontend.client.PathCompClient import PathCompClient +from service.service.tools.ConnectionToString import connection_to_string from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory from .task_scheduler.TaskScheduler import TasksScheduler -from .tools.ContextGetters import get_service LOGGER = logging.getLogger(__name__) @@ -69,7 +72,9 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): # check that service does not exist context_client = ContextClient() - current_service = get_service(context_client, request.service_id) + current_service = get_service_by_id( + context_client, request.service_id, rw_copy=False, + include_config_rules=False, include_constraints=False, include_endpoint_ids=False) if current_service is not None: context_uuid = request.service_id.context_id.context_uuid.uuid service_uuid = request.service_id.service_uuid.uuid @@ -86,7 +91,9 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): # Set service status to "SERVICESTATUS_PLANNED" to ensure rest of components are aware the service is # being modified. context_client = ContextClient() - _service : Optional[Service] = get_service(context_client, request.service_id) + _service : Optional[Service] = get_service_by_id( + context_client, request.service_id, rw_copy=False, + include_config_rules=False, include_constraints=False, include_endpoint_ids=False) service = Service() service.CopyFrom(request if _service is None else _service) if service.service_type == ServiceTypeEnum.SERVICETYPE_UNKNOWN: # pylint: disable=no-member @@ -106,7 +113,11 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): service.service_config.config_rules.add().CopyFrom(config_rule) # pylint: disable=no-member service_id_with_uuids = context_client.SetService(service) - service_with_uuids = context_client.GetService(service_id_with_uuids) + + # PathComp requires endpoints, constraints and config rules + service_with_uuids = get_service_by_id( + context_client, service_id_with_uuids, rw_copy=False, + include_config_rules=True, include_constraints=True, include_endpoint_ids=True) num_disjoint_paths = 0 for constraint in request.service_constraints: @@ -147,10 +158,8 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): # Set service status to "SERVICESTATUS_PENDING_REMOVAL" to ensure rest of components are aware the service is # being modified. - _service : Optional[Service] = get_service(context_client, request) - if _service is None: raise Exception('Service({:s}) not found'.format(grpc_message_to_json_string(request))) - service = Service() - service.CopyFrom(_service) + service : Optional[Service] = get_service_by_id(context_client, request, rw_copy=True) + if service is None: raise Exception('Service({:s}) not found'.format(grpc_message_to_json_string(request))) # pylint: disable=no-member service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL context_client.SetService(service) @@ -162,3 +171,160 @@ class ServiceServiceServicerImpl(ServiceServiceServicer): tasks_scheduler.compose_from_service(service, is_delete=True) tasks_scheduler.execute_all() return Empty() + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def RecomputeConnections(self, request : Service, context : grpc.ServicerContext) -> Empty: + if len(request.service_endpoint_ids) > 0: + raise NotImplementedException('update-endpoints') + + if len(request.service_constraints) > 0: + raise NotImplementedException('update-constraints') + + if len(request.service_config.config_rules) > 0: + raise NotImplementedException('update-config-rules') + + context_client = ContextClient() + + updated_service : Optional[Service] = get_service_by_id( + context_client, request.service_id, rw_copy=True, + include_config_rules=False, include_constraints=False, include_endpoint_ids=False) + + if updated_service is None: + raise NotFoundException('service', request.service_id.service_uuid.uuid) + + # pylint: disable=no-member + if updated_service.service_type == ServiceTypeEnum.SERVICETYPE_UNKNOWN: + raise InvalidArgumentException( + 'request.service_type', ServiceTypeEnum.Name(updated_service.service_type) + ) + + # Set service status to "SERVICESTATUS_UPDATING" to ensure rest of components are aware the service is + # being modified. + # pylint: disable=no-member + updated_service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_UPDATING + + # Update endpoints + # pylint: disable=no-member + #del updated_service.service_endpoint_ids[:] + #updated_service.service_endpoint_ids.extend(request.service_endpoint_ids) + + # Update constraints + # pylint: disable=no-member + #del updated_service.service_constraints[:] + #updated_service.service_constraints.extend(request.service_constraints) + + # Update config rules + # pylint: disable=no-member + #del updated_service.service_config.config_rules[:] + #updated_service.service_config.config_rules.extend(request.service_config.config_rules) + + updated_service_id_with_uuids = context_client.SetService(updated_service) + + # PathComp requires endpoints, constraints and config rules + 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) + + # Get active connection + connections = context_client.ListConnections(updated_service_id_with_uuids) + if len(connections.connections) == 0: + MSG = 'Service({:s}) has no connections' + str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) + str_extra_details = MSG.format(str_service_id) + raise NotImplementedException('service-with-no-connections', extra_details=str_extra_details) + if len(connections.connections) > 1: + MSG = 'Service({:s}) has multiple ({:d}) connections({:s})' + str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) + num_connections = len(connections.connections) + str_connections = grpc_message_to_json_string(connections) + str_extra_details = MSG.format(str_service_id, num_connections, str_connections) + raise NotImplementedException('service-with-multiple-connections', extra_details=str_extra_details) + + old_connection = connections.connections[0] + if len(old_connection.sub_service_ids) > 0: + MSG = 'Service({:s})/Connection({:s}) has sub-services: {:s}' + str_service_id = grpc_message_to_json_string(updated_service_id_with_uuids) + str_connection_id = grpc_message_to_json_string(old_connection.connection_id) + 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) + + # 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))) + + 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() + + return Empty() diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index d755348ad3ebe0051885b56038e968ec2565d1b1..f2b6e38d6181a0c56b4f1dfca3116717d1400ced 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -62,7 +62,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py index a73ec53f37d68e0414eeb1df146373c6906273c5..3ec71dc64536e28457c4f1adbf3679186285786d 100644 --- a/src/service/service/service_handler_api/FilterFields.py +++ b/src/service/service/service_handler_api/FilterFields.py @@ -33,7 +33,8 @@ DEVICE_DRIVER_VALUES = { DeviceDriverEnum.DEVICEDRIVER_P4, DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352, - DeviceDriverEnum.DEVICEDRIVER_XR + DeviceDriverEnum.DEVICEDRIVER_XR, + DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN, } # Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified diff --git a/src/service/service/service_handler_api/ServiceHandlerFactory.py b/src/service/service/service_handler_api/ServiceHandlerFactory.py index 6aa21b49920254383fad5f28aa234b6ec0cad5a3..64ea204a2600a71b08c8c373a15640f5e2134787 100644 --- a/src/service/service/service_handler_api/ServiceHandlerFactory.py +++ b/src/service/service/service_handler_api/ServiceHandlerFactory.py @@ -73,6 +73,9 @@ class ServiceHandlerFactory: if field_indice is None: continue if not isinstance(field_values, Iterable) or isinstance(field_values, str): field_values = [field_values] + if len(field_values) == 0: + # do not allow empty fields; might cause wrong selection + raise UnsatisfiedFilterException(filter_fields) field_enum_values = FILTER_FIELD_ALLOWED_VALUES.get(field_name) diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py index 4c9059779d6b7031685e1de76b0a7ed651af6c5f..257bc138fe932e7e5abee00981848248039d0b3f 100644 --- a/src/service/service/service_handlers/__init__.py +++ b/src/service/service/service_handlers/__init__.py @@ -15,12 +15,14 @@ from common.proto.context_pb2 import DeviceDriverEnum, ServiceTypeEnum from ..service_handler_api.FilterFields import FilterFieldEnum from .l2nm_emulated.L2NMEmulatedServiceHandler import L2NMEmulatedServiceHandler +from .l2nm_ietfl2vpn.L2NM_IETFL2VPN_ServiceHandler import L2NM_IETFL2VPN_ServiceHandler from .l2nm_openconfig.L2NMOpenConfigServiceHandler import L2NMOpenConfigServiceHandler from .l3nm_emulated.L3NMEmulatedServiceHandler import L3NMEmulatedServiceHandler from .l3nm_openconfig.L3NMOpenConfigServiceHandler import L3NMOpenConfigServiceHandler +from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler from .p4.p4_service_handler import P4ServiceHandler from .tapi_tapi.TapiServiceHandler import TapiServiceHandler -from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler +from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler SERVICE_HANDLERS = [ (L2NMEmulatedServiceHandler, [ @@ -50,13 +52,19 @@ SERVICE_HANDLERS = [ (TapiServiceHandler, [ { FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, - FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API, DeviceDriverEnum.DEVICEDRIVER_XR], + FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API], + } + ]), + (TapiXrServiceHandler, [ + { + FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, + FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_XR], } ]), (MicrowaveServiceHandler, [ { FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_L2NM, - FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, + FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352], } ]), (P4ServiceHandler, [ @@ -65,4 +73,10 @@ SERVICE_HANDLERS = [ FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4, } ]), + (L2NM_IETFL2VPN_ServiceHandler, [ + { + FilterFieldEnum.SERVICE_TYPE : ServiceTypeEnum.SERVICETYPE_L2NM, + FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_IETF_L2VPN], + } + ]), ] diff --git a/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py index 4eb068f7a8a7a13e006e5fc60e180b0715c72d1d..747e6c49849fe011c15d222608f14512121c4e3a 100644 --- a/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py +++ b/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py @@ -27,39 +27,45 @@ def setup_config_rules( json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value - mtu = json_settings.get('mtu', 1450 ) # 1512 + #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 #bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333 - router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' + #router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801' sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1 - vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400 + vlan_id = json_endpoint_settings.get('vlan_id', None ) # 400 #address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1' #address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30 remote_router = json_endpoint_settings.get('remote_router', '0.0.0.0') # '5.5.5.5' - circuit_id = json_endpoint_settings.get('circuit_id', '000' ) # '111' + circuit_id = json_endpoint_settings.get('circuit_id', None ) # '111' + + if vlan_id is None: vlan_id = json_settings.get('vlan_id', 1) + if circuit_id is None: circuit_id = json_settings.get('circuit_id', '000') if_cirid_name = '{:s}.{:s}'.format(endpoint_name, str(circuit_id)) network_instance_name = 'ELAN-AC:{:s}'.format(str(circuit_id)) connection_point_id = 'VC-1' json_config_rules = [ - json_config_rule_set( - '/network_instance[default]', - {'name': 'default', 'type': 'DEFAULT_INSTANCE', 'router_id': router_id}), + #json_config_rule_set( + # '/network_instance[default]', + # {'name': 'default', 'type': 'DEFAULT_INSTANCE', 'router_id': router_id}), - json_config_rule_set( - '/network_instance[default]/protocols[OSPF]', - {'name': 'default', 'identifier': 'OSPF', 'protocol_name': 'OSPF'}), + #json_config_rule_set( + # '/network_instance[default]/protocols[OSPF]', + # {'name': 'default', 'identifier': 'OSPF', 'protocol_name': 'OSPF'}), - json_config_rule_set( - '/network_instance[default]/protocols[STATIC]', - {'name': 'default', 'identifier': 'STATIC', 'protocol_name': 'STATIC'}), + #json_config_rule_set( + # '/network_instance[default]/protocols[STATIC]', + # {'name': 'default', 'identifier': 'STATIC', 'protocol_name': 'STATIC'}), json_config_rule_set( '/network_instance[{:s}]'.format(network_instance_name), @@ -72,7 +78,7 @@ def setup_config_rules( json_config_rule_set( '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_cirid_name), {'name': network_instance_name, 'id': if_cirid_name, 'interface': if_cirid_name, - 'subinterface': sub_interface_index}), + 'subinterface': sub_interface_index}), json_config_rule_set( '/network_instance[{:s}]/connection_point[{:s}]'.format(network_instance_name, connection_point_id), @@ -92,15 +98,18 @@ def teardown_config_rules( json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + #json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] #bgp_as = json_settings.get('bgp_as', 0 ) # 65000 #bgp_route_target = json_settings.get('bgp_route_target', '0:0') # 65000:333 - router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' + #router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801' sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1 #vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400 @@ -123,24 +132,24 @@ def teardown_config_rules( {'name': network_instance_name, 'id': if_cirid_name, 'interface': if_cirid_name, 'subinterface': sub_interface_index}), - json_config_rule_delete( - '/interface[{:s}]/subinterface[{:s}]'.format(if_cirid_name, sub_interface_index), - {'name': if_cirid_name, 'index': sub_interface_index}), - json_config_rule_delete( '/network_instance[{:s}]'.format(network_instance_name), {'name': network_instance_name}), json_config_rule_delete( - '/network_instance[default]/protocols[STATIC]', - {'name': 'default', 'identifier': 'STATIC', 'protocol_name': 'STATIC'}), + '/interface[{:s}]/subinterface[{:d}]'.format(if_cirid_name, sub_interface_index), + {'name': if_cirid_name, 'index': sub_interface_index}), - json_config_rule_delete( - '/network_instance[default]/protocols[OSPF]', - {'name': 'default', 'identifier': 'OSPF', 'protocol_name': 'OSPF'}), + #json_config_rule_delete( + # '/network_instance[default]/protocols[STATIC]', + # {'name': 'default', 'identifier': 'STATIC', 'protocol_name': 'STATIC'}), - json_config_rule_delete( - '/network_instance[default]', - {'name': 'default', 'type': 'DEFAULT_INSTANCE', 'router_id': router_id}), + #json_config_rule_delete( + # '/network_instance[default]/protocols[OSPF]', + # {'name': 'default', 'identifier': 'OSPF', 'protocol_name': 'OSPF'}), + + #json_config_rule_delete( + # '/network_instance[default]', + # {'name': 'default', 'type': 'DEFAULT_INSTANCE', 'router_id': router_id}), ] return json_config_rules diff --git a/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py b/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py index 748b962f66a5122b675b79f3a5ca15a73cdaf658..c5c7e407e2dabd28f8e89406627862b0d434d4b3 100644 --- a/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py +++ b/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py @@ -14,7 +14,7 @@ import json, logging from typing import Any, List, Optional, Tuple, Union -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type @@ -26,22 +26,7 @@ from .ConfigRules import setup_config_rules, teardown_config_rules LOGGER = logging.getLogger(__name__) -HISTOGRAM_BUCKETS = ( - # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - 10.0000, 25.000, 50.0000, 75.000, - 100.0, INF -) METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l2nm_emulated'}) -METRICS_POOL.get_or_create('SetEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) class L2NMEmulatedServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called @@ -82,6 +67,12 @@ class L2NMEmulatedServiceHandler(_ServiceHandler): device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) self.__task_executor.configure_device(device_obj) + if len(json_config_rules) > 0: + del device_obj.device_config.config_rules[:] + for json_config_rule in json_config_rules: + device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(device_obj) + results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint))) @@ -113,10 +104,12 @@ class L2NMEmulatedServiceHandler(_ServiceHandler): service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, settings, endpoint_settings) - del device_obj.device_config.config_rules[:] - for json_config_rule in json_config_rules: - device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device_obj) + if len(json_config_rules) > 0: + del device_obj.device_config.config_rules[:] + for json_config_rule in json_config_rules: + device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(device_obj) + results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint))) diff --git a/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py b/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py new file mode 100644 index 0000000000000000000000000000000000000000..2e832516b4e8c12028dcf82681406940b248e0f4 --- /dev/null +++ b/src/service/service/service_handlers/l2nm_ietfl2vpn/L2NM_IETFL2VPN_ServiceHandler.py @@ -0,0 +1,173 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json, logging +from typing import Any, Dict, List, Optional, Tuple, Union +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.proto.context_pb2 import ConfigRule, DeviceId, Service +from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set +from common.tools.object_factory.Device import json_device_id +from common.type_checkers.Checkers import chk_type +from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching +from service.service.service_handler_api._ServiceHandler import _ServiceHandler +from service.service.service_handler_api.SettingsHandler import SettingsHandler +from service.service.task_scheduler.TaskExecutor import TaskExecutor + +LOGGER = logging.getLogger(__name__) + +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l2nm_ietf_l2vpn'}) + +class L2NM_IETFL2VPN_ServiceHandler(_ServiceHandler): + def __init__( # pylint: disable=super-init-not-called + self, service : Service, task_executor : TaskExecutor, **settings + ) -> None: + self.__service = service + self.__task_executor = task_executor + self.__settings_handler = SettingsHandler(service.service_config, **settings) + + @metered_subclass_method(METRICS_POOL) + def SetEndpoint( + self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None + ) -> List[Union[bool, Exception]]: + + chk_type('endpoints', endpoints, list) + if len(endpoints) < 2: return [] + + service_uuid = self.__service.service_id.service_uuid.uuid + settings = self.__settings_handler.get('/settings') + json_settings : Dict = {} if settings is None else settings.value + encap_type = json_settings.get('encapsulation_type', '') + vlan_id = json_settings.get('vlan_id', 100) + + results = [] + try: + src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0]) + src_device = self.__task_executor.get_device(DeviceId(**json_device_id(src_device_uuid))) + src_endpoint = get_endpoint_matching(src_device, src_endpoint_uuid) + src_controller = self.__task_executor.get_device_controller(src_device) + + dst_device_uuid, dst_endpoint_uuid = get_device_endpoint_uuids(endpoints[-1]) + dst_device = self.__task_executor.get_device(DeviceId(**json_device_id(dst_device_uuid))) + dst_endpoint = get_endpoint_matching(dst_device, dst_endpoint_uuid) + dst_controller = self.__task_executor.get_device_controller(dst_device) + + if src_controller.device_id.device_uuid.uuid != dst_controller.device_id.device_uuid.uuid: + raise Exception('Different Src-Dst devices not supported by now') + controller = src_controller + + json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { + 'uuid' : service_uuid, + 'src_device_name' : src_device.name, + 'src_endpoint_name' : src_endpoint.name, + 'dst_device_name' : dst_device.name, + 'dst_endpoint_name' : dst_endpoint.name, + 'encapsulation_type': encap_type, + 'vlan_id' : vlan_id, + }) + del controller.device_config.config_rules[:] + controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(controller) + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to SetEndpoint for Service({:s})'.format(str(service_uuid))) + results.append(e) + + return results + + @metered_subclass_method(METRICS_POOL) + def DeleteEndpoint( + self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None + ) -> List[Union[bool, Exception]]: + + chk_type('endpoints', endpoints, list) + if len(endpoints) < 2: return [] + + service_uuid = self.__service.service_id.service_uuid.uuid + + results = [] + try: + src_device_uuid, _ = get_device_endpoint_uuids(endpoints[0]) + src_device = self.__task_executor.get_device(DeviceId(**json_device_id(src_device_uuid))) + src_controller = self.__task_executor.get_device_controller(src_device) + + dst_device_uuid, _ = get_device_endpoint_uuids(endpoints[1]) + dst_device = self.__task_executor.get_device(DeviceId(**json_device_id(dst_device_uuid))) + dst_controller = self.__task_executor.get_device_controller(dst_device) + + if src_controller.device_id.device_uuid.uuid != dst_controller.device_id.device_uuid.uuid: + raise Exception('Different Src-Dst devices not supported by now') + controller = src_controller + + json_config_rule = json_config_rule_delete('/services/service[{:s}]'.format(service_uuid), { + 'uuid': service_uuid + }) + del controller.device_config.config_rules[:] + controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(controller) + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to DeleteEndpoint for Service({:s})'.format(str(service_uuid))) + results.append(e) + + return results + + @metered_subclass_method(METRICS_POOL) + def SetConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('constraints', constraints, list) + if len(constraints) == 0: return [] + + msg = '[SetConstraint] Method not implemented. Constraints({:s}) are being ignored.' + LOGGER.warning(msg.format(str(constraints))) + return [True for _ in range(len(constraints))] + + @metered_subclass_method(METRICS_POOL) + def DeleteConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('constraints', constraints, list) + if len(constraints) == 0: return [] + + msg = '[DeleteConstraint] Method not implemented. Constraints({:s}) are being ignored.' + LOGGER.warning(msg.format(str(constraints))) + return [True for _ in range(len(constraints))] + + @metered_subclass_method(METRICS_POOL) + def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('resources', resources, list) + if len(resources) == 0: return [] + + results = [] + for resource in resources: + try: + resource_value = json.loads(resource[1]) + self.__settings_handler.set(resource[0], resource_value) + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to SetConfig({:s})'.format(str(resource))) + results.append(e) + + return results + + @metered_subclass_method(METRICS_POOL) + def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('resources', resources, list) + if len(resources) == 0: return [] + + results = [] + for resource in resources: + try: + self.__settings_handler.delete(resource[0]) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to DeleteConfig({:s})'.format(str(resource))) + results.append(e) + + return results diff --git a/src/opticalattackmitigator/proto/__init__.py b/src/service/service/service_handlers/l2nm_ietfl2vpn/__init__.py similarity index 100% rename from src/opticalattackmitigator/proto/__init__.py rename to src/service/service/service_handlers/l2nm_ietfl2vpn/__init__.py diff --git a/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py b/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py index 92b93ba277b1cec37e909628fb0e470a4960e667..69354ff759338a03f52587ff2abb5da4ea3ab232 100644 --- a/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py +++ b/src/service/service/service_handlers/l2nm_openconfig/ConfigRules.py @@ -20,11 +20,11 @@ def setup_config_rules( service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str, service_settings : TreeNode, endpoint_settings : TreeNode, endpoint_acls : List [Tuple] ) -> List[Dict]: - + if service_settings is None: return [] if endpoint_settings is None: return [] - json_settings : Dict = service_settings.value + #json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value json_settings : Dict = {} if service_settings is None else service_settings.value @@ -55,34 +55,24 @@ def setup_config_rules( connection_point_id = 'VC-1' #Uso provisional json_config_rules = [ - + json_config_rule_set( '/network_instance[{:s}]'.format(network_instance_name), - {'name': network_instance_name, - 'type': 'L2VSI'}), + {'name': network_instance_name, 'type': 'L2VSI'}), json_config_rule_set( - '/interface[{:s}]/subinterface[0]'.format(if_cirid_name), - {'name': if_cirid_name, - 'type': 'l2vlan', - 'index': sub_interface_index, - 'vlan_id': vlan_id}), + '/interface[{:s}]/subinterface[{:d}]'.format(if_cirid_name, sub_interface_index), + {'name': if_cirid_name, 'type': 'l2vlan', 'index': sub_interface_index, 'vlan_id': vlan_id}), json_config_rule_set( '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_cirid_name), - {'name': network_instance_name, - 'id': if_cirid_name, - 'interface': if_cirid_name, - 'subinterface': 0 - }), + {'name': network_instance_name, 'id': if_cirid_name, 'interface': if_cirid_name, + 'subinterface': sub_interface_index}), json_config_rule_set( '/network_instance[{:s}]/connection_point[{:s}]'.format(network_instance_name, connection_point_id), - {'name': network_instance_name, - 'connection_point': connection_point_id, - 'VC_ID': circuit_id, - 'remote_system': remote_router - }), + {'name': network_instance_name, 'connection_point': connection_point_id, 'VC_ID': circuit_id, + 'remote_system': remote_router}), ] for res_key, res_value in endpoint_acls: json_config_rules.append( @@ -95,8 +85,11 @@ def teardown_config_rules( service_settings : TreeNode, endpoint_settings : TreeNode ) -> List[Dict]: - #json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + if service_settings is None: return [] + if endpoint_settings is None: return [] + + #json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] @@ -105,7 +98,7 @@ def teardown_config_rules( #router_id = json_endpoint_settings.get('router_id', '0.0.0.0') # '10.95.0.10' #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0' ) # '60001:801' - #sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1 + sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0 ) # 1 #vlan_id = json_endpoint_settings.get('vlan_id', 1 ) # 400 #address_ip = json_endpoint_settings.get('address_ip', '0.0.0.0') # '2.2.2.1' #address_prefix = json_endpoint_settings.get('address_prefix', 24 ) # 30 @@ -114,17 +107,26 @@ def teardown_config_rules( if_cirid_name = '{:s}.{:s}'.format(endpoint_name, str(circuit_id)) network_instance_name = 'ELAN-AC:{:s}'.format(str(circuit_id)) - #connection_point_id = 'VC-1' + connection_point_id = 'VC-1' json_config_rules = [ + + #json_config_rule_delete( + # '/network_instance[{:s}]/connection_point[{:s}]'.format(network_instance_name, connection_point_id), + # {'name': network_instance_name, 'connection_point': connection_point_id, 'VC_ID': circuit_id}), + + #json_config_rule_delete( + # '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_cirid_name), + # {'name': network_instance_name, 'id': if_cirid_name, 'interface': if_cirid_name, + # 'subinterface': sub_interface_index}), + json_config_rule_delete( '/network_instance[{:s}]'.format(network_instance_name), {'name': network_instance_name}), - + json_config_rule_delete( - '/interface[{:s}]/subinterface[0]'.format(if_cirid_name),{ - 'name': if_cirid_name, - }), - + '/interface[{:s}]/subinterface[{:d}]'.format(if_cirid_name, sub_interface_index), + {'name': if_cirid_name, 'index': sub_interface_index}), + ] return json_config_rules diff --git a/src/service/service/service_handlers/l2nm_openconfig/L2NMOpenConfigServiceHandler.py b/src/service/service/service_handlers/l2nm_openconfig/L2NMOpenConfigServiceHandler.py index 467f4e4c842ecdfb5f9e3410c47d4334ee1cb9bb..6f7f05db5ceed0a2b9146f9275e1619131d77278 100644 --- a/src/service/service/service_handlers/l2nm_openconfig/L2NMOpenConfigServiceHandler.py +++ b/src/service/service/service_handlers/l2nm_openconfig/L2NMOpenConfigServiceHandler.py @@ -14,7 +14,7 @@ import json, logging from typing import Any, List, Optional, Tuple, Union -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type @@ -26,22 +26,7 @@ from .ConfigRules import setup_config_rules, teardown_config_rules LOGGER = logging.getLogger(__name__) -HISTOGRAM_BUCKETS = ( - # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - 10.0000, 25.000, 50.0000, 75.000, - 100.0, INF -) METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l2nm_openconfig'}) -METRICS_POOL.get_or_create('SetEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) class L2NMOpenConfigServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called diff --git a/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py index 2e1a0859de80cb6e1347bd02d876ec4cd6a2bff7..25fe9ca30db118f2c36e7e21a8b2e91f19ab76d9 100644 --- a/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py +++ b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py @@ -27,9 +27,6 @@ def setup_config_rules( json_settings : Dict = service_settings.value json_endpoint_settings : Dict = endpoint_settings.value - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value - service_short_uuid = service_uuid.split('-')[-1] network_instance_name = '{:s}-NetInst'.format(service_short_uuid) network_interface_desc = '{:s}-NetIf'.format(service_uuid) @@ -151,8 +148,8 @@ def teardown_config_rules( if service_settings is None: return [] if endpoint_settings is None: return [] - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value #mtu = json_settings.get('mtu', 1450 ) # 1512 #address_families = json_settings.get('address_families', [] ) # ['IPV4'] diff --git a/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py b/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py index 47de9c94fbb8a5ddac848336c2ed7936d0126b45..de02a43caffd91ae047bd73d319e969af6265c5c 100644 --- a/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py +++ b/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py @@ -14,7 +14,7 @@ import json, logging from typing import Any, List, Optional, Tuple, Union -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type @@ -26,22 +26,7 @@ from .ConfigRules import setup_config_rules, teardown_config_rules LOGGER = logging.getLogger(__name__) -HISTOGRAM_BUCKETS = ( - # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - 10.0000, 25.000, 50.0000, 75.000, - 100.0, INF -) METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l3nm_emulated'}) -METRICS_POOL.get_or_create('SetEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) class L3NMEmulatedServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called @@ -75,10 +60,12 @@ class L3NMEmulatedServiceHandler(_ServiceHandler): service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, settings, endpoint_settings) - del device_obj.device_config.config_rules[:] - for json_config_rule in json_config_rules: - device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device_obj) + if len(json_config_rules) > 0: + del device_obj.device_config.config_rules[:] + for json_config_rule in json_config_rules: + device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(device_obj) + results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint))) @@ -110,10 +97,12 @@ class L3NMEmulatedServiceHandler(_ServiceHandler): service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name, settings, endpoint_settings) - del device_obj.device_config.config_rules[:] - for json_config_rule in json_config_rules: - device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device_obj) + if len(json_config_rules) > 0: + del device_obj.device_config.config_rules[:] + for json_config_rule in json_config_rules: + device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(device_obj) + results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint))) diff --git a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py index e98dd57904bfb99694715fa053cfc63e8ef85963..b2ae12c31e90f8c42a44e4492d77cdf565cf2769 100644 --- a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py +++ b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py @@ -203,8 +203,8 @@ def teardown_config_rules( if service_settings is None: return [] if endpoint_settings is None: return [] - json_settings : Dict = {} if service_settings is None else service_settings.value - json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value + json_settings : Dict = service_settings.value + json_endpoint_settings : Dict = endpoint_settings.value service_short_uuid = service_uuid.split('-')[-1] network_instance_name = '{:s}-NetInst'.format(service_short_uuid) diff --git a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py index eae2f3cbec0cad805c44b338bfbac3fb06cb84b3..3f8a6d9dd445fb4e5b9f051ac117ca71655446e3 100644 --- a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py +++ b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py @@ -14,7 +14,7 @@ import json, logging from typing import Any, List, Optional, Tuple, Union -from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type @@ -26,22 +26,7 @@ from .ConfigRules import setup_config_rules, teardown_config_rules LOGGER = logging.getLogger(__name__) -HISTOGRAM_BUCKETS = ( - # .005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, INF - 0.0010, 0.0025, 0.0050, 0.0075, - 0.0100, 0.0250, 0.0500, 0.0750, - 0.1000, 0.2500, 0.5000, 0.7500, - 1.0000, 2.5000, 5.0000, 7.5000, - 10.0000, 25.000, 50.0000, 75.000, - 100.0, INF -) METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'l3nm_openconfig'}) -METRICS_POOL.get_or_create('SetEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteEndpoint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConstraint', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('SetConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) -METRICS_POOL.get_or_create('DeleteConfig', MetricTypeEnum.HISTOGRAM_DURATION, buckets=HISTOGRAM_BUCKETS) class L3NMOpenConfigServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called diff --git a/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py b/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py index ee64d2fa4ff0110aea9ee4beee97fa83915ab57d..40c87eeee2c8dd1ddd5a39162f8ff7f117344e3b 100644 --- a/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py +++ b/src/service/service/service_handlers/microwave/MicrowaveServiceHandler.py @@ -61,7 +61,7 @@ class MicrowaveServiceHandler(_ServiceHandler): device_uuid_dst, endpoint_uuid_dst = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) @@ -106,7 +106,7 @@ class MicrowaveServiceHandler(_ServiceHandler): device_uuid_dst, _ = get_device_endpoint_uuids(endpoints[1]) if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') + raise Exception('Different Src-Dst devices not supported by now') device_uuid = device_uuid_src device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) diff --git a/src/service/service/service_handlers/p4/p4_service_handler.py b/src/service/service/service_handlers/p4/p4_service_handler.py index 6f2cfb5a9bc4dac991eecd14ba7b6eb1218bdaa2..41cfcc5952601a16a13cd691f2e424017936aaa3 100644 --- a/src/service/service/service_handlers/p4/p4_service_handler.py +++ b/src/service/service/service_handlers/p4/p4_service_handler.py @@ -16,18 +16,20 @@ P4 service handler for the TeraFlowSDN controller. """ -import anytree, json, logging -from typing import Any, Dict, List, Optional, Tuple, Union -from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, DeviceId, Service -from common.tools.object_factory.ConfigRule import json_config_rule, json_config_rule_delete, json_config_rule_set +import logging +from typing import Any, List, Optional, Tuple, Union +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.proto.context_pb2 import ConfigRule, DeviceId, Service +from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set from common.tools.object_factory.Device import json_device_id -from common.type_checkers.Checkers import chk_type, chk_length +from common.type_checkers.Checkers import chk_type from service.service.service_handler_api._ServiceHandler import _ServiceHandler -from service.service.service_handler_api.AnyTreeTools import TreeNode, delete_subnode, get_subnode, set_subnode_value from service.service.task_scheduler.TaskExecutor import TaskExecutor LOGGER = logging.getLogger(__name__) +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4'}) + def create_rule_set(endpoint_a, endpoint_b): return json_config_rule_set( 'table', @@ -99,6 +101,7 @@ class P4ServiceHandler(_ServiceHandler): self.__service = service self.__task_executor = task_executor # pylint: disable=unused-private-member + @metered_subclass_method(METRICS_POOL) def SetEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None @@ -169,6 +172,7 @@ class P4ServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def DeleteEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None @@ -239,6 +243,7 @@ class P4ServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def SetConstraint(self, constraints: List[Tuple[str, Any]]) \ -> List[Union[bool, Exception]]: """ Create/Update service constraints. @@ -261,6 +266,7 @@ class P4ServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(constraints))) return [True for _ in range(len(constraints))] + @metered_subclass_method(METRICS_POOL) def DeleteConstraint(self, constraints: List[Tuple[str, Any]]) \ -> List[Union[bool, Exception]]: """ Delete service constraints. @@ -285,6 +291,7 @@ class P4ServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(constraints))) return [True for _ in range(len(constraints))] + @metered_subclass_method(METRICS_POOL) def SetConfig(self, resources: List[Tuple[str, Any]]) \ -> List[Union[bool, Exception]]: """ Create/Update configuration for a list of service resources. @@ -308,6 +315,7 @@ class P4ServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(resources))) return [True for _ in range(len(resources))] + @metered_subclass_method(METRICS_POOL) def DeleteConfig(self, resources: List[Tuple[str, Any]]) \ -> List[Union[bool, Exception]]: """ Delete configuration for a list of service resources. diff --git a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py index 8abd12b2a24c49a6c5e50cebe7a2d65dc7ce4eb1..af7d4bc949fc98f057ade66b58d8b9b38e0707ed 100644 --- a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py +++ b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py @@ -19,7 +19,7 @@ from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type -from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching +from service.service.service_handler_api.Tools import get_device_endpoint_uuids from service.service.service_handler_api._ServiceHandler import _ServiceHandler from service.service.service_handler_api.SettingsHandler import SettingsHandler from service.service.task_scheduler.TaskExecutor import TaskExecutor @@ -42,7 +42,7 @@ class TapiServiceHandler(_ServiceHandler): ) -> List[Union[bool, Exception]]: chk_type('endpoints', endpoints, list) - if len(endpoints) != 2: return [] + if len(endpoints) < 2: return [] service_uuid = self.__service.service_id.service_uuid.uuid settings = self.__settings_handler.get('/settings') @@ -55,30 +55,33 @@ class TapiServiceHandler(_ServiceHandler): results = [] try: - device_uuid_src, endpoint_uuid_src = get_device_endpoint_uuids(endpoints[0]) - device_uuid_dst, endpoint_uuid_dst = get_device_endpoint_uuids(endpoints[1]) + src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[0]) + src_device = self.__task_executor.get_device(DeviceId(**json_device_id(src_device_uuid))) + src_controller = self.__task_executor.get_device_controller(src_device) + if src_controller is None: src_controller = src_device - if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') - device_uuid = device_uuid_src + dst_device_uuid, dst_endpoint_uuid = get_device_endpoint_uuids(endpoints[-1]) + dst_device = self.__task_executor.get_device(DeviceId(**json_device_id(dst_device_uuid))) + dst_controller = self.__task_executor.get_device_controller(dst_device) + if dst_controller is None: dst_controller = dst_device - device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - endpoint_name_src = get_endpoint_matching(device_obj, endpoint_uuid_src).name - endpoint_name_dst = get_endpoint_matching(device_obj, endpoint_uuid_dst).name + if src_controller.device_id.device_uuid.uuid != dst_controller.device_id.device_uuid.uuid: + raise Exception('Different Src-Dst devices not supported by now') + controller = src_controller json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { 'uuid' : service_uuid, - 'input_sip' : endpoint_name_src, - 'output_sip' : endpoint_name_dst, + 'input_sip_uuid' : src_endpoint_uuid, + 'output_sip_uuid' : dst_endpoint_uuid, 'capacity_unit' : capacity_unit, 'capacity_value' : capacity_value, 'layer_protocol_name' : layer_proto_name, 'layer_protocol_qualifier': layer_proto_qual, 'direction' : direction, }) - del device_obj.device_config.config_rules[:] - device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device_obj) + del controller.device_config.config_rules[:] + controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(controller) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to SetEndpoint for Service({:s})'.format(str(service_uuid))) @@ -92,27 +95,32 @@ class TapiServiceHandler(_ServiceHandler): ) -> List[Union[bool, Exception]]: chk_type('endpoints', endpoints, list) - if len(endpoints) != 2: return [] + if len(endpoints) < 2: return [] service_uuid = self.__service.service_id.service_uuid.uuid results = [] try: - device_uuid_src, _ = get_device_endpoint_uuids(endpoints[0]) - device_uuid_dst, _ = get_device_endpoint_uuids(endpoints[1]) + src_device_uuid, _ = get_device_endpoint_uuids(endpoints[0]) + src_device = self.__task_executor.get_device(DeviceId(**json_device_id(src_device_uuid))) + src_controller = self.__task_executor.get_device_controller(src_device) + if src_controller is None: src_controller = src_device - if device_uuid_src != device_uuid_dst: - raise Exception('Diferent Src-Dst devices not supported by now') - device_uuid = device_uuid_src + dst_device_uuid, _ = get_device_endpoint_uuids(endpoints[1]) + dst_device = self.__task_executor.get_device(DeviceId(**json_device_id(dst_device_uuid))) + dst_controller = self.__task_executor.get_device_controller(dst_device) + if dst_controller is None: dst_controller = dst_device - device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) + if src_controller.device_id.device_uuid.uuid != dst_controller.device_id.device_uuid.uuid: + raise Exception('Different Src-Dst devices not supported by now') + controller = src_controller json_config_rule = json_config_rule_delete('/services/service[{:s}]'.format(service_uuid), { 'uuid': service_uuid }) - del device_obj.device_config.config_rules[:] - device_obj.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device_obj) + del controller.device_config.config_rules[:] + controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(controller) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteEndpoint for Service({:s})'.format(str(service_uuid))) diff --git a/src/service/service/service_handlers/tapi_xr/TapiXrServiceHandler.py b/src/service/service/service_handlers/tapi_xr/TapiXrServiceHandler.py new file mode 100644 index 0000000000000000000000000000000000000000..a79ebb82d6cb57967e96b70e0144fd410f8666b0 --- /dev/null +++ b/src/service/service/service_handlers/tapi_xr/TapiXrServiceHandler.py @@ -0,0 +1,190 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 json, logging +from typing import Any, Dict, List, Optional, Tuple, Union +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.proto.context_pb2 import ConfigRule, DeviceId, Service +from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set +from common.tools.object_factory.Device import json_device_id +from common.type_checkers.Checkers import chk_type +from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching +from service.service.service_handler_api._ServiceHandler import _ServiceHandler +from service.service.service_handler_api.SettingsHandler import SettingsHandler +from service.service.task_scheduler.TaskExecutor import TaskExecutor + +LOGGER = logging.getLogger(__name__) + +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'tapi_xr'}) + +class TapiXrServiceHandler(_ServiceHandler): + def __init__( # pylint: disable=super-init-not-called + self, service : Service, task_executor : TaskExecutor, **settings + ) -> None: + self.__service = service + self.__task_executor = task_executor + self.__settings_handler = SettingsHandler(service.service_config, **settings) + + @metered_subclass_method(METRICS_POOL) + def SetEndpoint( + self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None + ) -> List[Union[bool, Exception]]: + + chk_type('endpoints', endpoints, list) + + # When using regular mode where XR constellation is a single device, we get two endpoints. + # Convert that representation to a form that is understood by the service handler that + # expects constellation to be represented as multiple devices. + if len(endpoints) == 2: + endpoints = [None, endpoints[0], endpoints[1], None] + + if len(endpoints) != 4: return [] + + service_uuid = self.__service.service_id.service_uuid.uuid + settings = self.__settings_handler.get('/settings') + json_settings : Dict = {} if settings is None else settings.value + capacity_value = json_settings.get('capacity_value', 50.0) + capacity_unit = json_settings.get('capacity_unit', 'GHz') + + results = [] + try: + src_device_uuid, src_endpoint_uuid = get_device_endpoint_uuids(endpoints[1]) + src_device = self.__task_executor.get_device(DeviceId(**json_device_id(src_device_uuid))) + src_endpoint = get_endpoint_matching(src_device, src_endpoint_uuid) + src_controller = self.__task_executor.get_device_controller(src_device) + if src_controller is None: src_controller = src_device + + dst_device_uuid, dst_endpoint_uuid = get_device_endpoint_uuids(endpoints[2]) + dst_device = self.__task_executor.get_device(DeviceId(**json_device_id(dst_device_uuid))) + dst_endpoint = get_endpoint_matching(dst_device, dst_endpoint_uuid) + dst_controller = self.__task_executor.get_device_controller(dst_device) + if dst_controller is None: dst_controller = dst_device + + if src_controller.device_id.device_uuid.uuid != dst_controller.device_id.device_uuid.uuid: + raise Exception('Different Src-Dst devices not supported by now') + controller = src_controller + + # If the special mode that splits XR constellation to multiple modelled devices is used, + # add the device name to interface name. Otherwise use it as is (it will already contain pipe character + # end edge device name). This code should be refactored, as interface name structure is internal matter + # to XR driver and subject to change. + constellation_unique_src = src_endpoint.name if "|" in src_endpoint.name else '|'.join([src_device.name, src_endpoint.name]) + constellation_unique_dst = dst_endpoint.name if "|" in dst_endpoint.name else '|'.join([dst_device.name, dst_endpoint.name]) + + json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { + 'uuid' : service_uuid, + 'input_sip_name' : constellation_unique_src, + 'output_sip_name': constellation_unique_dst, + 'capacity_unit' : capacity_unit, + 'capacity_value' : capacity_value, + }) + + del controller.device_config.config_rules[:] + controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(controller) + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to SetEndpoint for Service({:s})'.format(str(service_uuid))) + results.append(e) + + return results + + @metered_subclass_method(METRICS_POOL) + def DeleteEndpoint( + self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None + ) -> List[Union[bool, Exception]]: + + chk_type('endpoints', endpoints, list) + if len(endpoints) < 2: return [] + + service_uuid = self.__service.service_id.service_uuid.uuid + + results = [] + try: + src_device_uuid, _ = get_device_endpoint_uuids(endpoints[0]) + src_device = self.__task_executor.get_device(DeviceId(**json_device_id(src_device_uuid))) + src_controller = self.__task_executor.get_device_controller(src_device) + if src_controller is None: src_controller = src_device + + dst_device_uuid, _ = get_device_endpoint_uuids(endpoints[1]) + dst_device = self.__task_executor.get_device(DeviceId(**json_device_id(dst_device_uuid))) + dst_controller = self.__task_executor.get_device_controller(dst_device) + if dst_controller is None: dst_controller = dst_device + + if src_controller.device_id.device_uuid.uuid != dst_controller.device_id.device_uuid.uuid: + raise Exception('Different Src-Dst devices not supported by now') + controller = src_controller + + json_config_rule = json_config_rule_delete('/services/service[{:s}]'.format(service_uuid), { + 'uuid': service_uuid + }) + del controller.device_config.config_rules[:] + controller.device_config.config_rules.append(ConfigRule(**json_config_rule)) + self.__task_executor.configure_device(controller) + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to DeleteEndpoint for Service({:s})'.format(str(service_uuid))) + results.append(e) + + return results + + @metered_subclass_method(METRICS_POOL) + def SetConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('constraints', constraints, list) + if len(constraints) == 0: return [] + + msg = '[SetConstraint] Method not implemented. Constraints({:s}) are being ignored.' + LOGGER.warning(msg.format(str(constraints))) + return [True for _ in range(len(constraints))] + + @metered_subclass_method(METRICS_POOL) + def DeleteConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('constraints', constraints, list) + if len(constraints) == 0: return [] + + msg = '[DeleteConstraint] Method not implemented. Constraints({:s}) are being ignored.' + LOGGER.warning(msg.format(str(constraints))) + return [True for _ in range(len(constraints))] + + @metered_subclass_method(METRICS_POOL) + def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('resources', resources, list) + if len(resources) == 0: return [] + + results = [] + for resource in resources: + try: + resource_value = json.loads(resource[1]) + self.__settings_handler.set(resource[0], resource_value) + results.append(True) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to SetConfig({:s})'.format(str(resource))) + results.append(e) + + return results + + @metered_subclass_method(METRICS_POOL) + def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: + chk_type('resources', resources, list) + if len(resources) == 0: return [] + + results = [] + for resource in resources: + try: + self.__settings_handler.delete(resource[0]) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Unable to DeleteConfig({:s})'.format(str(resource))) + results.append(e) + + return results diff --git a/src/opticalcentralizedattackdetector/__init__.py b/src/service/service/service_handlers/tapi_xr/__init__.py similarity index 100% rename from src/opticalcentralizedattackdetector/__init__.py rename to src/service/service/service_handlers/tapi_xr/__init__.py diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 932c56e2b1934e12e7849a60c22d3ca1be7f8093..ae0f1be7da291a5dc025641cb606f7a7706059ca 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -12,19 +12,28 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging #, json from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Optional, Union from common.method_wrappers.ServiceExceptions import NotFoundException -from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceId, Service, ServiceId +from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceDriverEnum, DeviceId, Service, ServiceId +from common.tools.context_queries.Connection import get_connection_by_id +from common.tools.context_queries.Device import get_device +from common.tools.context_queries.Service import get_service_by_id +from common.tools.grpc.Tools import grpc_message_to_json_string +from common.tools.object_factory.Device import json_device_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient +from service.service.service_handler_api.Exceptions import ( + UnsatisfiedFilterException, UnsupportedFilterFieldException, UnsupportedFilterFieldValueException) from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory, get_service_handler_class -from service.service.tools.ContextGetters import get_connection, get_device, get_service from service.service.tools.ObjectKeys import get_connection_key, get_device_key, get_service_key if TYPE_CHECKING: from service.service.service_handler_api._ServiceHandler import _ServiceHandler +LOGGER = logging.getLogger(__name__) + CacheableObject = Union[Connection, Device, Service] class CacheableObjectType(Enum): @@ -70,7 +79,7 @@ class TaskExecutor: connection_key = get_connection_key(connection_id) connection = self._load_grpc_object(CacheableObjectType.CONNECTION, connection_key) if connection is None: - connection = get_connection(self._context_client, connection_id) + connection = get_connection_by_id(self._context_client, connection_id) if connection is None: raise NotFoundException('Connection', connection_key) connection : Connection = self._store_editable_grpc_object( CacheableObjectType.CONNECTION, connection_key, Connection, connection) @@ -92,7 +101,7 @@ class TaskExecutor: device_key = get_device_key(device_id) device = self._load_grpc_object(CacheableObjectType.DEVICE, device_key) if device is None: - device = get_device(self._context_client, device_id) + device = get_device(self._context_client, device_id.device_uuid.uuid) if device is None: raise NotFoundException('Device', device_key) device : Device = self._store_editable_grpc_object( CacheableObjectType.DEVICE, device_key, Device, device) @@ -103,13 +112,40 @@ class TaskExecutor: self._device_client.ConfigureDevice(device) self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device) - def get_devices_from_connection(self, connection : Connection) -> Dict[str, Device]: + def get_device_controller(self, device : Device) -> Optional[Device]: + #json_controller = None + #for config_rule in device.device_config.config_rules: + # if config_rule.WhichOneof('config_rule') != 'custom': continue + # if config_rule.custom.resource_key != '_controller': continue + # json_controller = json.loads(config_rule.custom.resource_value) + # break + + #if json_controller is None: return None + + #controller_uuid = json_controller['uuid'] + controller_uuid = device.controller_id.device_uuid.uuid + if len(controller_uuid) == 0: return None + controller = self.get_device(DeviceId(**json_device_id(controller_uuid))) + controller_uuid = controller.device_id.device_uuid.uuid + if controller is None: raise Exception('Device({:s}) not found'.format(str(controller_uuid))) + return controller + + def get_devices_from_connection( + self, connection : Connection, exclude_managed_by_controller : bool = False + ) -> Dict[str, Device]: devices = dict() for endpoint_id in connection.path_hops_endpoint_ids: device = self.get_device(endpoint_id.device_id) device_uuid = endpoint_id.device_id.device_uuid.uuid if device is None: raise Exception('Device({:s}) not found'.format(str(device_uuid))) - devices[device_uuid] = device + + controller = self.get_device_controller(device) + if controller is None: + devices[device_uuid] = device + else: + if not exclude_managed_by_controller: + devices[device_uuid] = device + devices[controller.device_id.device_uuid.uuid] = controller return devices # ----- Service-related methods ------------------------------------------------------------------------------------ @@ -118,7 +154,7 @@ class TaskExecutor: service_key = get_service_key(service_id) service = self._load_grpc_object(CacheableObjectType.SERVICE, service_key) if service is None: - service = get_service(self._context_client, service_id) + service = get_service_by_id(self._context_client, service_id) if service is None: raise NotFoundException('Service', service_key) service : service = self._store_editable_grpc_object( CacheableObjectType.SERVICE, service_key, Service, service) @@ -139,6 +175,22 @@ class TaskExecutor: def get_service_handler( self, connection : Connection, service : Service, **service_handler_settings ) -> '_ServiceHandler': - connection_devices = self.get_devices_from_connection(connection) - service_handler_class = get_service_handler_class(self._service_handler_factory, service, connection_devices) - return service_handler_class(service, self, **service_handler_settings) + connection_devices = self.get_devices_from_connection(connection, exclude_managed_by_controller=True) + try: + service_handler_class = get_service_handler_class( + self._service_handler_factory, service, connection_devices) + return service_handler_class(service, self, **service_handler_settings) + except (UnsatisfiedFilterException, UnsupportedFilterFieldException, UnsupportedFilterFieldValueException): + dict_connection_devices = { + cd_data.name : (cd_uuid, cd_data.name, { + (device_driver, DeviceDriverEnum.Name(device_driver)) + for device_driver in cd_data.device_drivers + }) + for cd_uuid,cd_data in connection_devices.items() + } + LOGGER.exception( + 'Unable to select service handler. service={:s} connection={:s} connection_devices={:s}'.format( + grpc_message_to_json_string(service), grpc_message_to_json_string(connection), + str(dict_connection_devices) + ) + ) diff --git a/src/service/service/task_scheduler/TaskScheduler.py b/src/service/service/task_scheduler/TaskScheduler.py index fbc554aa261cbc68009258d322aa01d52bfe760d..fceed36e92771394dff9e9f45ef928a0175b8d32 100644 --- a/src/service/service/task_scheduler/TaskScheduler.py +++ b/src/service/service/task_scheduler/TaskScheduler.py @@ -198,15 +198,57 @@ class TasksScheduler: t1 = time.time() LOGGER.debug('[compose_from_service] elapsed_time: {:f} sec'.format(t1-t0)) + def compose_service_connection_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_ConnectionDeconfigure( + self._executor, old_connection.connection_id)) + + new_connection_configure_key = self._add_task_if_not_exists(Task_ConnectionConfigure( + 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('[compose_service_connection_update] elapsed_time: {:f} sec'.format(t1-t0)) + def execute_all(self, dry_run : bool = False) -> None: ordered_task_keys = list(self._dag.static_order()) LOGGER.debug('[execute_all] ordered_task_keys={:s}'.format(str(ordered_task_keys))) results = [] for task_key in ordered_task_keys: + str_task_name = ('DRY ' if dry_run else '') + str(task_key) + LOGGER.debug('[execute_all] starting task {:s}'.format(str_task_name)) 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_all] results={:s}'.format(str(results))) return zip(ordered_task_keys, results) diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py index 5a47005b304836050dd8c0882214dd9cebd5d8b5..4367ffdee4d6d5b9edfc9fd30d0d6b6f48da8a75 100644 --- a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py +++ b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py @@ -32,7 +32,7 @@ class Task_ConnectionConfigure(_Task): def connection_id(self) -> ConnectionId: return self._connection_id @staticmethod - def build_key(connection_id : ConnectionId) -> str: + def build_key(connection_id : ConnectionId) -> str: # pylint: disable=arguments-differ str_connection_id = get_connection_key(connection_id) return KEY_TEMPLATE.format(connection_id=str_connection_id) diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py index 5736054febd2fb9e8a36b5a2235ca3f412e0e174..70f41566ef5e69605a527cc0392b77acb866ec2c 100644 --- a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py +++ b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py @@ -32,7 +32,7 @@ class Task_ConnectionDeconfigure(_Task): def connection_id(self) -> ConnectionId: return self._connection_id @staticmethod - def build_key(connection_id : ConnectionId) -> str: + def build_key(connection_id : ConnectionId) -> str: # pylint: disable=arguments-differ str_connection_id = get_connection_key(connection_id) return KEY_TEMPLATE.format(connection_id=str_connection_id) diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py index 6a4e11b540cd9b85028d92cf86899ee098056c36..0f021b6ca65da1c6b5e44d8577bf9dd6875eb17a 100644 --- a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py +++ b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py @@ -28,7 +28,7 @@ class Task_ServiceDelete(_Task): def service_id(self) -> ServiceId: return self._service_id @staticmethod - def build_key(service_id : ServiceId) -> str: + def build_key(service_id : ServiceId) -> str: # pylint: disable=arguments-differ str_service_id = get_service_key(service_id) return KEY_TEMPLATE.format(service_id=str_service_id) diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py index 815cb33c3d540755704153b661e889fc2660d268..d5360fe85eae68085298406fc0ed19dd105f187e 100644 --- a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py +++ b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py @@ -32,7 +32,7 @@ class Task_ServiceSetStatus(_Task): def new_status(self) -> ServiceStatusEnum: return self._new_status @staticmethod - def build_key(service_id : ServiceId, new_status : ServiceStatusEnum) -> str: + def build_key(service_id : ServiceId, new_status : ServiceStatusEnum) -> str: # pylint: disable=arguments-differ str_service_id = get_service_key(service_id) str_new_status = ServiceStatusEnum.Name(new_status) return KEY_TEMPLATE.format(service_id=str_service_id, new_status=str_new_status) diff --git a/src/service/service/tools/ConnectionToString.py b/src/service/service/tools/ConnectionToString.py new file mode 100644 index 0000000000000000000000000000000000000000..1c189e00ff9004dc0929f58a02560e8bea69fa91 --- /dev/null +++ b/src/service/service/tools/ConnectionToString.py @@ -0,0 +1,25 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 typing import List +from common.proto.context_pb2 import Connection + +def connection_to_string(connection : Connection) -> str: + str_device_endpoint_uuids : List[str] = list() + for endpoint_id in connection.path_hops_endpoint_ids: + device_uuid = endpoint_id.device_id.device_uuid.uuid + endpoint_uuid = endpoint_id.endpoint_uuid.uuid + device_endpoint_uuid = '{:s}:{:s}'.format(device_uuid, endpoint_uuid) + str_device_endpoint_uuids.append(device_endpoint_uuid) + return ','.join(str_device_endpoint_uuids) diff --git a/src/service/service/tools/ContextGetters.py b/src/service/service/tools/ContextGetters.py deleted file mode 100644 index 9b1d6224d1e4201cbc0720e7ce818a86e5ae2042..0000000000000000000000000000000000000000 --- a/src/service/service/tools/ContextGetters.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 -from typing import Optional -from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceId, Service, ServiceId -from context.client.ContextClient import ContextClient - -def get_connection(context_client : ContextClient, connection_id : ConnectionId) -> Optional[Connection]: - try: - connection : Connection = context_client.GetConnection(connection_id) - return connection - except grpc.RpcError as e: - if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member - return None - -def get_device(context_client : ContextClient, device_id : DeviceId) -> Optional[Device]: - try: - device : Device = context_client.GetDevice(device_id) - return device - except grpc.RpcError as e: - if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member - return None - -def get_service(context_client : ContextClient, service_id : ServiceId) -> Optional[Service]: - try: - service : Service = context_client.GetService(service_id) - return service - except grpc.RpcError as e: - if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member - return None diff --git a/src/service/tests/descriptors_recompute_conns.json b/src/service/tests/descriptors_recompute_conns.json new file mode 100644 index 0000000000000000000000000000000000000000..dd571ccb6b2ff61ca0e581780ca02d71171bb894 --- /dev/null +++ b/src/service/tests/descriptors_recompute_conns.json @@ -0,0 +1,239 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R3"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R4"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R5"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R6"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R7"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"}, + {"sample_types": [], "type": "copper", "uuid": "2/4"}, + {"sample_types": [], "type": "copper", "uuid": "2/5"}, + {"sample_types": [], "type": "copper", "uuid": "2/6"} + ]}}} + ]} + } + ], + "links": [ + {"link_id": {"link_uuid": {"uuid": "R1==R2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1==R6"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1==R7"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2==R1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2==R3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3==R2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3==R4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3==R7"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R4==R3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R4==R5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R5==R4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R5==R6"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R5==R7"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/5"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R6==R1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R6==R5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R7==R1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R7==R3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R7==R5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/5"}}, + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/3"}} + ]} + ], + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "test-svc"} + }, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id":{"device_uuid":{"uuid":"R1"}},"endpoint_uuid":{"uuid":"1/1"}}, + {"device_id":{"device_uuid":{"uuid":"R4"}},"endpoint_uuid":{"uuid":"1/1"}} + ], + "service_constraints": [ + {"sla_capacity": {"capacity_gbps": 10.0}}, + {"sla_latency": {"e2e_latency_ms": 15.2}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "address_families": ["IPV4"], "bgp_as": 65000, "bgp_route_target": "65000:123", + "mtu": 1512, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R1]/endpoint[1/1]/settings", "resource_value": { + "sub_interface_index": 0, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R4]/endpoint[1/1]/settings", "resource_value": { + "sub_interface_index": 0, "vlan_id": 111 + }}} + ]} + } + ] +} diff --git a/src/service/tests/test_service_recompute_cons.sh b/src/service/tests/test_service_recompute_cons.sh new file mode 100644 index 0000000000000000000000000000000000000000..e5bc18895b2968ba99b7262458ed988e57ee920c --- /dev/null +++ b/src/service/tests/test_service_recompute_cons.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +source my_deploy.sh +./deploy/all.sh + +source tfs_runtime_env_vars.sh +PYTHONPATH=./src pytest --log-level=INFO --verbose src/service/tests/test_unitary_recompute_conns.py diff --git a/src/service/tests/test_unitary_recompute_conns.py b/src/service/tests/test_unitary_recompute_conns.py new file mode 100644 index 0000000000000000000000000000000000000000..717e3af73b0d21d1dfeeab1e388c5df663417337 --- /dev/null +++ b/src/service/tests/test_unitary_recompute_conns.py @@ -0,0 +1,120 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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) + LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) + assert len(response.services) == 1 + service = response.services[0] + service_id = service.service_id + + response = context_client.ListConnections(service_id) + LOGGER.info(' 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) + LOGGER.info(' 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) + + assert str_old_connections != str_new_connections + + str_old_connections = str_new_connections + + # Change path second 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) + LOGGER.info(' 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) + + assert str_old_connections != str_new_connections + + + # ===== Cleanup scenario =========================================================================================== + # Validate and unload the base scenario + descriptor_loader.validate() + descriptor_loader.unload() + validate_empty_scenario(context_client) diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py index acec3ae303266714ae7f50c5c0d78fc41d350ea1..f91c55e281e8ed5f994dea3dce43a63184669795 100644 --- a/src/slice/service/SliceServiceServicerImpl.py +++ b/src/slice/service/SliceServiceServicerImpl.py @@ -19,7 +19,7 @@ from common.proto.context_pb2 import ( from common.proto.slice_pb2_grpc import SliceServiceServicer from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.tools.context_queries.InterDomain import is_multi_domain -from common.tools.context_queries.Slice import get_slice +from common.tools.context_queries.Slice import get_slice_by_id from common.tools.grpc.ConfigRules import copy_config_rules from common.tools.grpc.Constraints import copy_constraints from common.tools.grpc.EndPointIds import copy_endpoint_ids @@ -44,9 +44,7 @@ class SliceServiceServicerImpl(SliceServiceServicer): # Set slice status to "SERVICESTATUS_PLANNED" to ensure rest of components are aware the slice is # being modified. context_client = ContextClient() - slice_ro : Optional[Service] = get_slice( - context_client, request.slice_id.slice_uuid.uuid, request.slice_id.context_id.context_uuid.uuid, - rw_copy=False) + slice_ro : Optional[Slice] = get_slice_by_id(context_client, request.slice_id, rw_copy=False) slice_rw = Slice() slice_rw.CopyFrom(request if slice_ro is None else slice_ro) diff --git a/src/slice/service/__main__.py b/src/slice/service/__main__.py index aef1c4b82a540ddb40f35f4af2340ead539a0451..4d581530a40c16cd130dbf12dd0aa2936902c272 100644 --- a/src/slice/service/__main__.py +++ b/src/slice/service/__main__.py @@ -55,7 +55,7 @@ def main(): grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(timeout=0.1): pass + while not terminate.wait(timeout=1.0): pass LOGGER.info('Terminating...') grpc_service.stop() diff --git a/src/slice/service/slice_grouper/SliceGrouper.py b/src/slice/service/slice_grouper/SliceGrouper.py index 735d028993eb11e83138caebde1e32ebc830093f..2f1a791819f6a8d0951e9e93ca22d071ea66c1f7 100644 --- a/src/slice/service/slice_grouper/SliceGrouper.py +++ b/src/slice/service/slice_grouper/SliceGrouper.py @@ -29,6 +29,7 @@ class SliceGrouper: def __init__(self) -> None: self._lock = threading.Lock() self._is_enabled = is_slice_grouping_enabled() + LOGGER.info('Slice Grouping: {:s}'.format('ENABLED' if self._is_enabled else 'DISABLED')) if not self._is_enabled: return metrics_exporter = MetricsExporter() diff --git a/src/slice/service/slice_grouper/Tools.py b/src/slice/service/slice_grouper/Tools.py index ca957f3c7760eb65b649d22ecb5b57dee3e08dab..c815a19d5477ec82c2c2702ba58bb5b092144692 100644 --- a/src/slice/service/slice_grouper/Tools.py +++ b/src/slice/service/slice_grouper/Tools.py @@ -18,7 +18,7 @@ from common.Settings import get_setting from common.method_wrappers.ServiceExceptions import NotFoundException from common.proto.context_pb2 import IsolationLevelEnum, Slice, SliceId, SliceStatusEnum from common.tools.context_queries.Context import create_context -from common.tools.context_queries.Slice import get_slice +from common.tools.context_queries.Slice import get_slice_by_uuid from context.client.ContextClient import ContextClient from slice.service.slice_grouper.MetricsExporter import MetricsExporter @@ -70,7 +70,7 @@ def create_slice_groups( slice_group_ids : Dict[str, SliceId] = dict() for slice_group in slice_groups: slice_group_name = slice_group[0] - slice_group_obj = get_slice(context_client, slice_group_name, DEFAULT_CONTEXT_NAME) + slice_group_obj = get_slice_by_uuid(context_client, slice_group_name, DEFAULT_CONTEXT_NAME) if slice_group_obj is None: slice_group_obj = create_slice_group( DEFAULT_CONTEXT_NAME, slice_group_name, slice_group[2], slice_group[1]) @@ -111,7 +111,7 @@ def add_slice_to_group(slice_obj : Slice, selected_group : Tuple[str, float, flo slice_uuid = slice_obj.slice_id.slice_uuid.uuid context_client = ContextClient() - slice_group_obj = get_slice(context_client, group_name, DEFAULT_CONTEXT_NAME, rw_copy=True) + slice_group_obj = get_slice_by_uuid(context_client, group_name, DEFAULT_CONTEXT_NAME, rw_copy=True) if slice_group_obj is None: raise NotFoundException('Slice', group_name, extra_details='while adding to group') @@ -148,7 +148,7 @@ def remove_slice_from_group(slice_obj : Slice, selected_group : Tuple[str, float slice_uuid = slice_obj.slice_id.slice_uuid.uuid context_client = ContextClient() - slice_group_obj = get_slice(context_client, group_name, DEFAULT_CONTEXT_NAME, rw_copy=True) + slice_group_obj = get_slice_by_uuid(context_client, group_name, DEFAULT_CONTEXT_NAME, rw_copy=True) if slice_group_obj is None: raise NotFoundException('Slice', group_name, extra_details='while removing from group') diff --git a/src/tests/oeccpsc22/.gitignore b/src/tests/oeccpsc22/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6b97d6fe3ad32f39097745229ab7f547f26ecb12 --- /dev/null +++ b/src/tests/oeccpsc22/.gitignore @@ -0,0 +1 @@ +# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc. diff --git a/src/tests/oeccpsc22/delete_all.sh b/src/tests/oeccpsc22/delete_all.sh new file mode 100755 index 0000000000000000000000000000000000000000..c0d39fa8bd690ebfe13bea321f94f769d5817079 --- /dev/null +++ b/src/tests/oeccpsc22/delete_all.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-dom1 tfs-dom2 + +# Delete secondary ingress controllers +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom1.yaml +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom2.yaml diff --git a/src/tests/oeccpsc22/deploy_all.sh b/src/tests/oeccpsc22/deploy_all.sh new file mode 100755 index 0000000000000000000000000000000000000000..737230346593bff3840cf7097fcf726242f84ce4 --- /dev/null +++ b/src/tests/oeccpsc22/deploy_all.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-dom1 tfs-dom2 + +# Delete secondary ingress controllers +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom1.yaml +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom2.yaml + +# Create secondary ingress controllers +kubectl apply -f oeccpsc22/nginx-ingress-controller-dom1.yaml +kubectl apply -f oeccpsc22/nginx-ingress-controller-dom2.yaml + +# Deploy TFS for Domain 1 +source oeccpsc22/deploy_specs_dom1.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_dom1.sh + +# Deploy TFS for Domain 2 +source oeccpsc22/deploy_specs_dom2.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_dom2.sh diff --git a/src/tests/oeccpsc22/deploy_dom1.sh b/src/tests/oeccpsc22/deploy_dom1.sh new file mode 100755 index 0000000000000000000000000000000000000000..81fb9984450461f46e9011c7ef49dfe3070fc371 --- /dev/null +++ b/src/tests/oeccpsc22/deploy_dom1.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-dom1 + +# Delete secondary ingress controllers +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom1.yaml + +# Create secondary ingress controllers +kubectl apply -f oeccpsc22/nginx-ingress-controller-dom1.yaml + +# Deploy TFS for Domain 1 +source oeccpsc22/deploy_specs_dom1.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_dom1.sh diff --git a/src/tests/oeccpsc22/deploy_dom2.sh b/src/tests/oeccpsc22/deploy_dom2.sh new file mode 100755 index 0000000000000000000000000000000000000000..93fff1d15a56ceb20a6d625643453244eb71124e --- /dev/null +++ b/src/tests/oeccpsc22/deploy_dom2.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-dom2 + +# Delete secondary ingress controllers +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom2.yaml + +# Create secondary ingress controllers +kubectl apply -f oeccpsc22/nginx-ingress-controller-dom2.yaml + +# Deploy TFS for Domain 2 +source oeccpsc22/deploy_specs_dom2.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_dom2.sh diff --git a/src/tests/oeccpsc22/deploy_specs_dom1.sh b/src/tests/oeccpsc22/deploy_specs_dom1.sh new file mode 100755 index 0000000000000000000000000000000000000000..b269236b0bd7ac6ac21a743205157fd9aec42c37 --- /dev/null +++ b/src/tests/oeccpsc22/deploy_specs_dom1.sh @@ -0,0 +1,127 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 automation monitoring pathcomp service slice compute webui interdomain load_generator" +export TFS_COMPONENTS="context device pathcomp service slice interdomain webui" + +# 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-dom1" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="oeccpsc22/nginx-ingress-http-dom1.yaml oeccpsc22/expose-services-dom1.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 the database name to be used by Context. +export CRDB_DATABASE="tfs_dom1" + +# 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="" + +# Disable flag for re-deploying CockroachDB from scratch. +export CRDB_REDEPLOY="" + + +# ----- NATS ------------------------------------------------------------------- + +# Set the namespace where NATS will be deployed. +export NATS_NAMESPACE="nats-dom1" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4223" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8223" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-dom1" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8813" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9011" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9001" + +# 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" diff --git a/src/tests/oeccpsc22/deploy_specs_dom2.sh b/src/tests/oeccpsc22/deploy_specs_dom2.sh new file mode 100755 index 0000000000000000000000000000000000000000..112142437ed172f3b773ae148b57b5e0732676fb --- /dev/null +++ b/src/tests/oeccpsc22/deploy_specs_dom2.sh @@ -0,0 +1,127 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 automation monitoring pathcomp service slice compute webui interdomain load_generator" +export TFS_COMPONENTS="context device pathcomp service slice interdomain webui" + +# 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-dom2" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="oeccpsc22/nginx-ingress-http-dom2.yaml oeccpsc22/expose-services-dom2.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="YES" + + +# ----- 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 the database name to be used by Context. +export CRDB_DATABASE="tfs_dom2" + +# 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="" + +# Disable flag for re-deploying CockroachDB from scratch. +export CRDB_REDEPLOY="" + + +# ----- NATS ------------------------------------------------------------------- + +# Set the namespace where NATS will be deployed. +export NATS_NAMESPACE="nats-dom2" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4224" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8224" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-dom2" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8814" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9012" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9002" + +# 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" diff --git a/src/tests/oeccpsc22/descriptors/domain1.json b/src/tests/oeccpsc22/descriptors/domain1.json new file mode 100644 index 0000000000000000000000000000000000000000..2db10b4d1f2e7a702e6da99d1da28fc2fc21c288 --- /dev/null +++ b/src/tests/oeccpsc22/descriptors/domain1.json @@ -0,0 +1,178 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}}, + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "DC1"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "int", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "D1", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC2"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "int", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "D2", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "D2"}}, "device_type": "network", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "10010"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "D1", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" }, + {"uuid": "DC2", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R1@D1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "2", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "5", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "DC1", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R2@D1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "1", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "3", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "5", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R3@D1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "2", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "4", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R4@D1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "3", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "5", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "D2", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R5@D1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "1", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "2", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "4", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"} + ]}}} + ]} + } + ], + "links": [ + {"link_id": {"link_uuid": {"uuid": "DC1/D1==R1@D1/DC1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "D1"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}}, + {"device_id": {"device_uuid": {"uuid": "R1@D1"}}, "endpoint_uuid": {"uuid": "DC1"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1@D1/DC1==DC1/D1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1@D1"}}, "endpoint_uuid": {"uuid": "DC1"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "D1"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ]}, + {"link_id": {"link_uuid": {"uuid": "DC2/D2==D2/DC2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "D2"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}}, + {"device_id": {"device_uuid": {"uuid": "D2"}}, "endpoint_uuid": {"uuid": "DC2"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ]}, + {"link_id": {"link_uuid": {"uuid": "D2/DC2==DC2/D2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "D2"}}, "endpoint_uuid": {"uuid": "DC2"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "D2"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R4@D1/D2==D2/D1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4@D1"}}, "endpoint_uuid": {"uuid": "D2"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}}, + {"device_id": {"device_uuid": {"uuid": "D2"}}, "endpoint_uuid": {"uuid": "D1"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ]}, + {"link_id": {"link_uuid": {"uuid": "D2/D1==R4@D1/D2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "D2"}}, "endpoint_uuid": {"uuid": "D1"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}}, + {"device_id": {"device_uuid": {"uuid": "R4@D1"}}, "endpoint_uuid": {"uuid": "D2"}, "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ]}, + + {"link_id": {"link_uuid": {"uuid": "R1@D1/2==R2@D1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1@D1"}}, "endpoint_uuid": {"uuid": "2"}}, + {"device_id": {"device_uuid": {"uuid": "R2@D1"}}, "endpoint_uuid": {"uuid": "1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1@D1/5==R5@D1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1@D1"}}, "endpoint_uuid": {"uuid": "5"}}, + {"device_id": {"device_uuid": {"uuid": "R5@D1"}}, "endpoint_uuid": {"uuid": "1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2@D1/1==R1@D1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2@D1"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "R1@D1"}}, "endpoint_uuid": {"uuid": "2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2@D1/3==R3@D1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2@D1"}}, "endpoint_uuid": {"uuid": "3"}}, + {"device_id": {"device_uuid": {"uuid": "R3@D1"}}, "endpoint_uuid": {"uuid": "2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2@D1/5==R5@D1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2@D1"}}, "endpoint_uuid": {"uuid": "5"}}, + {"device_id": {"device_uuid": {"uuid": "R5@D1"}}, "endpoint_uuid": {"uuid": "2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3@D1/2==R2@D1/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3@D1"}}, "endpoint_uuid": {"uuid": "2"}}, + {"device_id": {"device_uuid": {"uuid": "R2@D1"}}, "endpoint_uuid": {"uuid": "3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3@D1/4==R4@D1/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3@D1"}}, "endpoint_uuid": {"uuid": "4"}}, + {"device_id": {"device_uuid": {"uuid": "R4@D1"}}, "endpoint_uuid": {"uuid": "3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R4@D1/3==R3@D1/4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4@D1"}}, "endpoint_uuid": {"uuid": "3"}}, + {"device_id": {"device_uuid": {"uuid": "R3@D1"}}, "endpoint_uuid": {"uuid": "4"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R4@D1/5==R5@D1/4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4@D1"}}, "endpoint_uuid": {"uuid": "5"}}, + {"device_id": {"device_uuid": {"uuid": "R5@D1"}}, "endpoint_uuid": {"uuid": "4"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R5@D1/1==R1@D1/5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5@D1"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "R1@D1"}}, "endpoint_uuid": {"uuid": "5"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R5@D1/2==R2@D1/5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5@D1"}}, "endpoint_uuid": {"uuid": "2"}}, + {"device_id": {"device_uuid": {"uuid": "R2@D1"}}, "endpoint_uuid": {"uuid": "5"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R5@D1/4==R4@D1/5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5@D1"}}, "endpoint_uuid": {"uuid": "4"}}, + {"device_id": {"device_uuid": {"uuid": "R4@D1"}}, "endpoint_uuid": {"uuid": "5"}} + ]} + ] +} diff --git a/src/tests/oeccpsc22/descriptors/domain2.json b/src/tests/oeccpsc22/descriptors/domain2.json new file mode 100644 index 0000000000000000000000000000000000000000..e7a00f74e7cc14c9db6d7be6fa89ef538f9cfa34 --- /dev/null +++ b/src/tests/oeccpsc22/descriptors/domain2.json @@ -0,0 +1,72 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}}, + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "inter"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R1@D2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "2", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "3", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R2@D2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "1", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "3", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "D1", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R3@D2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 2, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"uuid": "1", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "2", "context_uuid": "admin", "topology_uuid": "admin", "type": "copper/internal"}, + {"uuid": "DC2", "context_uuid": "admin", "topology_uuid": "inter", "type": "copper/border" } + ]}}} + ]} + } + ], + "links": [ + {"link_id": {"link_uuid": {"uuid": "R1@D2/2==R2@D2/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1@D2"}}, "endpoint_uuid": {"uuid": "2"}}, + {"device_id": {"device_uuid": {"uuid": "R2@D2"}}, "endpoint_uuid": {"uuid": "1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R1@D2/3==R3@D2/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1@D2"}}, "endpoint_uuid": {"uuid": "3"}}, + {"device_id": {"device_uuid": {"uuid": "R3@D2"}}, "endpoint_uuid": {"uuid": "1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2@D2/1==R1@D2/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2@D2"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "R1@D2"}}, "endpoint_uuid": {"uuid": "2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R2@D2/3==R3@D2/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2@D2"}}, "endpoint_uuid": {"uuid": "3"}}, + {"device_id": {"device_uuid": {"uuid": "R3@D2"}}, "endpoint_uuid": {"uuid": "2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3@D2/1==R1@D2/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3@D2"}}, "endpoint_uuid": {"uuid": "1"}}, + {"device_id": {"device_uuid": {"uuid": "R1@D2"}}, "endpoint_uuid": {"uuid": "3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "R3@D2/2==R2@D2/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3@D2"}}, "endpoint_uuid": {"uuid": "2"}}, + {"device_id": {"device_uuid": {"uuid": "R2@D2"}}, "endpoint_uuid": {"uuid": "3"}} + ]} + ] +} diff --git a/src/tests/oeccpsc22/descriptors/inter-domain-service.json b/src/tests/oeccpsc22/descriptors/inter-domain-service.json new file mode 100644 index 0000000000000000000000000000000000000000..4b53c433aba16845b703b72a3fe4ef1f9e54c0f2 --- /dev/null +++ b/src/tests/oeccpsc22/descriptors/inter-domain-service.json @@ -0,0 +1,32 @@ +{ + "services": [ + { + "service_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "idc-l2-svc"}}, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id":{"device_uuid":{"uuid":"DC1"}},"endpoint_uuid":{"uuid":"int"}}, + {"device_id":{"device_uuid":{"uuid":"DC2"}},"endpoint_uuid":{"uuid":"int"}} + ], + "service_constraints": [ + {"sla_capacity": {"capacity_gbps": 10.0}}, + {"sla_latency": {"e2e_latency_ms": 15.2}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": {"mtu": 1512, "vlan_id": 300}}}, + {"action": 1, "custom": {"resource_key": "/device[R1@D1]/endpoint[2]/settings", "resource_value": {"remote_router": "10.0.0.2"}}}, + {"action": 1, "custom": {"resource_key": "/device[R1@D1]/endpoint[5]/settings", "resource_value": {"remote_router": "10.0.0.5"}}}, + {"action": 1, "custom": {"resource_key": "/device[R2@D1]/endpoint[1]/settings", "resource_value": {"remote_router": "10.0.0.1"}}}, + {"action": 1, "custom": {"resource_key": "/device[R2@D1]/endpoint[3]/settings", "resource_value": {"remote_router": "10.0.0.3"}}}, + {"action": 1, "custom": {"resource_key": "/device[R2@D1]/endpoint[5]/settings", "resource_value": {"remote_router": "10.0.0.5"}}}, + {"action": 1, "custom": {"resource_key": "/device[R3@D1]/endpoint[2]/settings", "resource_value": {"remote_router": "10.0.0.2"}}}, + {"action": 1, "custom": {"resource_key": "/device[R3@D1]/endpoint[4]/settings", "resource_value": {"remote_router": "10.0.0.4"}}}, + {"action": 1, "custom": {"resource_key": "/device[R4@D1]/endpoint[3]/settings", "resource_value": {"remote_router": "10.0.0.3"}}}, + {"action": 1, "custom": {"resource_key": "/device[R4@D1]/endpoint[5]/settings", "resource_value": {"remote_router": "10.0.0.5"}}}, + {"action": 1, "custom": {"resource_key": "/device[R5@D1]/endpoint[1]/settings", "resource_value": {"remote_router": "10.0.0.1"}}}, + {"action": 1, "custom": {"resource_key": "/device[R5@D1]/endpoint[2]/settings", "resource_value": {"remote_router": "10.0.0.2"}}}, + {"action": 1, "custom": {"resource_key": "/device[R5@D1]/endpoint[4]/settings", "resource_value": {"remote_router": "10.0.0.4"}}} + ]} + } + ] +} diff --git a/src/tests/oeccpsc22/dump_logs.sh b/src/tests/oeccpsc22/dump_logs.sh index a2180f6dff3f35cc7d0e9e2011179a6d8b933ea1..3a2e51a56b9346a254995d935fd45d8b5e7a1396 100755 --- a/src/tests/oeccpsc22/dump_logs.sh +++ b/src/tests/oeccpsc22/dump_logs.sh @@ -5,7 +5,7 @@ # 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 +# 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, @@ -13,20 +13,33 @@ # See the License for the specific language governing permissions and # limitations under the License. -mkdir -p tmp/exec_logs/ -kubectl --namespace oeccpsc22-1 logs deployment/computeservice -c server > tmp/exec_logs/d1_compute.log -kubectl --namespace oeccpsc22-1 logs deployment/contextservice -c server > tmp/exec_logs/d1_context.log -kubectl --namespace oeccpsc22-1 logs deployment/deviceservice -c server > tmp/exec_logs/d1_device.log -kubectl --namespace oeccpsc22-1 logs deployment/interdomainservice -c server > tmp/exec_logs/d1_interdomain.log -kubectl --namespace oeccpsc22-1 logs deployment/monitoringservice -c server > tmp/exec_logs/d1_monitoring.log -kubectl --namespace oeccpsc22-1 logs deployment/serviceservice -c server > tmp/exec_logs/d1_service.log -kubectl --namespace oeccpsc22-1 logs deployment/sliceservice -c server > tmp/exec_logs/d1_slice.log +rm -rf tmp/exec -kubectl --namespace oeccpsc22-2 logs deployment/computeservice -c server > tmp/exec_logs/d2_compute.log -kubectl --namespace oeccpsc22-2 logs deployment/contextservice -c server > tmp/exec_logs/d2_context.log -kubectl --namespace oeccpsc22-2 logs deployment/deviceservice -c server > tmp/exec_logs/d2_device.log -kubectl --namespace oeccpsc22-2 logs deployment/interdomainservice -c server > tmp/exec_logs/d2_interdomain.log -kubectl --namespace oeccpsc22-2 logs deployment/monitoringservice -c server > tmp/exec_logs/d2_monitoring.log -kubectl --namespace oeccpsc22-2 logs deployment/serviceservice -c server > tmp/exec_logs/d2_service.log -kubectl --namespace oeccpsc22-2 logs deployment/sliceservice -c server > tmp/exec_logs/d2_slice.log +echo "Collecting logs for Domain 1..." +mkdir -p tmp/exec/dom1 +kubectl --namespace tfs-dom1 logs deployments/contextservice server > tmp/exec/dom1/context.log +kubectl --namespace tfs-dom1 logs deployments/deviceservice server > tmp/exec/dom1/device.log +kubectl --namespace tfs-dom1 logs deployments/serviceservice server > tmp/exec/dom1/service.log +kubectl --namespace tfs-dom1 logs deployments/pathcompservice frontend > tmp/exec/dom1/pathcomp-frontend.log +kubectl --namespace tfs-dom1 logs deployments/pathcompservice backend > tmp/exec/dom1/pathcomp-backend.log +kubectl --namespace tfs-dom1 logs deployments/sliceservice server > tmp/exec/dom1/slice.log +kubectl --namespace tfs-dom1 logs deployment/computeservice server > tmp/exec/dom1/compute.log +kubectl --namespace tfs-dom1 logs deployment/interdomainservice server > tmp/exec/dom1/interdomain.log +kubectl --namespace tfs-dom1 logs deployment/monitoringservice server > tmp/exec/dom1/monitoring.log +printf "\n" + +echo "Collecting logs for Domain 2..." +mkdir -p tmp/exec/dom2 +kubectl --namespace tfs-dom2 logs deployments/contextservice server > tmp/exec/dom2/context.log +kubectl --namespace tfs-dom2 logs deployments/deviceservice server > tmp/exec/dom2/device.log +kubectl --namespace tfs-dom2 logs deployments/serviceservice server > tmp/exec/dom2/service.log +kubectl --namespace tfs-dom2 logs deployments/pathcompservice frontend > tmp/exec/dom2/pathcomp-frontend.log +kubectl --namespace tfs-dom2 logs deployments/pathcompservice backend > tmp/exec/dom2/pathcomp-backend.log +kubectl --namespace tfs-dom2 logs deployments/sliceservice server > tmp/exec/dom2/slice.log +kubectl --namespace tfs-dom2 logs deployment/computeservice server > tmp/exec/dom2/compute.log +kubectl --namespace tfs-dom2 logs deployment/interdomainservice server > tmp/exec/dom2/interdomain.log +kubectl --namespace tfs-dom2 logs deployment/monitoringservice server > tmp/exec/dom2/monitoring.log +printf "\n" + +echo "Done!" diff --git a/src/tests/oeccpsc22/expose-services-dom1.yaml b/src/tests/oeccpsc22/expose-services-dom1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ebfb38fc4781240887fa52163224607da661b952 --- /dev/null +++ b/src/tests/oeccpsc22/expose-services-dom1.yaml @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: Service +metadata: + name: remote-teraflow +spec: + type: ExternalName + externalName: interdomainservice.dom2.svc.cluster.local + ports: + - name: grpc + protocol: TCP + port: 10010 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: contextservice-public +# labels: +# app: contextservice +#spec: +# type: NodePort +# selector: +# app: contextservice +# ports: +# - name: grpc +# protocol: TCP +# port: 1010 +# targetPort: 1010 +# nodePort: 30111 +# - name: rest +# protocol: TCP +# port: 8080 +# targetPort: 8080 +# nodePort: 30001 +# - name: redis +# protocol: TCP +# port: 6379 +# targetPort: 6379 +# nodePort: 30631 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: deviceservice-public +# labels: +# app: deviceservice +#spec: +# type: NodePort +# selector: +# app: deviceservice +# ports: +# - name: grpc +# protocol: TCP +# port: 2020 +# targetPort: 2020 +# nodePort: 30221 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: computeservice-public +#spec: +# type: NodePort +# selector: +# app: computeservice +# ports: +# - name: http +# protocol: TCP +# port: 8080 +# targetPort: 8080 +# nodePort: 30881 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: webuiservice-public +# labels: +# app: webuiservice +#spec: +# type: NodePort +# selector: +# app: webuiservice +# ports: +# - name: http +# protocol: TCP +# port: 8004 +# targetPort: 8004 +# nodePort: 30801 +# - name: grafana +# protocol: TCP +# port: 3000 +# targetPort: 3000 +# nodePort: 30301 diff --git a/src/tests/oeccpsc22/expose-services-dom2.yaml b/src/tests/oeccpsc22/expose-services-dom2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cf04f3f5eb4b029cc4cb03e41df9c8ced23d92f8 --- /dev/null +++ b/src/tests/oeccpsc22/expose-services-dom2.yaml @@ -0,0 +1,106 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: Service +metadata: + name: remote-teraflow +spec: + type: ExternalName + externalName: interdomainservice.dom1.svc.cluster.local + ports: + - name: grpc + protocol: TCP + port: 10010 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: contextservice-public +# labels: +# app: contextservice +#spec: +# type: NodePort +# selector: +# app: contextservice +# ports: +# - name: grpc +# protocol: TCP +# port: 1010 +# targetPort: 1010 +# nodePort: 30112 +# - name: rest +# protocol: TCP +# port: 8080 +# targetPort: 8080 +# nodePort: 30002 +# - name: redis +# protocol: TCP +# port: 6379 +# targetPort: 6379 +# nodePort: 30632 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: deviceservice-public +# labels: +# app: deviceservice +#spec: +# type: NodePort +# selector: +# app: deviceservice +# ports: +# - name: grpc +# protocol: TCP +# port: 2020 +# targetPort: 2020 +# nodePort: 30222 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: computeservice-public +#spec: +# type: NodePort +# selector: +# app: computeservice +# ports: +# - name: http +# protocol: TCP +# port: 8080 +# targetPort: 8080 +# nodePort: 30882 +#--- +#apiVersion: v1 +#kind: Service +#metadata: +# name: webuiservice-public +# labels: +# app: webuiservice +#spec: +# type: NodePort +# selector: +# app: webuiservice +# ports: +# - name: http +# protocol: TCP +# port: 8004 +# targetPort: 8004 +# nodePort: 30802 +# - name: grafana +# protocol: TCP +# port: 3000 +# targetPort: 3000 +# nodePort: 30302 diff --git a/src/tests/oeccpsc22/expose_services_teraflow_1.yaml b/src/tests/oeccpsc22/expose_services_teraflow_1.yaml deleted file mode 100644 index d956db1a781147467efd1c4724e0734b579d8f5d..0000000000000000000000000000000000000000 --- a/src/tests/oeccpsc22/expose_services_teraflow_1.yaml +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 -kind: Service -metadata: - name: remote-teraflow -spec: - type: ExternalName - externalName: interdomainservice.oeccpsc22-2.svc.cluster.local - ports: - - name: grpc - protocol: TCP - port: 10010 ---- -apiVersion: v1 -kind: Service -metadata: - name: contextservice-public - labels: - app: contextservice -spec: - type: NodePort - selector: - app: contextservice - ports: - - name: grpc - protocol: TCP - port: 1010 - targetPort: 1010 - nodePort: 30111 - - name: rest - protocol: TCP - port: 8080 - targetPort: 8080 - nodePort: 30001 - - name: redis - protocol: TCP - port: 6379 - targetPort: 6379 - nodePort: 30631 ---- -apiVersion: v1 -kind: Service -metadata: - name: deviceservice-public - labels: - app: deviceservice -spec: - type: NodePort - selector: - app: deviceservice - ports: - - name: grpc - protocol: TCP - port: 2020 - targetPort: 2020 - nodePort: 30221 ---- -apiVersion: v1 -kind: Service -metadata: - name: computeservice-public -spec: - type: NodePort - selector: - app: computeservice - ports: - - name: http - protocol: TCP - port: 8080 - targetPort: 8080 - nodePort: 30881 ---- -apiVersion: v1 -kind: Service -metadata: - name: webuiservice-public - labels: - app: webuiservice -spec: - type: NodePort - selector: - app: webuiservice - ports: - - name: http - protocol: TCP - port: 8004 - targetPort: 8004 - nodePort: 30801 - - name: grafana - protocol: TCP - port: 3000 - targetPort: 3000 - nodePort: 30301 diff --git a/src/tests/oeccpsc22/expose_services_teraflow_2.yaml b/src/tests/oeccpsc22/expose_services_teraflow_2.yaml deleted file mode 100644 index d8acb96533f8886afc0fd5c802d3616277676e33..0000000000000000000000000000000000000000 --- a/src/tests/oeccpsc22/expose_services_teraflow_2.yaml +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 -kind: Service -metadata: - name: remote-teraflow -spec: - type: ExternalName - externalName: interdomainservice.oeccpsc22-1.svc.cluster.local - ports: - - name: grpc - protocol: TCP - port: 10010 ---- -apiVersion: v1 -kind: Service -metadata: - name: contextservice-public - labels: - app: contextservice -spec: - type: NodePort - selector: - app: contextservice - ports: - - name: grpc - protocol: TCP - port: 1010 - targetPort: 1010 - nodePort: 30112 - - name: rest - protocol: TCP - port: 8080 - targetPort: 8080 - nodePort: 30002 - - name: redis - protocol: TCP - port: 6379 - targetPort: 6379 - nodePort: 30632 ---- -apiVersion: v1 -kind: Service -metadata: - name: deviceservice-public - labels: - app: deviceservice -spec: - type: NodePort - selector: - app: deviceservice - ports: - - name: grpc - protocol: TCP - port: 2020 - targetPort: 2020 - nodePort: 30222 ---- -apiVersion: v1 -kind: Service -metadata: - name: computeservice-public -spec: - type: NodePort - selector: - app: computeservice - ports: - - name: http - protocol: TCP - port: 8080 - targetPort: 8080 - nodePort: 30882 ---- -apiVersion: v1 -kind: Service -metadata: - name: webuiservice-public - labels: - app: webuiservice -spec: - type: NodePort - selector: - app: webuiservice - ports: - - name: http - protocol: TCP - port: 8004 - targetPort: 8004 - nodePort: 30802 - - name: grafana - protocol: TCP - port: 3000 - targetPort: 3000 - nodePort: 30302 diff --git a/src/tests/oeccpsc22/fast_redeploy.sh b/src/tests/oeccpsc22/fast_redeploy.sh new file mode 100755 index 0000000000000000000000000000000000000000..f4e909eef106a4720d184415d1ec584adb98e1b0 --- /dev/null +++ b/src/tests/oeccpsc22/fast_redeploy.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +kubectl delete namespace tfs-dom1 tfs-dom2 + +echo "Deploying tfs-dom1 ..." +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom1.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl create namespace tfs-dom1 > ./tmp/logs/deploy-tfs-dom1.log +kubectl apply -f oeccpsc22/nginx-ingress-controller-dom1.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-dom1.log +kubectl --namespace tfs-dom1 apply -f oeccpsc22/tfs-ingress-dom1.yaml > ./tmp/logs/deploy-tfs-dom1.log +printf "\n" + +echo "Deploying tfs-dom2 ..." +kubectl delete -f oeccpsc22/nginx-ingress-controller-dom2.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl create namespace tfs-dom2 > ./tmp/logs/deploy-tfs-dom2.log +kubectl apply -f oeccpsc22/nginx-ingress-controller-dom2.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-dom2.log +kubectl --namespace tfs-dom2 apply -f oeccpsc22/tfs-ingress-dom2.yaml > ./tmp/logs/deploy-tfs-dom2.log +printf "\n" + +echo "Waiting tfs-dom1 ..." +kubectl wait --namespace tfs-dom1 --for='condition=available' --timeout=300s deployment/contextservice +kubectl wait --namespace tfs-dom1 --for='condition=available' --timeout=300s deployment/deviceservice +kubectl wait --namespace tfs-dom1 --for='condition=available' --timeout=300s deployment/pathcompservice +kubectl wait --namespace tfs-dom1 --for='condition=available' --timeout=300s deployment/serviceservice +kubectl wait --namespace tfs-dom1 --for='condition=available' --timeout=300s deployment/sliceservice +kubectl wait --namespace tfs-dom1 --for='condition=available' --timeout=300s deployment/webuiservice +printf "\n" + +echo "Waiting tfs-dom2 ..." +kubectl wait --namespace tfs-dom2 --for='condition=available' --timeout=300s deployment/contextservice +kubectl wait --namespace tfs-dom2 --for='condition=available' --timeout=300s deployment/deviceservice +kubectl wait --namespace tfs-dom2 --for='condition=available' --timeout=300s deployment/pathcompservice +kubectl wait --namespace tfs-dom2 --for='condition=available' --timeout=300s deployment/serviceservice +kubectl wait --namespace tfs-dom2 --for='condition=available' --timeout=300s deployment/sliceservice +kubectl wait --namespace tfs-dom2 --for='condition=available' --timeout=300s deployment/webuiservice +printf "\n" + +echo "Done!" diff --git a/src/tests/oeccpsc22/nginx-ingress-controller-dom1.yaml b/src/tests/oeccpsc22/nginx-ingress-controller-dom1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1815bfbaa481ef269c513f8b55d949127f10bc30 --- /dev/null +++ b/src/tests/oeccpsc22/nginx-ingress-controller-dom1.yaml @@ -0,0 +1,134 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: ConfigMap +metadata: + name: nginx-load-balancer-microk8s-conf-dom1 + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-udp-microk8s-conf-dom1 + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-tcp-microk8s-conf-dom1 + namespace: ingress +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: tfs-ingress-class-dom1 + annotations: + ingressclass.kubernetes.io/is-default-class: "false" +spec: + controller: tfs.etsi.org/controller-class-dom1 +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: nginx-ingress-microk8s-controller-dom1 + namespace: ingress + labels: + microk8s-application: nginx-ingress-microk8s-dom1 +spec: + selector: + matchLabels: + name: nginx-ingress-microk8s-dom1 + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: nginx-ingress-microk8s-dom1 + spec: + terminationGracePeriodSeconds: 60 + restartPolicy: Always + serviceAccountName: nginx-ingress-microk8s-serviceaccount + containers: + - image: k8s.gcr.io/ingress-nginx/controller:v1.2.0 + imagePullPolicy: IfNotPresent + name: nginx-ingress-microk8s + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 # www-data + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + hostPort: 8001 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 4431 + protocol: TCP + - name: health + containerPort: 10254 + hostPort: 12541 + protocol: TCP + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-dom1 + - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-microk8s-conf-dom1 + - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-microk8s-conf-dom1 + - --election-id=ingress-controller-leader-dom1 + - --controller-class=tfs.etsi.org/controller-class-dom1 + - --ingress-class=tfs-ingress-class-dom1 + - ' ' + - --publish-status-address=127.0.0.1 diff --git a/src/tests/oeccpsc22/nginx-ingress-controller-dom2.yaml b/src/tests/oeccpsc22/nginx-ingress-controller-dom2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dede032850092733aa9b3136f20ecf078b2ce05a --- /dev/null +++ b/src/tests/oeccpsc22/nginx-ingress-controller-dom2.yaml @@ -0,0 +1,134 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: ConfigMap +metadata: + name: nginx-load-balancer-microk8s-conf-dom2 + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-udp-microk8s-conf-dom2 + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-tcp-microk8s-conf-dom2 + namespace: ingress +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: tfs-ingress-class-dom2 + annotations: + ingressclass.kubernetes.io/is-default-class: "false" +spec: + controller: tfs.etsi.org/controller-class-dom2 +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: nginx-ingress-microk8s-controller-dom2 + namespace: ingress + labels: + microk8s-application: nginx-ingress-microk8s-dom2 +spec: + selector: + matchLabels: + name: nginx-ingress-microk8s-dom2 + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: nginx-ingress-microk8s-dom2 + spec: + terminationGracePeriodSeconds: 60 + restartPolicy: Always + serviceAccountName: nginx-ingress-microk8s-serviceaccount + containers: + - image: k8s.gcr.io/ingress-nginx/controller:v1.2.0 + imagePullPolicy: IfNotPresent + name: nginx-ingress-microk8s + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 # www-data + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + hostPort: 8002 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 4432 + protocol: TCP + - name: health + containerPort: 10254 + hostPort: 12542 + protocol: TCP + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-dom2 + - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-microk8s-conf-dom2 + - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-microk8s-conf-dom2 + - --election-id=ingress-controller-leader-dom2 + - --controller-class=tfs.etsi.org/controller-class-dom2 + - --ingress-class=tfs-ingress-class-dom2 + - ' ' + - --publish-status-address=127.0.0.1 diff --git a/src/tests/oeccpsc22/nginx-ingress-http-dom1.yaml b/src/tests/oeccpsc22/nginx-ingress-http-dom1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b03699946e6a81e6cb8a91379f0952c2894e6578 --- /dev/null +++ b/src/tests/oeccpsc22/nginx-ingress-http-dom1.yaml @@ -0,0 +1,46 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tfs-ingress-dom1 + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: tfs-ingress-class-dom1 + rules: + - http: + paths: + - path: /webui(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 8004 + - path: /grafana(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 3000 + - path: /()(restconf/.*) + pathType: Prefix + backend: + service: + name: computeservice + port: + number: 8080 diff --git a/src/tests/oeccpsc22/nginx-ingress-http-dom2.yaml b/src/tests/oeccpsc22/nginx-ingress-http-dom2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d07b73ee2a94d6ed54b4b5658c595e1ce635bddb --- /dev/null +++ b/src/tests/oeccpsc22/nginx-ingress-http-dom2.yaml @@ -0,0 +1,53 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tfs-ingress-dom2 + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: tfs-ingress-class-dom2 + rules: + - http: + paths: + - path: /webui(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 8004 + - path: /grafana(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 3000 + - path: /context(/|$)(.*) + pathType: Prefix + backend: + service: + name: contextservice + port: + number: 8080 + - path: /()(restconf/.*) + pathType: Prefix + backend: + service: + name: computeservice + port: + number: 8080 diff --git a/src/tests/oeccpsc22/deploy_in_kubernetes.sh b/src/tests/oeccpsc22/old/deploy_in_kubernetes.sh similarity index 100% rename from src/tests/oeccpsc22/deploy_in_kubernetes.sh rename to src/tests/oeccpsc22/old/deploy_in_kubernetes.sh diff --git a/src/tests/oeccpsc22/show_deploy.sh b/src/tests/oeccpsc22/show_deploy.sh index d5e9346e51cb5bf6ffa442c0b3f9356176efff5c..77a8b8781701d660ad517c1714b3ec367b31dd1d 100755 --- a/src/tests/oeccpsc22/show_deploy.sh +++ b/src/tests/oeccpsc22/show_deploy.sh @@ -13,14 +13,31 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Deploy TeraFlow instance 1 -printf "TeraFlow Instance 1:\n--------------------\n" -export K8S_NAMESPACE="oeccpsc22-1" -kubectl --namespace $K8S_NAMESPACE get all + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +# Deploy TeraFlow Domain 1 +printf "TeraFlow Domain 1:\n--------------------\n" + +echo "Deployment Resources:" +kubectl --namespace tfs-dom1 get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs-dom1 get ingress +printf "\n" printf "\n\n" -# Deploy TeraFlow instance 2 -printf "TeraFlow Instance 2:\n--------------------\n" -export K8S_NAMESPACE="oeccpsc22-2" -kubectl --namespace $K8S_NAMESPACE get all +# Deploy TeraFlow Domain 2 +printf "TeraFlow Domain 2:\n--------------------\n" + +echo "Deployment Resources:" +kubectl --namespace tfs-dom2 get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs-dom2 get ingress +printf "\n" diff --git a/src/tests/ofc22/descriptors_emulated.json b/src/tests/ofc22/descriptors_emulated.json index aa76edecd116ee7336fc1a2621d2bc3ae95080ce..b68b9636d58d9c80c4774e4ade557f83796ac5b5 100644 --- a/src/tests/ofc22/descriptors_emulated.json +++ b/src/tests/ofc22/descriptors_emulated.json @@ -97,6 +97,35 @@ {"device_id": {"device_uuid": {"uuid": "R4-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}}, {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} ] + }, + + { + "link_id": {"link_uuid": {"uuid": "O1-OLS==R1-EMU/13/0/0/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, + {"device_id": {"device_uuid": {"uuid": "R1-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "O1-OLS==R2-EMU/13/0/0/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, + {"device_id": {"device_uuid": {"uuid": "R2-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "O1-OLS==R3-EMU/13/0/0/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, + {"device_id": {"device_uuid": {"uuid": "R3-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "O1-OLS==R4-EMU/13/0/0/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, + {"device_id": {"device_uuid": {"uuid": "R4-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}} + ] } ] } \ No newline at end of file diff --git a/src/tests/ofc22/descriptors_emulated_xr.json b/src/tests/ofc22/descriptors_emulated_xr.json index 4e247bb30d4df25fa75d30a3baa94f1348c0a6d9..b873d31143406a5f6cedbf19c1b357f2223d42d9 100644 --- a/src/tests/ofc22/descriptors_emulated_xr.json +++ b/src/tests/ofc22/descriptors_emulated_xr.json @@ -96,6 +96,18 @@ "device_operational_status": 1, "device_drivers": [6], "device_endpoints": [] + }, + { + "device_id": {"device_uuid": {"uuid": "X2-XR-CONSTELLATION"}}, + "device_type": "xr-constellation", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "172.19.219.44"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": "{\"username\": \"xr-user-1\", \"password\": \"xr-user-1\", \"hub_module_name\": \"XR HUB 2\", \"consistency-mode\": \"lifecycle\"}"}} + ]}, + "device_operational_status": 1, + "device_drivers": [6], + "device_endpoints": [] } ], "links": [ diff --git a/src/tests/ofc23/.gitignore b/src/tests/ofc23/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0a3f4400d5c88b1af32c7667d69d2fdc12d5424e --- /dev/null +++ b/src/tests/ofc23/.gitignore @@ -0,0 +1,2 @@ +# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc. +descriptors_real.json diff --git a/src/tests/ofc23/MultiIngressController.txt b/src/tests/ofc23/MultiIngressController.txt new file mode 100644 index 0000000000000000000000000000000000000000..190e6df7425983db43d8b1888f29861ec9056ed6 --- /dev/null +++ b/src/tests/ofc23/MultiIngressController.txt @@ -0,0 +1,23 @@ +# Ref: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/ +# Ref: https://fabianlee.org/2021/07/29/kubernetes-microk8s-with-multiple-metallb-endpoints-and-nginx-ingress-controllers/ + +# Check node limits +kubectl describe nodes + +# Create secondary ingress controllers +kubectl apply -f ofc23/nginx-ingress-controller-parent.yaml +kubectl apply -f ofc23/nginx-ingress-controller-child.yaml + +# Delete secondary ingress controllers +kubectl delete -f ofc23/nginx-ingress-controller-parent.yaml +kubectl delete -f ofc23/nginx-ingress-controller-child.yaml + +source ofc23/deploy_specs_parent.sh +./deploy/all.sh + +source ofc23/deploy_specs_child.sh +./deploy/all.sh + +# Manually deploy ingresses for instances +kubectl --namespace tfs-parent apply -f ofc23/tfs-ingress-parent.yaml +kubectl --namespace tfs-child apply -f ofc23/tfs-ingress-child.yaml diff --git a/src/opticalcentralizedattackdetector/client/__init__.py b/src/tests/ofc23/__init__.py similarity index 100% rename from src/opticalcentralizedattackdetector/client/__init__.py rename to src/tests/ofc23/__init__.py diff --git a/src/tests/ofc23/delete_hierar.sh b/src/tests/ofc23/delete_hierar.sh new file mode 100755 index 0000000000000000000000000000000000000000..4a03dad1cc29cff72347f68bc7b1a082924a9211 --- /dev/null +++ b/src/tests/ofc23/delete_hierar.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-parent tfs-child + +# Delete secondary ingress controllers +kubectl delete -f ofc23/nginx-ingress-controller-parent.yaml +kubectl delete -f ofc23/nginx-ingress-controller-child.yaml diff --git a/src/tests/ofc23/delete_sligrp.sh b/src/tests/ofc23/delete_sligrp.sh new file mode 100755 index 0000000000000000000000000000000000000000..cce0bd53febc4765f9d455619f49ea4de8dfe870 --- /dev/null +++ b/src/tests/ofc23/delete_sligrp.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs diff --git a/src/tests/ofc23/deploy_child.sh b/src/tests/ofc23/deploy_child.sh new file mode 100755 index 0000000000000000000000000000000000000000..9b05ed88739114bf9029d8afaf491d7fec726bff --- /dev/null +++ b/src/tests/ofc23/deploy_child.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-child + +# Delete secondary ingress controllers +kubectl delete -f ofc23/nginx-ingress-controller-child.yaml + +# Create secondary ingress controllers +kubectl apply -f ofc23/nginx-ingress-controller-child.yaml + +# Deploy TFS for Child +source ofc23/deploy_specs_child.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_child.sh diff --git a/src/tests/ofc23/deploy_hierar.sh b/src/tests/ofc23/deploy_hierar.sh new file mode 100755 index 0000000000000000000000000000000000000000..4874688ad7561156b1b5fc4c80b72a9745feb6a0 --- /dev/null +++ b/src/tests/ofc23/deploy_hierar.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-parent tfs-child + +# Delete secondary ingress controllers +kubectl delete -f ofc23/nginx-ingress-controller-parent.yaml +kubectl delete -f ofc23/nginx-ingress-controller-child.yaml + +# Create secondary ingress controllers +kubectl apply -f ofc23/nginx-ingress-controller-parent.yaml +kubectl apply -f ofc23/nginx-ingress-controller-child.yaml + +# Deploy TFS for Parent +source ofc23/deploy_specs_parent.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_parent.sh + +# Deploy TFS for Child +source ofc23/deploy_specs_child.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_child.sh diff --git a/src/tests/ofc23/deploy_parent.sh b/src/tests/ofc23/deploy_parent.sh new file mode 100755 index 0000000000000000000000000000000000000000..ac4a2954213cf577efe1b1a8e499635d80ea3548 --- /dev/null +++ b/src/tests/ofc23/deploy_parent.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-parent + +# Delete secondary ingress controllers +kubectl delete -f ofc23/nginx-ingress-controller-parent.yaml + +# Create secondary ingress controllers +kubectl apply -f ofc23/nginx-ingress-controller-parent.yaml + +# Deploy TFS for Parent +source ofc23/deploy_specs_parent.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_parent.sh diff --git a/src/tests/ofc23/deploy_sligrp.sh b/src/tests/ofc23/deploy_sligrp.sh new file mode 100755 index 0000000000000000000000000000000000000000..62a9df5cf006af856f168add4058d63eaa905784 --- /dev/null +++ b/src/tests/ofc23/deploy_sligrp.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +# Delete old namespaces +kubectl delete namespace tfs-sligrp + +# Deploy TFS for Slice Goruping +source ofc23/deploy_specs_sligrp.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_sligrp.sh diff --git a/src/tests/ofc23/deploy_specs_child.sh b/src/tests/ofc23/deploy_specs_child.sh new file mode 100755 index 0000000000000000000000000000000000000000..4d2b3502294925d82f675263fd6bddea62ec181a --- /dev/null +++ b/src/tests/ofc23/deploy_specs_child.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. +#automation monitoring load_generator +export TFS_COMPONENTS="context device pathcomp service slice compute webui" + +# 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-child" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="ofc23/tfs-ingress-child.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="YES" + + +# ----- 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 the database name to be used by Context. +export CRDB_DATABASE="tfs_child" + +# 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-child" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4224" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8224" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-child" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8814" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9012" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9002" + +# 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="YES" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/src/tests/ofc23/deploy_specs_parent.sh b/src/tests/ofc23/deploy_specs_parent.sh new file mode 100755 index 0000000000000000000000000000000000000000..808f4e28734be71e6eb7fb2aced39211fd8e7f24 --- /dev/null +++ b/src/tests/ofc23/deploy_specs_parent.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. +#automation monitoring load_generator +export TFS_COMPONENTS="context device pathcomp service slice compute webui" + +# 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-parent" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="ofc23/tfs-ingress-parent.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 the database name to be used by Context. +export CRDB_DATABASE="tfs_parent" + +# 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-parent" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4223" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8223" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-parent" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8813" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9011" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9001" + +# 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="YES" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/src/tests/ofc23/deploy_specs_sligrp.sh b/src/tests/ofc23/deploy_specs_sligrp.sh new file mode 100755 index 0000000000000000000000000000000000000000..90bea4567bd35d845abf943670f8aa33070dff57 --- /dev/null +++ b/src/tests/ofc23/deploy_specs_sligrp.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. +#automation monitoring load_generator +export TFS_COMPONENTS="context device pathcomp service slice webui 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-sligrp" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.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 the database name to be used by Context. +export CRDB_DATABASE="tfs_sligrp" + +# 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-sligrp" + +# 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" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-sligrp" + +# 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="9010" + +# 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="YES" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/src/tests/ofc23/descriptors/adva-interfaces.txt b/src/tests/ofc23/descriptors/adva-interfaces.txt new file mode 100644 index 0000000000000000000000000000000000000000..a634735058aa9490ddbd43e8e9a0752fbd4a6ee6 --- /dev/null +++ b/src/tests/ofc23/descriptors/adva-interfaces.txt @@ -0,0 +1,89 @@ +R199 +eth-1/0/1 +eth-1/0/10 +eth-1/0/11 +eth-1/0/12 +eth-1/0/13 +eth-1/0/14 +eth-1/0/15 +eth-1/0/16 +eth-1/0/17 +eth-1/0/18 +eth-1/0/19 +eth-1/0/2 +eth-1/0/20 +eth-1/0/21 +eth-1/0/22 +eth-1/0/23 +eth-1/0/24 +eth-1/0/25 +eth-1/0/26 +eth-1/0/27 +eth-1/0/28 +eth-1/0/29 +eth-1/0/3 +eth-1/0/30 +eth-1/0/4 +eth-1/0/5 +eth-1/0/6 +eth-1/0/7 +eth-1/0/8 +eth-1/0/9 + +R155 +eth-1/0/1 +eth-1/0/10 +eth-1/0/11 +eth-1/0/12 +eth-1/0/13 +eth-1/0/14 +eth-1/0/15 +eth-1/0/16 +eth-1/0/17 +eth-1/0/18 +eth-1/0/19 +eth-1/0/2 +eth-1/0/20 +eth-1/0/21 +eth-1/0/22 +eth-1/0/23 +eth-1/0/24 +eth-1/0/25 +eth-1/0/26 +eth-1/0/27 +eth-1/0/3 +eth-1/0/4 +eth-1/0/5 +eth-1/0/6 +eth-1/0/7 +eth-1/0/8 +eth-1/0/9 + +R149 +eth-1/0/1 +eth-1/0/10 +eth-1/0/11 +eth-1/0/12 +eth-1/0/13 +eth-1/0/14 +eth-1/0/15 +eth-1/0/16 +eth-1/0/17 +eth-1/0/18 +eth-1/0/19 +eth-1/0/2 +eth-1/0/20 +eth-1/0/21 +eth-1/0/22 +eth-1/0/23 +eth-1/0/24 +eth-1/0/25 +eth-1/0/26 +eth-1/0/27 +eth-1/0/3 +eth-1/0/4 +eth-1/0/5 +eth-1/0/6 +eth-1/0/7 +eth-1/0/8 +eth-1/0/9 diff --git a/src/tests/ofc23/descriptors/backup/dc-2-dc-service.json b/src/tests/ofc23/descriptors/backup/dc-2-dc-service.json new file mode 100644 index 0000000000000000000000000000000000000000..3a83afa6de81f137204aecc5f0eca476aad71e61 --- /dev/null +++ b/src/tests/ofc23/descriptors/backup/dc-2-dc-service.json @@ -0,0 +1,37 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "dc-2-dc-svc"} + }, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id":{"device_uuid":{"uuid":"DC1"}},"endpoint_uuid":{"uuid":"int"}}, + {"device_id":{"device_uuid":{"uuid":"DC2"}},"endpoint_uuid":{"uuid":"int"}} + ], + "service_constraints": [ + {"sla_capacity": {"capacity_gbps": 10.0}}, + {"sla_latency": {"e2e_latency_ms": 15.2}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "address_families": ["IPV4"], "bgp_as": 65000, "bgp_route_target": "65000:123", + "mtu": 1512, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R149]/endpoint[eth-1/0/22]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "5.5.5.5", + "address_ip": "172.16.4.1", "address_prefix": 24, "sub_interface_index": 0, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R155]/endpoint[eth-1/0/22]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "5.5.5.1", + "address_ip": "172.16.2.1", "address_prefix": 24, "sub_interface_index": 0, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R199]/endpoint[eth-1/0/21]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "5.5.5.6", + "address_ip": "172.16.1.1", "address_prefix": 24, "sub_interface_index": 0, "vlan_id": 111 + }}} + ]} + } + ] +} diff --git a/src/tests/ofc23/descriptors/backup/descriptor_child.json b/src/tests/ofc23/descriptors/backup/descriptor_child.json new file mode 100644 index 0000000000000000000000000000000000000000..eea9571531cfbebfcc53dba0679d1bd1b6900b2f --- /dev/null +++ b/src/tests/ofc23/descriptors/backup/descriptor_child.json @@ -0,0 +1,183 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R199"}}, "device_type": "packet-router", "device_drivers": [1], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.199"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"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": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120}, + "endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/4"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/5"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/6"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/7"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/8"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/9"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/10"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/11"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/12"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/13"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/14"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/15"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/16"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/17"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/18"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/19"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/20"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/21"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/22"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/23"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/24"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/25"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/26"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/27"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/28"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/29"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/30"} + ] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R155"}}, "device_type": "packet-router", "device_drivers": [1], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.155"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"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": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120}, + "endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/4"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/5"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/6"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/7"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/8"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/9"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/10"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/11"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/12"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/13"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/14"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/15"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/16"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/17"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/18"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/19"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/20"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/21"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/22"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/23"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/24"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/25"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/26"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/27"} + ] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R149"}}, "device_type": "packet-router", "device_drivers": [1], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.149"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"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": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120}, + "endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/4"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/5"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/6"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/7"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/8"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/9"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/10"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/11"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/12"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/13"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/14"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/15"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/16"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/17"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/18"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/19"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/20"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/21"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/22"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/23"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/24"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/25"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/26"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth-1/0/27"} + ] + }}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/19==R155/eth-1/0/19"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/19==R199/eth-1/0/19"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/20==R149/eth-1/0/20"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/20==R199/eth-1/0/20"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/25==R155/eth-1/0/25"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/25==R149/eth-1/0/25"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + } + ] +} diff --git a/src/tests/ofc23/descriptors/backup/descriptor_parent.json b/src/tests/ofc23/descriptors/backup/descriptor_parent.json new file mode 100644 index 0000000000000000000000000000000000000000..42b60e3cf09285955fbfbc567d977e60f78956be --- /dev/null +++ b/src/tests/ofc23/descriptors/backup/descriptor_parent.json @@ -0,0 +1,258 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "scheme": "http", "username": "admin", "password": "admin" + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW"}}, "device_type": "microwave-radio-system", "device_drivers": [4, 5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "nms5ux", "password": "nms5ux", "timeout": 120, "scheme": "https", + "node_ids": ["192.168.27.139", "192.168.27.140"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, "device_type": "open-line-system", "device_drivers": [2], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "cttc-ols.cttc-ols.svc.cluster.local"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "4900"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "IPM"}}, "device_type": "xr-constellation", "device_drivers": [6], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8444"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "xr-user-1", "password": "xr-user-1", "hub_module_name": "OFC HUB 1", + "consistency-mode": "lifecycle", "import_topology": "devices" + }}} + ]} + }, + + + { + "device_id": {"device_uuid": {"uuid": "DC1"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "device_type": "emu-optical-splitter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "optical/internal", "uuid": "common"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf1"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf2"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf3"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC2"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "DC1/eth1==R149/eth-1/0/22"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/22==DC1/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/9==MW/192.168.27.140:5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/9"}}, + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.140:5"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW/192.168.27.140:5==R149/eth-1/0/9"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.140:5"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/9"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW/192.168.27.139:5==OFC HUB 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.139:5"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/1/1==MW/192.168.27.139:5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.139:5"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/XR-T1==Optical-Splitter/common"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/common==OFC HUB 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf1==OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/79516f5e-55a0-5671-977a-1f5cc934e700==Optical-Splitter/leaf1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "79516f5e-55a0-5671-977a-1f5cc934e700"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf2==OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/30d9323e-b916-51ce-a9a8-cf88f62eb77f==Optical-Splitter/leaf2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "30d9323e-b916-51ce-a9a8-cf88f62eb77f"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/XR-T1==OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/68ac012e-54d4-5846-b5dc-6ec356404f90==OFC LEAF 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "68ac012e-54d4-5846-b5dc-6ec356404f90"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/XR-T1==OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/367b19b1-3172-54d8-bdd4-12d3ac5604f6==OFC LEAF 2/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "367b19b1-3172-54d8-bdd4-12d3ac5604f6"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/1/1==R155/eth-1/0/25"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/25==OFC LEAF 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/1/1==R199/eth-1/0/20"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/20==OFC LEAF 2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/22==DC2/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth1==R155/eth-1/0/22"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/21==DC2/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth2==R199/eth-1/0/21"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}} + ] + } + ] +} diff --git a/src/tests/ofc23/descriptors/emulated/dc-2-dc-service.json b/src/tests/ofc23/descriptors/emulated/dc-2-dc-service.json new file mode 100644 index 0000000000000000000000000000000000000000..7c3be015d0965d4bdaed8e225e79da072a7de6f3 --- /dev/null +++ b/src/tests/ofc23/descriptors/emulated/dc-2-dc-service.json @@ -0,0 +1,41 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "dc-2-dc-svc"} + }, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id":{"device_uuid":{"uuid":"DC1"}},"endpoint_uuid":{"uuid":"int"}}, + {"device_id":{"device_uuid":{"uuid":"DC2"}},"endpoint_uuid":{"uuid":"int"}} + ], + "service_constraints": [ + {"sla_capacity": {"capacity_gbps": 10.0}}, + {"sla_latency": {"e2e_latency_ms": 15.2}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "address_families": ["IPV4"], "bgp_as": 65000, "bgp_route_target": "65000:123", + "mtu": 1512, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE1]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.1", + "address_ip": "3.3.1.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE2]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.2", + "address_ip": "3.3.2.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE3]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.3", + "address_ip": "3.3.3.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE4]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.4", + "address_ip": "3.3.4.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}} + ]} + } + ] +} diff --git a/src/tests/ofc23/descriptors/emulated/descriptor_child.json b/src/tests/ofc23/descriptors/emulated/descriptor_child.json new file mode 100644 index 0000000000000000000000000000000000000000..1dc6fd35531db1989b9b85c846b6fc8d0524f08f --- /dev/null +++ b/src/tests/ofc23/descriptors/emulated/descriptor_child.json @@ -0,0 +1,149 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "PE1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "PE2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "PE3"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "PE4"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + ]}}} + ]} + } + ], + "links": [ + + { + "link_id": {"link_uuid": {"uuid": "PE1/2/2==PE2/2/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE1/2/3==PE3/2/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "2/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE1/2/4==PE4/2/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "2/4"}}, + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "2/1"}} + ] + }, + + { + "link_id": {"link_uuid": {"uuid": "PE2/2/1==PE1/2/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE2/2/3==PE3/2/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE2/2/4==PE4/2/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/4"}}, + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + + { + "link_id": {"link_uuid": {"uuid": "PE3/2/1==PE1/2/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "2/3"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE3/2/2==PE2/2/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/3"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE4/2/2==PE2/2/4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/4"}} + ] + }, + + { + "link_id": {"link_uuid": {"uuid": "PE4/2/1==PE1/2/4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "2/4"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE4/2/2==PE2/2/4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "2/2"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "2/4"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE4/2/3==PE3/2/4"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "2/4"}} + ] + } + + ] +} diff --git a/src/tests/ofc23/descriptors/emulated/descriptor_parent.json b/src/tests/ofc23/descriptors/emulated/descriptor_parent.json new file mode 100644 index 0000000000000000000000000000000000000000..1b1f5dbfd57b2e1543e86ba8d2633a0e944fced5 --- /dev/null +++ b/src/tests/ofc23/descriptors/emulated/descriptor_parent.json @@ -0,0 +1,258 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "scheme": "http", "username": "admin", "password": "admin" + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW"}}, "device_type": "microwave-radio-system", "device_drivers": [4, 5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", "timeout": 120, "scheme": "https", + "node_ids": ["192.168.27.139", "192.168.27.140"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, "device_type": "open-line-system", "device_drivers": [2], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "cttc-ols.cttc-ols.svc.cluster.local"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "4900"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "IPM"}}, "device_type": "xr-constellation", "device_drivers": [6], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8444"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "xr-user-1", "password": "xr-user-1", "hub_module_name": "OFC HUB 1", + "consistency-mode": "lifecycle", "import_topology": "devices" + }}} + ]} + }, + + + { + "device_id": {"device_uuid": {"uuid": "DC1"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "device_type": "emu-optical-splitter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "optical/internal", "uuid": "common"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf1"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf2"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf3"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC2"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "DC1/eth1==R149/eth-1/0/22"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/22==DC1/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/9==MW/192.168.27.140:5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/9"}}, + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.140:5"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW/192.168.27.140:5==R149/eth-1/0/9"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.140:5"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/9"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW/192.168.27.139:5==OFC HUB 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.139:5"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/1/1==MW/192.168.27.139:5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.139:5"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/XR-T1==Optical-Splitter/common"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/common==OFC HUB 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf1==OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/79516f5e-55a0-5671-977a-1f5cc934e700==Optical-Splitter/leaf1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "79516f5e-55a0-5671-977a-1f5cc934e700"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf2==OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/30d9323e-b916-51ce-a9a8-cf88f62eb77f==Optical-Splitter/leaf2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "30d9323e-b916-51ce-a9a8-cf88f62eb77f"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/XR-T1==OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/68ac012e-54d4-5846-b5dc-6ec356404f90==OFC LEAF 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "68ac012e-54d4-5846-b5dc-6ec356404f90"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/XR-T1==OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/367b19b1-3172-54d8-bdd4-12d3ac5604f6==OFC LEAF 2/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "367b19b1-3172-54d8-bdd4-12d3ac5604f6"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/1/1==R155/eth-1/0/25"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/25==OFC LEAF 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/1/1==R199/eth-1/0/20"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/20==OFC LEAF 2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/22==DC2/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth1==R155/eth-1/0/22"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/21==DC2/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth2==R199/eth-1/0/21"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}} + ] + } + ] +} diff --git a/src/tests/ofc23/descriptors/emulated/descriptor_parent_noxr.json b/src/tests/ofc23/descriptors/emulated/descriptor_parent_noxr.json new file mode 100644 index 0000000000000000000000000000000000000000..c4a6646ede081fc2f6ee449d7771de3dbcbd77ec --- /dev/null +++ b/src/tests/ofc23/descriptors/emulated/descriptor_parent_noxr.json @@ -0,0 +1,332 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "scheme": "http", "username": "admin", "password": "admin" + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW1-2"}}, "device_type": "microwave-radio-system", "device_drivers": [5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", "timeout": 120, "scheme": "https", + "node_ids": ["172.18.0.1", "172.18.0.2"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW3-4"}}, "device_type": "microwave-radio-system", "device_drivers": [5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", "timeout": 120, "scheme": "https", + "node_ids": ["172.18.0.3", "172.18.0.4"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, "device_type": "open-line-system", "device_drivers": [2], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "cttc-ols.cttc-ols.svc.cluster.local"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "4900"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC1"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "device_type": "emu-optical-splitter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "optical/internal", "uuid": "common"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf1"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf2"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf3"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R3"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC2"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "DC1/eth1==PE1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE1/1/1==DC1/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "DC1/eth2==PE2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE2/1/1==DC1/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE1/1/2==MW1-2/172.18.0.1:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.1:1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW1-2/172.18.0.1:1==PE1/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.1:1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW1-2/172.18.0.2:1==R1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.2:1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R1/1/1==MW1-2/172.18.0.2:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.2:1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE2/1/2==MW3-4/172.18.0.3:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.3:1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW3-4/172.18.0.3:1==PE2/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.3:1"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW3-4/172.18.0.4:1==R1/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.4:1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R1/1/2==MW3-4/172.18.0.4:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.4:1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R1/1/3==Optical-Splitter/common"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/3"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/common==R1/1/3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/3"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf1==OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/79516f5e-55a0-5671-977a-1f5cc934e700==Optical-Splitter/leaf1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "79516f5e-55a0-5671-977a-1f5cc934e700"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf2==OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/30d9323e-b916-51ce-a9a8-cf88f62eb77f==Optical-Splitter/leaf2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "30d9323e-b916-51ce-a9a8-cf88f62eb77f"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R2/1/1==OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/68ac012e-54d4-5846-b5dc-6ec356404f90==R2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "68ac012e-54d4-5846-b5dc-6ec356404f90"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R3/1/1==OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/367b19b1-3172-54d8-bdd4-12d3ac5604f6==R3/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "367b19b1-3172-54d8-bdd4-12d3ac5604f6"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R2/1/2==PE3/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE3/1/2==R2/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R3/1/2==PE4/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE4/1/2==R3/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE3/1/1==DC2/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth1==PE3/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE4/1/1==DC2/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth2==PE4/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + } + ] +} diff --git a/src/tests/ofc23/descriptors/emulated/ipm-ctrl.json b/src/tests/ofc23/descriptors/emulated/ipm-ctrl.json new file mode 100644 index 0000000000000000000000000000000000000000..91e9de611dac2627525bb11f81755ea651887e74 --- /dev/null +++ b/src/tests/ofc23/descriptors/emulated/ipm-ctrl.json @@ -0,0 +1,25 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"topology_uuid": {"uuid": "admin"}, "context_id": {"context_uuid": {"uuid": "admin"}}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "XR-CONSTELLATION"}}, + "device_type": "xr-constellation", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8444"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "xr-user-1", "password": "xr-user-1", "hub_module_name": "OFC HUB 1", + "consistency-mode": "lifecycle" + }}} + ]}, + "device_operational_status": 1, + "device_drivers": [6], + "device_endpoints": [] + } + ] +} diff --git a/src/tests/ofc23/descriptors/emulated/old/descriptor_parent.json b/src/tests/ofc23/descriptors/emulated/old/descriptor_parent.json new file mode 100644 index 0000000000000000000000000000000000000000..413b7566292d7841777547aeb665c7eb3b8ca293 --- /dev/null +++ b/src/tests/ofc23/descriptors/emulated/old/descriptor_parent.json @@ -0,0 +1,311 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "scheme": "http", "username": "admin", "password": "admin" + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW1-2"}}, "device_type": "microwave-radio-system", "device_drivers": [5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", "timeout": 120, "scheme": "https", + "node_ids": ["172.18.0.1", "172.18.0.2"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW3-4"}}, "device_type": "microwave-radio-system", "device_drivers": [5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", "timeout": 120, "scheme": "https", + "node_ids": ["172.18.0.3", "172.18.0.4"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, "device_type": "open-line-system", "device_drivers": [2], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "cttc-ols.cttc-ols.svc.cluster.local"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "4900"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "IPM"}}, "device_type": "xr-constellation", "device_drivers": [6], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8444"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "xr-user-1", "password": "xr-user-1", "hub_module_name": "OFC HUB 1", + "consistency-mode": "lifecycle", "import_topology": "devices" + }}} + ]} + }, + + + { + "device_id": {"device_uuid": {"uuid": "DC1"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "device_type": "emu-optical-splitter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "optical/internal", "uuid": "common"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf1"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf2"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf3"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC2"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "DC1/eth1==PE1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE1/1/1==DC1/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "DC1/eth2==PE2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE2/1/1==DC1/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE1/1/2==MW1-2/172.18.0.1:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.1:1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW1-2/172.18.0.1:1==PE1/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.1:1"}}, + {"device_id": {"device_uuid": {"uuid": "PE1"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW1-2/172.18.0.2:1==OFC HUB 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.2:1"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/1/1==MW1-2/172.18.0.2:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "MW1-2"}}, "endpoint_uuid": {"uuid": "172.18.0.2:1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE2/1/2==MW3-4/172.18.0.3:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.3:1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW3-4/172.18.0.3:1==PE2/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.3:1"}}, + {"device_id": {"device_uuid": {"uuid": "PE2"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW3-4/172.18.0.4:1==OFC HUB 1/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.4:1"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/1/2==MW3-4/172.18.0.4:1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "MW3-4"}}, "endpoint_uuid": {"uuid": "172.18.0.4:1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/XR-T1==Optical-Splitter/common"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/common==OFC HUB 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf1==OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/79516f5e-55a0-5671-977a-1f5cc934e700==Optical-Splitter/leaf1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "79516f5e-55a0-5671-977a-1f5cc934e700"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf2==OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/30d9323e-b916-51ce-a9a8-cf88f62eb77f==Optical-Splitter/leaf2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "30d9323e-b916-51ce-a9a8-cf88f62eb77f"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/XR-T1==OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/68ac012e-54d4-5846-b5dc-6ec356404f90==OFC LEAF 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "68ac012e-54d4-5846-b5dc-6ec356404f90"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/XR-T1==OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/367b19b1-3172-54d8-bdd4-12d3ac5604f6==OFC LEAF 2/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "367b19b1-3172-54d8-bdd4-12d3ac5604f6"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/1/1==PE3/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE3/1/2==OFC LEAF 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/1/1==PE4/1/2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "PE4/1/2==OFC LEAF 2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE3/1/1==DC2/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth1==PE3/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "PE3"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "PE4/1/1==DC2/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth2==PE4/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "PE4"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + } + ] +} diff --git a/src/tests/ofc23/descriptors/real/dc-2-dc-service.json b/src/tests/ofc23/descriptors/real/dc-2-dc-service.json new file mode 100644 index 0000000000000000000000000000000000000000..3a83afa6de81f137204aecc5f0eca476aad71e61 --- /dev/null +++ b/src/tests/ofc23/descriptors/real/dc-2-dc-service.json @@ -0,0 +1,37 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "dc-2-dc-svc"} + }, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id":{"device_uuid":{"uuid":"DC1"}},"endpoint_uuid":{"uuid":"int"}}, + {"device_id":{"device_uuid":{"uuid":"DC2"}},"endpoint_uuid":{"uuid":"int"}} + ], + "service_constraints": [ + {"sla_capacity": {"capacity_gbps": 10.0}}, + {"sla_latency": {"e2e_latency_ms": 15.2}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "address_families": ["IPV4"], "bgp_as": 65000, "bgp_route_target": "65000:123", + "mtu": 1512, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R149]/endpoint[eth-1/0/22]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "5.5.5.5", + "address_ip": "172.16.4.1", "address_prefix": 24, "sub_interface_index": 0, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R155]/endpoint[eth-1/0/22]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "5.5.5.1", + "address_ip": "172.16.2.1", "address_prefix": 24, "sub_interface_index": 0, "vlan_id": 111 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R199]/endpoint[eth-1/0/21]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "5.5.5.6", + "address_ip": "172.16.1.1", "address_prefix": 24, "sub_interface_index": 0, "vlan_id": 111 + }}} + ]} + } + ] +} diff --git a/src/tests/ofc23/descriptors/real/descriptor_child.json b/src/tests/ofc23/descriptors/real/descriptor_child.json new file mode 100644 index 0000000000000000000000000000000000000000..8d695cfd2d419f263b554d0f2bf648b92cdde672 --- /dev/null +++ b/src/tests/ofc23/descriptors/real/descriptor_child.json @@ -0,0 +1,93 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R199"}}, "device_type": "packet-router", "device_drivers": [1], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.199"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"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": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 86400} + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R149"}}, "device_type": "packet-router", "device_drivers": [1], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.149"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"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": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 86400} + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R155"}}, "device_type": "packet-router", "device_drivers": [1], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.155"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "830"}}, + {"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": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 86400} + }}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/19==R155/eth-1/0/19"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/19==R199/eth-1/0/19"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/19"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/20==R149/eth-1/0/20"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/20==R199/eth-1/0/20"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/25==R155/eth-1/0/25"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/25==R149/eth-1/0/25"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + } + ] +} diff --git a/src/tests/ofc23/descriptors/real/descriptor_parent.json b/src/tests/ofc23/descriptors/real/descriptor_parent.json new file mode 100644 index 0000000000000000000000000000000000000000..3317d46edaf6d270125d8b094c3b6384a3dd52fd --- /dev/null +++ b/src/tests/ofc23/descriptors/real/descriptor_parent.json @@ -0,0 +1,258 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "scheme": "http", "username": "admin", "password": "admin" + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "MW"}}, "device_type": "microwave-radio-system", "device_drivers": [4, 5], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "192.168.27.136"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "nms5ux", "password": "nms5ux", "timeout": 120, "scheme": "https", + "node_ids": ["192.168.27.139", "192.168.27.140"] + }}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, "device_type": "open-line-system", "device_drivers": [2], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "cttc-ols.cttc-ols.svc.cluster.local"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "4900"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "IPM"}}, "device_type": "xr-constellation", "device_drivers": [6], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.95.86.126"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "443"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "xr-user-1", "password": "xr-user-1", "hub_module_name": "OFC HUB 1", + "consistency-mode": "lifecycle", "import_topology": "devices" + }}} + ]} + }, + + + { + "device_id": {"device_uuid": {"uuid": "DC1"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "device_type": "emu-optical-splitter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "optical/internal", "uuid": "common"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf1"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf2"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf3"}, + {"sample_types": [], "type": "optical/internal", "uuid": "leaf4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "DC2"}}, "device_type": "emu-datacenter", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "eth1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "eth2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "int"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "DC1/eth1==R149/eth-1/0/22"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/22==DC1/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}}, + {"device_id": {"device_uuid": {"uuid": "DC1"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R149/eth-1/0/9==MW/192.168.27.140:5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/9"}}, + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.140:5"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "MW/192.168.27.140:5==R149/eth-1/0/9"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.140:5"}}, + {"device_id": {"device_uuid": {"uuid": "R149"}}, "endpoint_uuid": {"uuid": "eth-1/0/9"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "MW/192.168.27.139:5==OFC HUB 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.139:5"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/1/1==MW/192.168.27.139:5"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "MW"}}, "endpoint_uuid": {"uuid": "192.168.27.139:5"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC HUB 1/XR-T1==Optical-Splitter/common"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/common==OFC HUB 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "common"}}, + {"device_id": {"device_uuid": {"uuid": "OFC HUB 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf1==OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/79516f5e-55a0-5671-977a-1f5cc934e700==Optical-Splitter/leaf1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "79516f5e-55a0-5671-977a-1f5cc934e700"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "Optical-Splitter/leaf2==OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/30d9323e-b916-51ce-a9a8-cf88f62eb77f==Optical-Splitter/leaf2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "30d9323e-b916-51ce-a9a8-cf88f62eb77f"}}, + {"device_id": {"device_uuid": {"uuid": "Optical-Splitter"}}, "endpoint_uuid": {"uuid": "leaf2"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/XR-T1==OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/68ac012e-54d4-5846-b5dc-6ec356404f90==OFC LEAF 1/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "68ac012e-54d4-5846-b5dc-6ec356404f90"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/XR-T1==OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/367b19b1-3172-54d8-bdd4-12d3ac5604f6==OFC LEAF 2/XR-T1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "367b19b1-3172-54d8-bdd4-12d3ac5604f6"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "XR-T1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 1/1/1==R155/eth-1/0/25"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/25==OFC LEAF 1/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/25"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "OFC LEAF 2/1/1==R199/eth-1/0/20"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/20==OFC LEAF 2/1/1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/20"}}, + {"device_id": {"device_uuid": {"uuid": "OFC LEAF 2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R155/eth-1/0/22==DC2/eth1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth1==R155/eth-1/0/22"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth1"}}, + {"device_id": {"device_uuid": {"uuid": "R155"}}, "endpoint_uuid": {"uuid": "eth-1/0/22"}} + ] + }, + + + { + "link_id": {"link_uuid": {"uuid": "R199/eth-1/0/21==DC2/eth2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}}, + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "DC2/eth2==R199/eth-1/0/21"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "DC2"}}, "endpoint_uuid": {"uuid": "eth2"}}, + {"device_id": {"device_uuid": {"uuid": "R199"}}, "endpoint_uuid": {"uuid": "eth-1/0/21"}} + ] + } + ] +} diff --git a/src/tests/ofc23/dump_logs.sh b/src/tests/ofc23/dump_logs.sh new file mode 100755 index 0000000000000000000000000000000000000000..cc3162b337c1b35e9ff158b400a8d5c47931bdca --- /dev/null +++ b/src/tests/ofc23/dump_logs.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +rm -rf tmp/exec + +echo "Collecting logs for Parent..." +mkdir -p tmp/exec/parent +kubectl --namespace tfs-parent logs deployments/contextservice server > tmp/exec/parent/context.log +kubectl --namespace tfs-parent logs deployments/deviceservice server > tmp/exec/parent/device.log +kubectl --namespace tfs-parent logs deployments/serviceservice server > tmp/exec/parent/service.log +kubectl --namespace tfs-parent logs deployments/pathcompservice frontend > tmp/exec/parent/pathcomp-frontend.log +kubectl --namespace tfs-parent logs deployments/pathcompservice backend > tmp/exec/parent/pathcomp-backend.log +kubectl --namespace tfs-parent logs deployments/sliceservice server > tmp/exec/parent/slice.log +printf "\n" + +echo "Collecting logs for Child..." +mkdir -p tmp/exec/child +kubectl --namespace tfs-child logs deployments/contextservice server > tmp/exec/child/context.log +kubectl --namespace tfs-child logs deployments/deviceservice server > tmp/exec/child/device.log +kubectl --namespace tfs-child logs deployments/serviceservice server > tmp/exec/child/service.log +kubectl --namespace tfs-child logs deployments/pathcompservice frontend > tmp/exec/child/pathcomp-frontend.log +kubectl --namespace tfs-child logs deployments/pathcompservice backend > tmp/exec/child/pathcomp-backend.log +kubectl --namespace tfs-child logs deployments/sliceservice server > tmp/exec/child/slice.log +printf "\n" + +echo "Done!" diff --git a/src/tests/ofc23/fast_redeploy.sh b/src/tests/ofc23/fast_redeploy.sh new file mode 100755 index 0000000000000000000000000000000000000000..58d1193ded582d4fdff3222d5bcdc0fe510a7034 --- /dev/null +++ b/src/tests/ofc23/fast_redeploy.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + + +kubectl delete namespace tfs-parent tfs-child + +echo "Deploying tfs-parent ..." +kubectl delete -f ofc23/nginx-ingress-controller-parent.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl create namespace tfs-parent > ./tmp/logs/deploy-tfs-parent.log +kubectl apply -f ofc23/nginx-ingress-controller-parent.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-parent.log +kubectl --namespace tfs-parent apply -f ofc23/tfs-ingress-parent.yaml > ./tmp/logs/deploy-tfs-parent.log +printf "\n" + +echo "Deploying tfs-child ..." +kubectl delete -f ofc23/nginx-ingress-controller-child.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl create namespace tfs-child > ./tmp/logs/deploy-tfs-child.log +kubectl apply -f ofc23/nginx-ingress-controller-child.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-child.log +kubectl --namespace tfs-child apply -f ofc23/tfs-ingress-child.yaml > ./tmp/logs/deploy-tfs-child.log +printf "\n" + +echo "Waiting tfs-parent ..." +kubectl wait --namespace tfs-parent --for='condition=available' --timeout=300s deployment/contextservice +kubectl wait --namespace tfs-parent --for='condition=available' --timeout=300s deployment/deviceservice +kubectl wait --namespace tfs-parent --for='condition=available' --timeout=300s deployment/pathcompservice +kubectl wait --namespace tfs-parent --for='condition=available' --timeout=300s deployment/serviceservice +kubectl wait --namespace tfs-parent --for='condition=available' --timeout=300s deployment/sliceservice +kubectl wait --namespace tfs-parent --for='condition=available' --timeout=300s deployment/webuiservice +printf "\n" + +echo "Waiting tfs-child ..." +kubectl wait --namespace tfs-child --for='condition=available' --timeout=300s deployment/contextservice +kubectl wait --namespace tfs-child --for='condition=available' --timeout=300s deployment/deviceservice +kubectl wait --namespace tfs-child --for='condition=available' --timeout=300s deployment/pathcompservice +kubectl wait --namespace tfs-child --for='condition=available' --timeout=300s deployment/serviceservice +kubectl wait --namespace tfs-child --for='condition=available' --timeout=300s deployment/sliceservice +kubectl wait --namespace tfs-child --for='condition=available' --timeout=300s deployment/webuiservice +printf "\n" + +echo "Done!" diff --git a/src/tests/ofc23/nginx-ingress-controller-child.yaml b/src/tests/ofc23/nginx-ingress-controller-child.yaml new file mode 100644 index 0000000000000000000000000000000000000000..00a64d75e9a9a2cb93cdbd6d89790e26b0730eb6 --- /dev/null +++ b/src/tests/ofc23/nginx-ingress-controller-child.yaml @@ -0,0 +1,134 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: ConfigMap +metadata: + name: nginx-load-balancer-microk8s-conf-child + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-udp-microk8s-conf-child + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-tcp-microk8s-conf-child + namespace: ingress +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: tfs-ingress-class-child + annotations: + ingressclass.kubernetes.io/is-default-class: "false" +spec: + controller: tfs.etsi.org/controller-class-child +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: nginx-ingress-microk8s-controller-child + namespace: ingress + labels: + microk8s-application: nginx-ingress-microk8s-child +spec: + selector: + matchLabels: + name: nginx-ingress-microk8s-child + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: nginx-ingress-microk8s-child + spec: + terminationGracePeriodSeconds: 60 + restartPolicy: Always + serviceAccountName: nginx-ingress-microk8s-serviceaccount + containers: + - image: k8s.gcr.io/ingress-nginx/controller:v1.2.0 + imagePullPolicy: IfNotPresent + name: nginx-ingress-microk8s + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 # www-data + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + hostPort: 8002 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 4432 + protocol: TCP + - name: health + containerPort: 10254 + hostPort: 12542 + protocol: TCP + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-child + - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-microk8s-conf-child + - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-microk8s-conf-child + - --election-id=ingress-controller-leader-child + - --controller-class=tfs.etsi.org/controller-class-child + - --ingress-class=tfs-ingress-class-child + - ' ' + - --publish-status-address=127.0.0.1 diff --git a/src/tests/ofc23/nginx-ingress-controller-parent.yaml b/src/tests/ofc23/nginx-ingress-controller-parent.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c504c2e6766c1ad5b81a2479b4d05a09ba46d906 --- /dev/null +++ b/src/tests/ofc23/nginx-ingress-controller-parent.yaml @@ -0,0 +1,134 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: v1 +kind: ConfigMap +metadata: + name: nginx-load-balancer-microk8s-conf-parent + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-udp-microk8s-conf-parent + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-tcp-microk8s-conf-parent + namespace: ingress +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: tfs-ingress-class-parent + annotations: + ingressclass.kubernetes.io/is-default-class: "false" +spec: + controller: tfs.etsi.org/controller-class-parent +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: nginx-ingress-microk8s-controller-parent + namespace: ingress + labels: + microk8s-application: nginx-ingress-microk8s-parent +spec: + selector: + matchLabels: + name: nginx-ingress-microk8s-parent + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: nginx-ingress-microk8s-parent + spec: + terminationGracePeriodSeconds: 60 + restartPolicy: Always + serviceAccountName: nginx-ingress-microk8s-serviceaccount + containers: + - image: k8s.gcr.io/ingress-nginx/controller:v1.2.0 + imagePullPolicy: IfNotPresent + name: nginx-ingress-microk8s + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 # www-data + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + hostPort: 8001 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 4431 + protocol: TCP + - name: health + containerPort: 10254 + hostPort: 12541 + protocol: TCP + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-parent + - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-microk8s-conf-parent + - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-microk8s-conf-parent + - --election-id=ingress-controller-leader-parent + - --controller-class=tfs.etsi.org/controller-class-parent + - --ingress-class=tfs-ingress-class-parent + - ' ' + - --publish-status-address=127.0.0.1 diff --git a/src/tests/ofc23/show_deploy.sh b/src/tests/ofc23/show_deploy.sh new file mode 100755 index 0000000000000000000000000000000000000000..d4e112b0f494e4a6dba964eda4e31652b8548043 --- /dev/null +++ b/src/tests/ofc23/show_deploy.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +echo "Deployment Resources:" +kubectl --namespace tfs-parent get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs-parent get ingress +printf "\n" + +echo "Deployment Resources:" +kubectl --namespace tfs-child get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs-child get ingress +printf "\n" diff --git a/src/tests/ofc23/show_deploy_sligrp.sh b/src/tests/ofc23/show_deploy_sligrp.sh new file mode 100755 index 0000000000000000000000000000000000000000..b5e3600ba99ec2e4de4a953f99c44ed2d88bba57 --- /dev/null +++ b/src/tests/ofc23/show_deploy_sligrp.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +echo "Deployment Resources:" +kubectl --namespace tfs get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs get ingress +printf "\n" diff --git a/src/tests/ofc23/tfs-ingress-child.yaml b/src/tests/ofc23/tfs-ingress-child.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a93b9321c9f25c78e8423413c4225f78c7aee719 --- /dev/null +++ b/src/tests/ofc23/tfs-ingress-child.yaml @@ -0,0 +1,53 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tfs-ingress-child + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: tfs-ingress-class-child + rules: + - http: + paths: + - path: /webui(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 8004 + - path: /grafana(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 3000 + - path: /context(/|$)(.*) + pathType: Prefix + backend: + service: + name: contextservice + port: + number: 8080 + - path: /()(restconf/.*) + pathType: Prefix + backend: + service: + name: computeservice + port: + number: 8080 diff --git a/src/tests/ofc23/tfs-ingress-parent.yaml b/src/tests/ofc23/tfs-ingress-parent.yaml new file mode 100644 index 0000000000000000000000000000000000000000..baf506dd90f320a1913beb8becd39164daa21370 --- /dev/null +++ b/src/tests/ofc23/tfs-ingress-parent.yaml @@ -0,0 +1,53 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tfs-ingress-parent + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: tfs-ingress-class-parent + rules: + - http: + paths: + - path: /webui(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 8004 + - path: /grafana(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 3000 + - path: /context(/|$)(.*) + pathType: Prefix + backend: + service: + name: contextservice + port: + number: 8080 + - path: /()(restconf/.*) + pathType: Prefix + backend: + service: + name: computeservice + port: + number: 8080 diff --git a/src/tests/p4/setup.sh b/src/tests/p4/setup.sh index 78e7f7372d911623cd541495ab15ad3cd548c3ef..a98ad31ab159217c209d5077b258fd398d5113cd 100755 --- a/src/tests/p4/setup.sh +++ b/src/tests/p4/setup.sh @@ -16,7 +16,7 @@ export POD_NAME=$(kubectl get pods -n=tfs | grep device | awk '{print $1}') -kubectl exec ${POD_NAME} -n=tfs -- mkdir /root/p4 +kubectl exec ${POD_NAME} -n=tfs -c=server -- mkdir /root/p4 -kubectl cp src/tests/p4/p4/p4info.txt tfs/${POD_NAME}:/root/p4 -kubectl cp src/tests/p4/p4/bmv2.json tfs/${POD_NAME}:/root/p4 +kubectl cp src/tests/p4/p4/p4info.txt tfs/${POD_NAME}:/root/p4 -c=server +kubectl cp src/tests/p4/p4/bmv2.json tfs/${POD_NAME}:/root/p4 -c=server diff --git a/src/tests/scenario3/README.md b/src/tests/scenario3/README.md index a89d71f74b4ac35fa78aa5619019c8afad79410d..cc6d0c70417d5ec98810e557233941c3b0d043e6 100644 --- a/src/tests/scenario3/README.md +++ b/src/tests/scenario3/README.md @@ -1 +1,3 @@ -# Scenario 3 - ... +# Scenario 3 - Cybersecurity + + diff --git a/src/tests/scenario3/l3/README.md b/src/tests/scenario3/l3/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f66d8e351033d2762a77269243b6d3bb2a1d7022 --- /dev/null +++ b/src/tests/scenario3/l3/README.md @@ -0,0 +1,3 @@ +# Scripts to automatically run the "Attack Detection & Mitigation at the L3 Layer" workflow (Scenario 3). +"launch_l3_attack_detection_and_mitigation.sh" launches the TeraFlow OS components, which includes the CentralizedAttackDetector and AttackMitigator componentes necessary to perform this workflow. +"launch_l3_attack_detection_and_mitigation_complete.sh" also launches the DistributedAttackDetector, which monitors the network data plane and passively collects traffic packets and aggregates them in network flows, which are then provided to the CentralizedAttackDetector to detect attacks that may be occurring in the network. diff --git a/src/tests/scenario3/l3/complete_deploy.sh b/src/tests/scenario3/l3/complete_deploy.sh new file mode 100755 index 0000000000000000000000000000000000000000..5e8a2772c61ac2e96e5cf675468d27be2b940fe6 --- /dev/null +++ b/src/tests/scenario3/l3/complete_deploy.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +./src/tests/ofc22/run_test_03_delete_service.sh +./src/tests/ofc22/run_test_04_cleanup.sh +source src/tests/ofc22/deploy_specs.sh +source my_deploy.sh +./deploy/all.sh +source tfs_runtime_env_vars.sh +ofc22/run_test_01_bootstrap.sh +ofc22/run_test_02_create_service.sh diff --git a/src/tests/scenario3/l3/copy_protos_to_dad.sh b/src/tests/scenario3/l3/copy_protos_to_dad.sh new file mode 100755 index 0000000000000000000000000000000000000000..6735d9cf95d2243e6f87b5508c2e3f7b9756c474 --- /dev/null +++ b/src/tests/scenario3/l3/copy_protos_to_dad.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +# Set the variables for the remote host and destination directory +REMOTE_HOST="192.168.165.73" +DEST_DIR="/home/ubuntu/TeraflowDockerDistributed/l3_distributedattackdetector/proto" + +# Copy the files to the remote host +sshpass -p "ubuntu" scp /home/ubuntu/tfs-ctrl-new/proto/src/python/l3_centralizedattackdetector_pb2.py "$REMOTE_HOST:$DEST_DIR" +sshpass -p "ubuntu" scp /home/ubuntu/tfs-ctrl-new/proto/src/python/l3_centralizedattackdetector_pb2_grpc.py "$REMOTE_HOST:$DEST_DIR" + +sshpass -p "ubuntu" scp /home/ubuntu/tfs-ctrl-new/proto/src/python/l3_attackmitigator_pb2.py "$REMOTE_HOST:$DEST_DIR" +sshpass -p "ubuntu" scp /home/ubuntu/tfs-ctrl-new/proto/src/python/l3_attackmitigator_pb2_grpc.py "$REMOTE_HOST:$DEST_DIR" diff --git a/src/tests/scenario3/l3/deploy_l3_component.sh b/src/tests/scenario3/l3/deploy_l3_component.sh new file mode 100755 index 0000000000000000000000000000000000000000..8e468c9067c93a06c6716ac618f5c9fdba860d34 --- /dev/null +++ b/src/tests/scenario3/l3/deploy_l3_component.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +component=$1 + +source "my_deploy.sh" + +echo "Deploying $component..." + +# check if component == "CAD" +if [ $component == "CAD" ]; then + # find kubernetes pod that contains "centralizedattackdetectorservice" + pod=$(kubectl --namespace $TFS_K8S_NAMESPACE get pods | grep l3-centralizedattackdetectorservice | awk '{print $1}') + + # delete pod + kubectl --namespace $TFS_K8S_NAMESPACE delete pod $pod --force --grace-period=0 + + # # wait for pod to be deleted + # while [ $(kubectl --namespace $TFS_K8S_NAMESPACE get pods | grep l3-centralizedattackdetectorservice | wc -l) -gt 0 ]; do + # sleep 1 + # done + + # deploy l3_centralizedattackdetector component + ./deploy_component.sh "l3_centralizedattackdetector" +fi + +# check if component == "AM" +if [ $component == "AM" ]; then + # find kubernetes pod that contains "l3-attackmitigatorservice" + pod=$(kubectl --namespace $TFS_K8S_NAMESPACE get pods | grep l3-attackmitigatorservice | awk '{print $1}') + + # delete pod + kubectl --namespace $TFS_K8S_NAMESPACE delete pod $pod --force --grace-period=0 + + # # wait for pod to be deleted + # while [ $(kubectl --namespace $TFS_K8S_NAMESPACE get pods | grep l3-attackmitigatorservice | wc -l) -gt 0 ]; do + # sleep 1 + # done + + # deploy l3_attackmitigator component + ./deploy_component.sh "l3_attackmitigator" +fi + +echo "Component $component deployed" + +echo "Restarting DAD..." +sshpass -p "ubuntu" ssh -o StrictHostKeyChecking=no -n -f ubuntu@192.168.165.73 "sh -c 'nohup /home/ubuntu/TeraflowDockerDistributed/restart.sh > /dev/null 2>&1 &'" +echo "DAD restarted" diff --git a/src/tests/scenario3/l3/get_ml_model_info.sh b/src/tests/scenario3/l3/get_ml_model_info.sh new file mode 100755 index 0000000000000000000000000000000000000000..19fb1177a23c13e4cdffd2e8c75df3aad3502c04 --- /dev/null +++ b/src/tests/scenario3/l3/get_ml_model_info.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +pod=$(kubectl get pods -n "tfs" -l app=l3-centralizedattackdetectorservice | sed -n '2p' | cut -d " " -f1) +while true; do + kubectl -n "tfs" cp $pod:prediction_accuracy.txt ./prediction_accuracy.txt + clear + cat prediction_accuracy.txt | tail -n 10 + sleep 1 +done diff --git a/src/tests/scenario3/l3/launch_l3_attack_detection_and_mitigation.sh b/src/tests/scenario3/l3/launch_l3_attack_detection_and_mitigation.sh new file mode 100644 index 0000000000000000000000000000000000000000..a22d98bad6c203c825d3343c44e3d31674a41ec0 --- /dev/null +++ b/src/tests/scenario3/l3/launch_l3_attack_detection_and_mitigation.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +cd /home/ubuntu/tfs-ctrl +source my_deploy.sh +./deploy.sh +./show_deploy.sh + +source tfs_runtime_env_vars.sh + +ofc22/run_test_01_bootstrap.sh +ofc22/run_test_02_create_service.sh diff --git a/src/tests/scenario3/l3/launch_l3_attack_detection_and_mitigation_complete.sh b/src/tests/scenario3/l3/launch_l3_attack_detection_and_mitigation_complete.sh new file mode 100644 index 0000000000000000000000000000000000000000..05b20077eb951102ab11fc90aaab53463c41f94f --- /dev/null +++ b/src/tests/scenario3/l3/launch_l3_attack_detection_and_mitigation_complete.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +cd /home/ubuntu/tfs-ctrl +source my_deploy.sh +./deploy.sh +./show_deploy.sh + +source tfs_runtime_env_vars.sh + +ofc22/run_test_01_bootstrap.sh +ofc22/run_test_02_create_service.sh + +sshpass -p "ubuntu" ssh -o StrictHostKeyChecking=no -n -f ubuntu@192.168.165.73 "sh -c 'nohup /home/ubuntu/TeraflowDockerDistributed/restart.sh > /dev/null 2>&1 &'" diff --git a/src/tests/scenario3/l3/launch_webui.sh b/src/tests/scenario3/l3/launch_webui.sh new file mode 100755 index 0000000000000000000000000000000000000000..bf1867eb108331647f3ad343b0ab23d098617aff --- /dev/null +++ b/src/tests/scenario3/l3/launch_webui.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +ssh -L 12345:localhost:80 ubuntu@192.168.165.78 diff --git a/src/tests/scenario3/optical/README.md b/src/tests/scenario3/optical/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a23f86e75614016f40e65cdc5d3bd75c26337768 --- /dev/null +++ b/src/tests/scenario3/optical/README.md @@ -0,0 +1,5 @@ +# Optical Cybersecurity + + + +## Publications diff --git a/src/tests/scenario3/optical/dashboard.json b/src/tests/scenario3/optical/dashboard.json new file mode 100644 index 0000000000000000000000000000000000000000..990ab47e95f9db5bc021ca91333f4c5fe61f7ff7 --- /dev/null +++ b/src/tests/scenario3/optical/dashboard.json @@ -0,0 +1,1537 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": [], + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "8.5.22" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 2, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 12, + "title": "General status", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 85 + }, + { + "color": "orange", + "value": 90 + }, + { + "color": "red", + "value": 95 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 20, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "8.5.22", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "(rate(tfs_opticalattackmanager_loop_seconds_sum[1m]) / rate(tfs_opticalattackmanager_loop_seconds_count[1m])) / tfs_opticalattackmanager_desired_monitoring_interval", + "instant": true, + "range": false, + "refId": "A" + } + ], + "title": "Loop time", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 31, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "expr": "tfs_opticalattackmanager_dropped_assessments_created", + "refId": "A" + } + ], + "title": "Dropped assessments", + "type": "timeseries" + }, + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 10, + "title": "Pipeline", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(tfs_opticalattackmanager_loop_seconds_bucket[$__rate_interval])) by (le))", + "legendFormat": "Measured", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "tfs_opticalattackmanager_desired_monitoring_interval", + "hide": false, + "legendFormat": "Desired", + "range": true, + "refId": "B" + } + ], + "title": "Loop time", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "tfs_opticalattackmanager_active_services", + "legendFormat": "Active services", + "range": true, + "refId": "A" + } + ], + "title": "Number of active optical services", + "type": "timeseries" + }, + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 8, + "title": "Services", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 59, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(tfs_opticalattackdetector_rpc_detectattack_histogram_duration_bucket[$__rate_interval])) by (le))", + "interval": "", + "legendFormat": "Detector", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(tfs_opticalattackdetector_inference_response_time_bucket[$__rate_interval])) by (le))", + "hide": false, + "legendFormat": "UL Inference", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(tfs_opticalattackdetector_cache_response_time_bucket[$__rate_interval])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "Cache", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(tfs_opticalattackdetector_mitigation_response_time_bucket[$__rate_interval])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "Mitigator", + "range": true, + "refId": "D" + } + ], + "title": "Response times", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 19 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "tfs_opticalattackmanager_number_workers", + "hide": false, + "legendFormat": "Manager", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "kube_replicaset_status_replicas{namespace=\"tfs\", replicaset=~\"opticalattackdetectorservice.+\"}", + "interval": "", + "legendFormat": "Detector", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "kube_replicaset_status_replicas{namespace=\"tfs\", replicaset=~\"dbscanservingservice.+\"}", + "hide": false, + "legendFormat": "UL Inference", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "kube_replicaset_status_replicas{namespace=\"tfs\", replicaset=~\"opticalattackmitigatorservice.+\"}", + "hide": false, + "interval": "", + "legendFormat": "Mitigator", + "range": true, + "refId": "C" + } + ], + "title": "Number of workers / replicas", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 6, + "panels": [ + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "title": "Panel Title", + "type": "timeseries" + } + ], + "title": "Resource usage", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 26, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{namespace=\"tfs\",pod=~\"opticalattackmanagerservice.+\"})", + "legendFormat": "Manager", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{namespace=\"tfs\",pod=~\"opticalattackdetectorservice.+\"})", + "hide": false, + "interval": "", + "legendFormat": "Detector", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{namespace=\"tfs\",pod=~\"dbscanservingservice.+\"})", + "hide": false, + "legendFormat": "UL Inference", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{namespace=\"tfs\",pod=~\"cachingservice.+\"})", + "hide": false, + "legendFormat": "Caching", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{namespace=\"tfs\",pod=~\"opticalattackmitigatorservice.+\"})", + "hide": false, + "legendFormat": "Mitigator", + "range": true, + "refId": "E" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 27, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(container_memory_working_set_bytes{namespace=\"tfs\", pod=~\"opticalattackmanagerservice.+\"})", + "interval": "", + "legendFormat": "Manager", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(container_memory_working_set_bytes{namespace=\"tfs\",pod=~\"opticalattackdetectorservice.+\"})", + "hide": false, + "interval": "", + "legendFormat": "Detector", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(container_memory_working_set_bytes{namespace=\"tfs\",pod=~\"dbscanservingservice.+\"})", + "hide": false, + "legendFormat": "UL Inference", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(container_memory_working_set_bytes{namespace=\"tfs\",pod=~\"cachingservice.+\"})", + "hide": false, + "legendFormat": "Caching", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{namespace=\"tfs\",pod=~\"opticalattackmitigatorservice.+\"})", + "hide": false, + "legendFormat": "Mitigator", + "range": true, + "refId": "E" + } + ], + "title": "RAM Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 28, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_receive_bytes_total{namespace=\"tfs\", pod=~\"opticalattackmanagerservice.+\"}[$__rate_interval]))", + "legendFormat": "Manager", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_receive_bytes_total{namespace=\"tfs\",pod=~\"opticalattackdetectorservice.+\"}[$__rate_interval]))", + "hide": false, + "interval": "", + "legendFormat": "Detector", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_receive_bytes_total{namespace=\"tfs\",pod=~\"dbscanservingservice.+\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "UL Inference", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_receive_bytes_total{namespace=\"tfs\",pod=~\"cachingservice.+\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "Caching", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_receive_bytes_total{namespace=\"tfs\",pod=~\"opticalattackmitigatorservice.+\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "Mitigator", + "range": true, + "refId": "E" + } + ], + "title": "Network (incoming)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 29, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=\"tfs\", pod=~\"opticalattackmanagerservice.+\"}[$__rate_interval]))", + "legendFormat": "Manager", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=\"tfs\",pod=~\"opticalattackdetectorservice.+\"}[$__rate_interval]))", + "hide": false, + "interval": "", + "legendFormat": "Detector", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=\"tfs\",pod=~\"dbscanservingservice.+\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "UL Inference", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=\"tfs\",pod=~\"cachingservice.+\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "Caching", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(irate(container_network_transmit_bytes_total{namespace=\"tfs\",pod=~\"opticalattackmitigatorservice.+\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "Mitigator", + "range": true, + "refId": "E" + } + ], + "title": "Network (outgoing)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 44 + }, + "id": 2, + "panels": [], + "title": "General status", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 29, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "mwatt" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 45 + }, + "id": 33, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(scaph_process_power_consumption_microwatts{namespace=\"tfs\", cmdline=~\".+opticalattackmanager.+\"})/1000", + "instant": false, + "legendFormat": "Manager", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(scaph_process_power_consumption_microwatts{namespace=\"tfs\", cmdline=~\".+opticalattackdetector.+\"})/1000", + "hide": false, + "instant": false, + "legendFormat": "Detector", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(scaph_process_power_consumption_microwatts{namespace=\"tfs\", cmdline=~\".+dbscan.+\"})/1000", + "hide": false, + "instant": false, + "interval": "", + "legendFormat": "UL Inference", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(scaph_process_power_consumption_microwatts{namespace=\"tfs\", cmdline=~\"redis-server.+\"})/1000", + "hide": false, + "instant": false, + "interval": "", + "legendFormat": "Cache", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(scaph_process_power_consumption_microwatts{namespace=\"tfs\", cmdline=~\".+opticalattackmitigator.+\"})/1000", + "hide": false, + "instant": false, + "interval": "", + "legendFormat": "Mitigator", + "range": true, + "refId": "E" + } + ], + "title": "Energy consumption", + "type": "timeseries" + } + ], + "refresh": "5s", + "schemaVersion": 36, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "TFS / Optical cybersecurity", + "uid": "-Q-B-AsVk", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/src/tests/scenario3/optical/deploy_specs.sh b/src/tests/scenario3/optical/deploy_specs.sh new file mode 100644 index 0000000000000000000000000000000000000000..878013d8b82177e3d70aa432e01583f03eded237 --- /dev/null +++ b/src/tests/scenario3/optical/deploy_specs.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 list of components, separated by spaces, you want to build images for, and deploy. +export TFS_COMPONENTS="context device automation monitoring pathcomp service slice compute webui load_generator" + +# addition for the optical cybersecurity component +export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" +export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" + + +# ----- CockroachDB ------------------------------------------------------------ + + +# Disable flag for dropping database, if it exists. +export CRDB_DROP_DATABASE_IF_EXISTS="YES" + + + +# ----- QuestDB ---------------------------------------------------------------- + +# Disable flag for dropping tables if they exist. +export QDB_DROP_TABLES_IF_EXIST="YES" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/src/tests/scenario3/optical/jocn/README.md b/src/tests/scenario3/optical/jocn/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0981331111d00ff7e6a6245c20186d4dc60f55f8 --- /dev/null +++ b/src/tests/scenario3/optical/jocn/README.md @@ -0,0 +1,5 @@ +# A Flexible and Scalable ML-Based Diagnosis Module for Optical Networks: A Security Use Case + +__Authors__: [Carlos Natalino](https://www.chalmers.se/en/persons/carda/), Lluis Gifre Renom, Francisco-Javier Moreno-Muro, Sergio Gonzalez Diaz, Ricard Vilalta, Raul Muñoz, Paolo Monti, and Marija Furdek + +Experiments from the JOCN paper. \ No newline at end of file diff --git a/src/tests/scenario3/optical/jocn/processing_results.ipynb b/src/tests/scenario3/optical/jocn/processing_results.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..828a0966c993e0dc5c7aca7d0cbcbf4474d92a23 --- /dev/null +++ b/src/tests/scenario3/optical/jocn/processing_results.ipynb @@ -0,0 +1,3506 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: matplotlib in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (3.6.1)\n", + "Requirement already satisfied: pandas in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (1.5.1)\n", + "Requirement already satisfied: requests in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (2.28.1)\n", + "Requirement already satisfied: numpy in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (1.23.4)\n", + "Requirement already satisfied: tqdm in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (4.64.1)\n", + "Requirement already satisfied: qrcode in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (7.4.2)\n", + "Requirement already satisfied: packaging>=20.0 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (21.3)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (1.4.4)\n", + "Requirement already satisfied: pillow>=6.2.0 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (9.2.0)\n", + "Requirement already satisfied: pyparsing>=2.2.1 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (3.0.9)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (4.37.4)\n", + "Requirement already satisfied: python-dateutil>=2.7 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (2.8.2)\n", + "Requirement already satisfied: cycler>=0.10 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (0.11.0)\n", + "Requirement already satisfied: contourpy>=1.0.1 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from matplotlib) (1.0.5)\n", + "Requirement already satisfied: pytz>=2020.1 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from pandas) (2021.3)\n", + "Requirement already satisfied: idna<4,>=2.5 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from requests) (3.3)\n", + "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from requests) (1.26.12)\n", + "Requirement already satisfied: charset-normalizer<3,>=2 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from requests) (2.0.12)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from requests) (2022.6.15.1)\n", + "Requirement already satisfied: pypng in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from qrcode) (0.20220715.0)\n", + "Requirement already satisfied: typing-extensions in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from qrcode) (4.3.0)\n", + "Requirement already satisfied: six>=1.5 in /home/carda/.pyenv/versions/3.9.14/envs/tfs/lib/python3.9/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip available: \u001b[0m\u001b[31;49m22.2.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.0.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" + ] + } + ], + "source": [ + "!pip install matplotlib pandas requests numpy tqdm qrcode" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-v0_8', 'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark', 'seaborn-v0_8-dark-palette', 'seaborn-v0_8-darkgrid', 'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook', 'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster', 'seaborn-v0_8-talk', 'seaborn-v0_8-ticks', 'seaborn-v0_8-white', 'seaborn-v0_8-whitegrid', 'tableau-colorblind10']\n" + ] + } + ], + "source": [ + "import collections\n", + "import datetime\n", + "import os\n", + "import time\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import requests\n", + "import qrcode\n", + "import qrcode.image.svg\n", + "\n", + "from tqdm.notebook import tqdm\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "print(plt.style.available)\n", + "# plt.style.use('seaborn-v0_8-colorblind') # paper figures\n", + "plt.style.use('seaborn-v0_8-poster') # poster figures\n", + "\n", + "plt.rcParams.update({'font.size': 14})\n", + "\n", + "%matplotlib inline\n", + "# %config InlineBackend.figure_format = 'svg'" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "jocn_20221204T093831.502593UTC\n", + "jocn_20230129T160117.267710UTC\n", + "jocn_20230131T082259.657842UTC\n", + "jocn_20230222T055227.218793UTC\n" + ] + } + ], + "source": [ + "# configs\n", + "from configs import base_results_folder, datetime_format, hpa_data, prometheus_endpoint\n", + "\n", + "# get latest folder:\n", + "latest_folder = None\n", + "for f in sorted(os.listdir(os.path.join(base_results_folder))):\n", + " if os.path.isdir(os.path.join(base_results_folder, f)) and f != \"figures\":\n", + " print(f)\n", + " latest_folder = f\n", + "\n", + "# latest_folder = \"jocn_20221204T093831.502593UTC\" # stable results from Sunda\n", + "# latest_folder = \"jocn_20230129T160117.267710UTC\" # folder from revision\n", + "latest_folder = \"jocn_20230131T082259.657842UTC\"\n", + "\n", + "start_experiment = time.mktime(datetime.datetime(2023, 1, 29, 16, 9, 0).timetuple()),\n", + "end_experiment = time.mktime(datetime.datetime(2023, 1, 29, 21, 15, 0).timetuple()),\n", + "\n", + "os.makedirs(os.path.join(base_results_folder, latest_folder, \"figures\"), exist_ok=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "img = qrcode.make('https://tfs.etsi.org/', image_factory=qrcode.image.svg.SvgImage)\n", + "\n", + "with open('results/etsi-qr.svg', 'wb') as qr:\n", + " img.save(qr)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['opticalattackmitigatorservice-hpa', 'dbscanservingservice-hpa', 'opticalattackdetectorservice-hpa']\n" + ] + } + ], + "source": [ + "# loading hpa names\n", + "hpas = []\n", + "with open(os.path.join(base_results_folder, latest_folder, \"hpas.csv\"), \"rt\", encoding=\"utf-8\") as file:\n", + " for line in file.readlines():\n", + " hpas.append(line.replace(\"\\n\", \"\"))\n", + "print(hpas)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
timestampnumber_servicesopticalattackmitigatorservice-hpa_cur_utilizationopticalattackmitigatorservice-hpa_target_utilizationopticalattackmitigatorservice-hpa_cur_replicasopticalattackmitigatorservice-hpa_desired_replicasdbscanservingservice-hpa_cur_utilizationdbscanservingservice-hpa_target_utilizationdbscanservingservice-hpa_cur_replicasdbscanservingservice-hpa_desired_replicasopticalattackdetectorservice-hpa_cur_utilizationopticalattackdetectorservice-hpa_target_utilizationopticalattackdetectorservice-hpa_cur_replicasopticalattackdetectorservice-hpa_desired_replicascache_cpucache_rammanager_cpumanager_ramseconds
1152023-01-31 14:13:0102802218022280223.688660e+11757220.02.569470e+114752.017103.0
1162023-01-31 14:18:000280221802228022NaNNaNNaNNaN17402.0
1172023-01-31 14:18:0102802218022280224.050550e+11757448.03.544610e+114752.017403.0
1182023-01-31 14:23:000180222802228022NaNNaNNaNNaN17702.0
1192023-01-31 14:23:01101802228022280224.055380e+11757448.05.106052e+1240888.017703.0
\n", + "
" + ], + "text/plain": [ + " timestamp number_services \\\n", + "115 2023-01-31 14:13:01 0 \n", + "116 2023-01-31 14:18:00 0 \n", + "117 2023-01-31 14:18:01 0 \n", + "118 2023-01-31 14:23:00 0 \n", + "119 2023-01-31 14:23:01 10 \n", + "\n", + " opticalattackmitigatorservice-hpa_cur_utilization \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 1 \n", + "119 1 \n", + "\n", + " opticalattackmitigatorservice-hpa_target_utilization \\\n", + "115 80 \n", + "116 80 \n", + "117 80 \n", + "118 80 \n", + "119 80 \n", + "\n", + " opticalattackmitigatorservice-hpa_cur_replicas \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 2 \n", + "119 2 \n", + "\n", + " opticalattackmitigatorservice-hpa_desired_replicas \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 2 \n", + "119 2 \n", + "\n", + " dbscanservingservice-hpa_cur_utilization \\\n", + "115 1 \n", + "116 1 \n", + "117 1 \n", + "118 2 \n", + "119 2 \n", + "\n", + " dbscanservingservice-hpa_target_utilization \\\n", + "115 80 \n", + "116 80 \n", + "117 80 \n", + "118 80 \n", + "119 80 \n", + "\n", + " dbscanservingservice-hpa_cur_replicas \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 2 \n", + "119 2 \n", + "\n", + " dbscanservingservice-hpa_desired_replicas \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 2 \n", + "119 2 \n", + "\n", + " opticalattackdetectorservice-hpa_cur_utilization \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 2 \n", + "119 2 \n", + "\n", + " opticalattackdetectorservice-hpa_target_utilization \\\n", + "115 80 \n", + "116 80 \n", + "117 80 \n", + "118 80 \n", + "119 80 \n", + "\n", + " opticalattackdetectorservice-hpa_cur_replicas \\\n", + "115 2 \n", + "116 2 \n", + "117 2 \n", + "118 2 \n", + "119 2 \n", + "\n", + " opticalattackdetectorservice-hpa_desired_replicas cache_cpu \\\n", + "115 2 3.688660e+11 \n", + "116 2 NaN \n", + "117 2 4.050550e+11 \n", + "118 2 NaN \n", + "119 2 4.055380e+11 \n", + "\n", + " cache_ram manager_cpu manager_ram seconds \n", + "115 757220.0 2.569470e+11 4752.0 17103.0 \n", + "116 NaN NaN NaN 17402.0 \n", + "117 757448.0 3.544610e+11 4752.0 17403.0 \n", + "118 NaN NaN NaN 17702.0 \n", + "119 757448.0 5.106052e+12 40888.0 17703.0 " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# https://stackoverflow.com/questions/12522963/converters-for-python-pandas\n", + "def convert_cpu_usage(value):\n", + " # u -> / 1_000\n", + " # n -> / 1_000_000\n", + " if len(value) == 0:\n", + " return float('nan')\n", + " if value.endswith(\"u\"):\n", + " return float(value.replace(\"u\", \"\")) * 1_000\n", + " elif value.endswith(\"n\"):\n", + " return float(value.replace(\"n\", \"\")) * 1_000_000\n", + " else:\n", + " raise ValueError(f\"Error converting {value} to mCPUs\")\n", + "\n", + "def convert_memory_usage(value):\n", + " if len(value) == 0:\n", + " return float('nan')\n", + " if value.endswith(\"Mi\"):\n", + " return float(value.replace(\"Mi\", \"\")) * 1_000\n", + " elif value.endswith(\"Ki\"):\n", + " return float(value.replace(\"Ki\", \"\"))\n", + " else:\n", + " raise ValueError(f\"Error converting {value} to Ki\")\n", + "\n", + "number_services = pd.read_csv(\n", + " os.path.join(base_results_folder, latest_folder, \"services.csv\"), skiprows=1,\n", + " converters={\n", + " \"cache_cpu\": convert_cpu_usage, \"manager_cpu\": convert_cpu_usage,\n", + " \"cache_ram\": convert_memory_usage, \"manager_ram\": convert_memory_usage,\n", + " }\n", + ")\n", + "number_services[\"timestamp\"] = pd.to_datetime(number_services[\"timestamp\"], format=datetime_format)\n", + "earliest_sample = number_services[\"timestamp\"].sort_values()[0]\n", + "\n", + "# number_services[\"seconds\"] = []\n", + "\n", + "number_services[\"seconds\"] = number_services.apply(lambda row: (row[\"timestamp\"] - earliest_sample).total_seconds(), axis=1)\n", + "\n", + "number_services.tail()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# last_sample = 97\n", + "last_sample = len(number_services[\"seconds\"])\n", + "\n", + "plt.figure(figsize=(6.4, 3.))\n", + "plt.grid(axis=\"x\", ls=\":\")\n", + "plt.plot(number_services[\"seconds\"][:last_sample], number_services[\"number_services\"][:last_sample])\n", + "\n", + "plt.text(13800, 1500, r\"$p=30$\", rotation=90, verticalalignment=\"center\", horizontalalignment=\"center\")\n", + "plt.text(16200, 1500, r\"$p=60$\", rotation=90, verticalalignment=\"center\", horizontalalignment=\"center\")\n", + "\n", + "plt.xlabel(\"Time [s]\")\n", + "plt.ylabel(\"Number of services\")\n", + "\n", + "plt.tight_layout()\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", \"number_services.pdf\"))\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(6.4, 3.6))\n", + "\n", + "plt.grid(axis=\"x\", ls=\":\")\n", + "\n", + "hpa = hpas[1]\n", + "plt.plot(number_services[\"seconds\"], number_services[f\"{hpa}_cur_utilization\"], label=\"Worker\", marker=\"^\", ls=\"--\", markersize=8, markevery=10, markeredgecolor=\"white\")\n", + "\n", + "hpa = hpas[2]\n", + "plt.plot(number_services[\"seconds\"], number_services[f\"{hpa}_cur_utilization\"], label=\"Inference\", ls=\":\", marker=\"v\", markersize=8, markevery=10, markeredgecolor=\"white\")\n", + "\n", + "plt.plot(number_services[\"seconds\"][:last_sample], number_services[f\"{hpa}_target_utilization\"][:last_sample], ls=\"--\", color=\"gray\", label=\"Target\")\n", + "\n", + "plt.xlabel(\"Time [s]\")\n", + "plt.ylabel(\"Avg. CPU Utilization [%]\")\n", + "plt.legend(loc=2)\n", + "\n", + "plt.tight_layout()\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"monitoring_hpa_cpu.pdf\"))\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(6.4, 3.6))\n", + "\n", + "plt.grid(axis=\"x\", ls=\":\")\n", + "\n", + "# plt.plot(number_services[\"seconds\"][:last_sample], [2 for x in range(len(number_services[\"seconds\"]))][:last_sample], ls=\"--\", color=\"gray\")\n", + "\n", + "hpa = hpas[1]\n", + "plt.plot(number_services[\"seconds\"], number_services[f\"{hpa}_cur_replicas\"], label=\"Worker\", marker=\"^\", ls=\"--\", markersize=8, markevery=10, markeredgecolor=\"white\")\n", + "\n", + "hpa = hpas[2]\n", + "plt.plot(number_services[\"seconds\"], number_services[f\"{hpa}_cur_replicas\"], label=\"Inference\", ls=\":\", marker=\"v\", markersize=8, markevery=10, markeredgecolor=\"white\")\n", + "\n", + "plt.plot(number_services[\"seconds\"][:last_sample], [10 for x in range(len(number_services[\"seconds\"]))][:last_sample], ls=\"--\", color=\"gray\", label=\"Max\")\n", + "\n", + "plt.xlabel(\"Time [s]\")\n", + "plt.ylabel(\"Number of replicas\")\n", + "plt.legend(loc=6)\n", + "\n", + "plt.tight_layout()\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"monitoring_hpa_replicas.pdf\"))\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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HTt2TPR516xZw2rUqOFRaDiFilarZUOHDmWFhYWubWvXrmUJCQkMAPv88895+z333HMMAOvRowe7dOkSb1tRURGbN28eO3jwIG/922+/zQCwOnXqsJUrV/K2/fLLL65+LliwgLfNKVTVajVLT09nv/76q2ubxWJhFouFHTt2jHEcx9RqNTt37pzoczLGWOfOnRkA9tZbb/HW+yNU9Xo9e++995jVanVtnzp1qktQHD16lLfvX3/9xTQaDQPAXnjhBWYymVzb5s+fzzQajWusuQvVy5cvM7VazTQaDVuyZAmz2+284+7cuZN9+umnvHVXrlxhderUYQDYo48+yvs+CgsL2cMPP8wAsCZNmoheODi/f7VazR588EFWUFDg2uYcr879n3jiCUm7rlu3ziXGjUajpP2EOL9TlUrFXnvtNVZWVubaZrfb2Zo1a0TjQO748Qf33/eLL77I+xwLFy50Cer//e9/vP2CuTaYTCb23//+l509e5a33mq1sm+++YYlJCQwrVbL8vLyAv48BEEQlR0SqgRBxBQbN250PVTu3r1btP333393bfckVHv16iV57EcffZQBYLm5ubz1er2eAeAJQG/88MMPLmEkFKNymTt3LgPAHn/8cdE2p1Bp2rQpM5vNou1OD9agQYN46/v06cMAsO+++86vPly9epUlJSUxtVrNduzYIdlm2bJlDAC74YYbeOudogYAW7hwocdzOF9C/Oc//xFtO378OOM4jqlUKnbmzBneNn+E6qhRoyTPmZub6/JIu+MUdz169JDc76WXXnId212obt26lQFgN910k8fPKeTf//43A8AGDhwoud1qtbJWrVqJPJ6MVXz/zZo1E4lYJ2vXrnV5Ct0FtxOn/UaPHs1b70momkwmlzf+1Vdf9eszBjN+/MHZT0/f14ABAxgA9vzzz/PWB3Nt8IXzexW+WCEIgogFaI4qQRAxxU8//QQA6NKlC2666SbR9o4dO6Jdu3ZejzFmzBiv6/fu3YvTp0+71tevXx8AvM6ddGfZsmUAgLvuugs33HCDX/s4OXDgAKZMmYLBgweje/fu6NSpEzp16oQPPvgAgGM+oCdGjx4NrVYrWn/LLbcAAI4ePcpb7/xcS5culZy7J+Snn35CaWkp2rZti7Zt20q2GTBgALRaLQ4ePIjz58+LticnJ+Pee+/1eI6HH34YAPDll1+Ktn311VdgjKFHjx7Izs722V8hTz31lOR6T/b55ZdfAACPPPKI5H6jR4+WXO+065EjR3jzaL3xzTffAAAef/xxye1qtRoDBw4EAKxbt06yzbBhw6DRSBcD6N69O+rWrYurV6/ixx9/5G0zGAyuMTts2DC/+rtlyxacP38eer0e48aN82sfJcaPPwT6PbsT6LXByfbt2zFhwgT83//9H7p16+b63S5ZsgSA998tQRBEVYXK0xAEEVM4S2U0b97cY5vmzZtjx44dHre3aNFCcn2TJk2g0WhgtVpx8OBB1K1bFwDw0ksvYdSoUXjyyScxY8YM9OrVC7fccgu6du3qEiXu7N27FwBw6623+v25AGD8+PF45513vCb2uXLlisdt119/veT6mjVrAgBKSkp465977jksWLAAX331FX7++Wf07t0bt956Kzp16oSWLVuKEuj89ddfAIATJ06gU6dOHvvh3O/06dPIysribXPa2BP33nsvnn32Wfz999/Ys2cP72WEU7w6xWygBGKfwsJCV/IiqRciANCwYUOkpKSIElVlZWVh6NCh+PLLL9G+fXu0b98e3bp1wy233IIuXbogPT2d176srMwlnl555RW88cYbkudzJraSEkqA99+ESqXCQw89hLfeegsLFizAXXfd5dq2YsUKlJaWonHjxn6PWecYb9GiBVJSUvzaR4nx4w+B/g7cCfTaYLVaMXLkSMkXK+54+90SBEFUVUioEgQRUzgfMp0PnVJ42+Ztu1qtRvXq1XHx4kXew+zIkSORnp6O6dOn448//sDs2bMxe/ZsAECHDh3w1ltvoVu3bq72TuGSlpbmz0cCACxevBhvv/02VCoVXn31Vdx1111o0KABEhMToVKp8L///Q89evSAxWLxeIzExETJ9SqVI/hGKICbNWuGP/74A1OmTMEvv/yCr7/+Gl9//TUAh1dwwoQJeOyxx1ztCwoKAACXLl3ymIHWHYPB4HcfnaSmpmLgwIH45ptvsGDBApdI/OOPP/DPP/8gOTmZJ7ICIRD7lJaWuv5OTk72eMzk5GTJjMqfffYZcnNzMXfuXGzbtg3btm0DAGg0Gtx5552YMWMGcnJyADhEsRN/PLBSdgV823bYsGF466238NNPP+HKlSuoXr06AHkvAOSMcbnj5+eff8abb74p2t6qVSt8+OGHovWB/g7cCfTaMH36dHz5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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for hpa in hpas:\n", + " # - \"cur_utilization\"\n", + " # - \"target_utilization\"\n", + " # - \"cur_replicas\"\n", + " # - \"desired_replicas\"\n", + "\n", + " fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9.6, 4.8))\n", + " fig.suptitle(hpa)\n", + "\n", + " ax1.grid(axis=\"x\", ls=\":\")\n", + " ax1.plot(number_services[\"seconds\"][:last_sample], number_services[f\"{hpa}_cur_utilization\"][:last_sample], label=\"Current\")\n", + " ax1.plot(number_services[\"seconds\"][:last_sample], number_services[f\"{hpa}_target_utilization\"][:last_sample], ls=\"--\", color=\"red\", label=\"Target\")\n", + " ax1.set_xlabel(\"(a) Time [s]\")\n", + " ax1.set_ylabel(\"Avg. CPU Utilization [%]\")\n", + " ax1.legend()\n", + "\n", + " ax2.grid(axis=\"x\", ls=\":\")\n", + " ax2.plot(number_services[\"seconds\"][:last_sample], number_services[f\"{hpa}_cur_replicas\"][:last_sample], label=\"Current\")\n", + " ax2.plot(number_services[\"seconds\"][:last_sample], number_services[f\"{hpa}_desired_replicas\"][:last_sample], ls=\"--\", color=\"green\", label=\"Desired\")\n", + " ax2.plot(number_services[\"seconds\"][:last_sample], [10 for x in range(len(number_services[\"seconds\"]))][:last_sample], ls=\"--\", color=\"red\", label=\"Max\")\n", + " ax2.set_xlabel(\"(b) Time [s]\")\n", + " ax2.set_ylabel(\"Number of Replicas\")\n", + " ax2.legend(loc=7)\n", + "\n", + " plt.tight_layout()\n", + " plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"monitoring_{hpa}.pdf\"))\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_2397991/1239110600.py:7: FutureWarning: The behavior of `series[i:j]` with an integer-dtype index is deprecated. In a future version, this will be treated as *label-based* indexing, consistent with e.g. `series[i]` lookups. To retain the old behavior, use `series.iloc[i:j]`. To get the future behavior, use `series.loc[i:j]`.\n", + " axs[i].plot(resources[\"seconds\"][:last_sample], resources[f\"{s}_{k}\"] / 1_000, label=\"Current\")\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA5QAAAHVCAYAAACOrbSoAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAACRy0lEQVR4nOzdd3hUVfoH8O+dyaQ3UgiB0CGhiiBVqrQVUBRQigrEVRF/61pQV0BRVlksq6JiwcIiFgQBERF1AVeUplIi0kOvAVJIMulTzu+POEPuvTOTmclMZib5fp4nD9xy5p65gdy8857zHkkIIUBERERERETkIo2vO0BERERERESBiQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASUREVEVLVq0gCRJ2Lx5s6+7QkRE5PcYUBIREREREZFbGFASERERERGRWxhQEhERERERkVsYUBIREREREZFbGFASEZFPCCHw1Vdf4ZZbbkHjxo0REhKCpKQk9O7dG88//zyysrKs52ZkZOCZZ55B3759kZKSguDgYMTHx2Pw4MH4+OOPIYRweK0ff/wREydORLNmzRAaGoqEhAR069YNM2fOxLFjx+y2O3PmDO655x40adIEISEhaNGiBR577DEUFhbabWMymbBkyRIMGTIECQkJCA4ORpMmTXDnnXdi7969rt8oIiIiPyaJ6p7CREREHlZaWopJkyZh7dq1AID4+Hi0bNkSV65cwZkzZ2AwGLBkyRKkp6cDALp3747du3cjJiYGycnJiIyMxIULF3DhwgUAwKRJk7Bs2TLVdcxmM/72t79h0aJFAICoqCikpqaiqKgIp0+fRllZGZ599lnMnTvX2qZFixY4ffo03njjDTz77LMoLS1Fx44dkZeXh9OnT0MIgd69e2PLli0ICgqSXe/KlSu45ZZbsGXLFgBA48aNkZSUhGPHjkGv10On0+Hjjz/GxIkTPX1LiYiIfIIZSiIiqnUPPPAA1q5di9jYWKxcuRKXL1/Gzp07cezYMRQUFODjjz9GmzZtrOfPmDED+/btQ35+Pg4dOoSdO3fi/Pnz+O2339C2bVt8/vnnWL58ueo6zz33HBYtWoSQkBC8++67yM3Nxa5du3D48GHo9XqsWbMG1113nc0+Pv7447j55ptx6dIl7N69GydPnsTGjRsRHh6OX375BZ988omqzZ133oktW7agX79+2LdvH86fP489e/YgPz8fCxYsgMlkwt13343MzEzP3UwiIiIfYoaSiIhq1R9//IEuXboAAH744QcMHjy4Rq+3adMmDBs2DDfeeCO+++476/7Lly+jefPmKCsrw3/+8x/cfffdTr2eJUPZrl07/PHHH9DpdLLjDz30EBYuXIgxY8bgyy+/VPWjWbNm2Lt3L2JjY1WvbWn7wAMP4J133nHvDRMREfmRoOpPISIi8hxLENanTx+XgsnTp09j+fLl2LNnD3JyclBeXg4A1j8zMjJk53/77bcoKytDkyZNMHXqVJf7OW3aNFUwaen3woULVXMvV6xYAaBy+K2tYBIAxo0bh4ULF+KHH35wuT9ERET+iAElERHVqn379gEArr/+eqfbvPnmm3jiiSdQUVFh95zc3Fyb1+nduzc0GtdneKSmptrcn5SUBADQ6/Wy/ZaCO19++SW2bt1qs21ZWRkA4OzZsy73h4iIyB8xoCQiolplqZBqL4untGPHDjz88MMAgL/97W+YOnUq2rZti6ioKGi1Wpw4cQKtW7eG0Wis0XWUIiIibO63BKfKGSNXrlwBABw9ehRHjx51+NqlpaVu9YmIiMjfsCgPERHVqujoaABAfn6+U+cvXboUAHDbbbfhrbfeQo8ePRAbGwutVgtAnZl09zo1FRkZCQD4z3/+AyFEtV9ERER1AQNKIiKqVddccw0AYPv27U6df/LkSQDAgAEDbB7/5ZdfHF7nl19+gdlsdrWbLuvcuTOAyqJDRERE9QUDSiIiqlXjxo2DJEnYsWMHNm/eXO354eHhAICsrCzVsbKyMixcuNBmu5EjRyIsLAznz5+3ucSHp40fPx4A8PHHH+PSpUtevx4REZE/YEBJRES1qlOnTkhPTwdQGVyuWbNGNgS0rKwMn376qbWwzcCBAwEA77zzDnbu3Gk97/Lly7jtttvsFrhJTEzEzJkzAQDTp0/HBx98IJtnaTQasXbtWqxbt84j7+umm27C8OHDkZeXhxtuuMFmYZ4TJ07g5ZdfxocffuiRaxIREfkaA0oiIqp1b7/9NkaPHo28vDyMHTsWiYmJ6NmzJ9q2bYvo6GhMnjzZuizHfffdh/bt26OgoAC9evVCWloaunXrhpSUFGzatAlvvfWW3es8/fTTmDZtGsrKyjBt2jTEx8ejR48eaN++PaKionDrrbdi9+7dHntfK1aswNChQ3Ho0CH0798fSUlJ6NmzJ6677jo0bNgQrVu3xpNPPolz58557JpERES+xICSiIhqXVhYGL766it88cUXGDFiBLRaLX7//Xfo9Xpcd911mDdvHm688UYAldVWt2zZggceeADJyck4efIksrKyMGbMGPz2228YMmSI3etoNBq899572LhxI8aOHYuIiAjs3bsXOTk56NChA2bPno0pU6Z47H3Fxsbiv//9L1auXIlbbrnF+r4OHTqE6OhoTJo0CZ9//jlmzJjhsWsSERH5kiRYao6IiIiIiIjcwAwlERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQElERERERERuYUBJREREREREbmFASURERERERG5hQGlG44cOYKFCxciPT0dnTt3RlBQECRJwrx58zx+rZ9//hnz58/HuHHj0KJFC0iSBEmSsHXrVoft9uzZg1deeQWTJk1CamoqNBoNJEnCp59+6vE+EhERERFR/RTk6w4EonfffRdvvPFGrVzroYcewt69e11u99xzz2Ht2rVe6BEREREREVElZijd0KlTJzz++OP47LPPcOjQIUyePNlr1xo2bBjmzp2Lr7/+GufOnUPz5s2date7d2/Mnj0bq1atwvHjxzFw4ECv9ZGIiIiIiOonZijdcO+998q2NRrvxeX//ve/3Wo3c+ZMD/eEiIiIiIhIjhnKWmQ0GvHhhx9i0KBBiIuLQ0hICFq2bIkHHngAZ8+e9XX3iIiIiIiIXMKAspbo9XoMGzYM9913H3bv3o1rrrkGo0ePRkhICBYtWoSuXbsiIyPD190kIiIiIiJyGgPKWjJ9+nRs3rwZN910E44fP47Nmzdj5cqVOHz4MBYsWIDc3FxMmDABJpPJ110lIiIiIiJyCgPKWnDo0CF8/vnnaNy4MZYtW4aGDRvKjj/yyCMYOXIkjh49iu+++85HvSQiIiIiInINA8pa8O2330IIgREjRiAqKsrmOYMGDQIAbN++vRZ7RkRERERE5D5Wea0FJ06cAAAsXrwYixcvdnhudnZ2bXSJiIiIiIioxhhQ1gKz2QwAuPbaa9GlSxeH5/bq1as2ukRERERERFRjDChrQdOmTQEAffv2xVtvveXj3hAREREREXkG51DWghEjRgAAvv76a5SVlfm4N0RERERERJ7BgLIWdO3aFePGjcPZs2cxduxYnDp1SnVOcXExPvvsM1y6dKn2O0hERH7nzJkzePDBB5GWloawsDCEhoaiZcuWmDp1Kvbu3Wu33aZNmzBy5EgkJCQgLCwM7dq1w1NPPYWioiKH1zt27BjS09ORkpKCkJAQpKSkID093VoHgIiIyBZJCCF83YlAs2fPHvzf//2fdfv48ePIyclBSkoKmjRpYt2/Zs0aJCcnAwD0ej3GjBmDH374AcHBwejSpQtatmwJIQROnTqFvXv3oqKiAocOHUK7du2sr/Hhhx/iww8/tG5nZGSgoqICHTp0sFaMTU5Oxpo1a2R9XL9+PZ5//nnr9sGDB6HX69G6dWskJCRY9//yyy8euitEROQpv/76K4YNGwa9Xo8mTZrguuuug1arxe+//46TJ08iKCgIy5Ytw+233y5rt2DBAsyYMQOSJKF///5ISkrCli1bcPHiRaSlpWHr1q2yZ4DFtm3bMHz4cJSUlKBjx47o1KkT9u/fjwMHDiAiIgKbNm1C7969a+vtExFRIBHksh9//FEAqPbr5MmTsnYmk0ksW7ZMjBw5UiQlJQmdTifi4+NFp06dxN133y3WrFkjKioqZG2effbZaq/TvHlzVR+XLFniVB+JiMj/XHPNNQKAmDZtmuy5YDKZxNNPPy0AiNjYWFFaWmo9tmfPHiFJktBqteLbb7+17i8uLhZDhgwRAMS4ceNU1youLhaNGzcWAMSsWbNkx2bNmiUAiKZNm4qSkhIvvFMiIgp0zFASERH5kdzcXGsW8fLly0hMTJQdN5lMiIqKQmlpKfbs2YOuXbsCAMaPH4+VK1fi3nvvxQcffCBrc/r0abRq1Qpms1k1Euadd97B3/72N6SmpuLQoUPQaK7OhjGbzWjfvj0yMzOxaNEi3H///d5620REFKA4h5KIiMiPhISEOH2uJfCsqKjA+vXrAQB33HGH6rzmzZujb9++AKCaImHZnjhxoiyYBACNRoMJEyYAAL788kun+0VERPUHA0oiIiI/EhkZif79+wMAnn76aRgMBusxs9mMuXPnorS0FCNGjLAuS5WZmYmSkhIAQPfu3W2+rmV/RkaGbL9l29V2REREANehdIrZbMaFCxcQFRUFSZJ83R0iIvqTEAJ6vR6NGzdWZdcC2QcffICRI0fi/fffx/r169G9e3dotVpkZGTg/PnzmDx5smxd45MnTwIAYmNjrQXblCzBp+VcoLJgXG5uLgCgWbNmDttlZ2ejuLgYERERNXpv586dk22bzWZoNBo+Y4mI/Iyzz1gGlE64cOGC9YFKRET+5+zZs0hJSfF1NzwmLS0NO3bswOTJk7FhwwacP3/eeqxDhw4YNGgQoqOjrfv0ej0AOAz2IiMjAQCFhYWqdo7aWtpZ2tY0oOTzlIgosFT3jGVA6QTLp71nz56VPcCJiMi3CgsL0bRpU7tZuUC1bds2jB071ro8yODBgxEcHIxt27ZhxowZuOeee7Bt2zYsXrzY1131GD5jiYj8i7PPWAaUTrAMwYmOjubDjojID9WloZL5+fkYM2YMcnJysGPHDvTq1ct67KabbkKHDh3QuXNn/Oc//8Fdd92FG264wfqwLy4utvu6RUVFACB7jlX9JcFeW0s7ZVt3nT17Vrat1+vRoUMHPmOJiPxUdc/YujPhhIiIqA5Yv349srOz0apVK1kwaVF1/6ZNmwAALVq0AFAZjFYdxlqVJZCznAtUBpRxcXEAgDNnzjhsl5CQUOPhrgCQkpIi+2rSpEmNX5OIiHyHASUREZEfsQR2jrJ1MTExAIC8vDwAlXMuw8PDAQC7du2y2cayv1u3brL9lm1X2xEREQEMKImIiPyKJWN3+PBhFBQUqI4bDAbs2bMHANCyZUsAQHBwMEaNGgUAWLZsmarN6dOnsX37dgDAmDFjZMcs28uXL4fZbJYdM5vNWLFiBQBg7Nixbr8nIiKquxhQEhER+ZERI0YgIiICpaWluO+++2RzGCsqKvDoo4/izJkz0Ol0uO2226zHZs6cCUmSsGTJEnz//ffW/SUlJbjnnntgMpkwbtw4tGvXTna99PR0NG7cGJmZmZgzZ47s2Jw5c5CZmYmUlBRMmTLFS++YiIgCmSSEEL7uhL8rLCxETEwMCgoKWDCAiMiP1NWfz59++inuvvtuGI1GJCYmokePHtDpdNi1axfOnz8PjUaDt99+G9OnT5e1W7BgAWbMmAFJkjBw4EA0bNgQW7ZsQVZWFtLS0rB161YkJCSorrdt2zYMHz4cJSUl6NSpEzp16oT9+/dj//79iIiIwKZNm9C7d2+vvNe6+j0kIgp0zv58ZkDpBD7siIj8U13++bx37168/vrr+Pnnn3H+/HkIIZCcnIx+/frhoYceQs+ePW2227RpE1599VX89ttvKC4uRrNmzXDbbbdh1qxZDku/Hzt2DM8//zw2bdqE7OxsJCYmYujQoXjmmWfQunVrb73NOv09JCIKZAwoPYgPOyIi/8Sfz4GP30MiIv/k7M9nzqEkIiIiIiIitzCgJCIiIiIiIrcE+boDRER10ZWSCtzzxV7sOVeAv/VtgSduaOPrLhEREZGfOJVXguUZ57F6XxZyiw24LiUG465Jxqj2SYgKDawQLbB6S0QUID745QzW7LsIAPjHN4cw7ppktIqP8HGviIiIyFuEECg3mlFhMsNoFtBIEjQSoJEkaDUSCkoNWP1HFj7POI9tp67I2p7MK8GqP7IQEqTB8NREjO2cjP6t4hAfEYzokCBoNJKP3lX1GFASEXnBwUt62fbhy0UMKImIiOqQt7eexIKfT+BSUTnKjWYYTDWvdVpuNGPdwUtYd/CSdZ9GAhqE6RAXHoyo0CCYzQLGP79Mf/4pYP/aC0Z3xK2dk2vcN3sYUBIReYHyoeKJhwwRERH5h8OX9Hjoq/0w18Lj3SyA3BIDcksMbrUvrjB5uEdyDCiJiLygwmR2uE1ERESB6+cTeTUKJsN0Gozu2Ah3dG2CzsnRWH/oElb/kYWfT+TWSpDqSQwoiYi8wKAIIJXbREREFLgOXy6SbUeHBiEqJAghQRqEBGkQpJEgBGASAmazgFkAAkD7hpGYcG1j3NKpESJDroZiD/ZriQf7tcRlfTm+PnAR/z2SjazCMuSVGpBXYkBeSYXfjnZiQElE5AUGxceLFUb/fAgQERGR65QB5Xf39sL1LeNq/LoNo0Jwb+/muLd3c9l+IQSKK0zQlxsRpJEQpKks9GP5UyPZL9qjdXDMExhQEhF5QYVRkaE0M0NJRERUVxzJlgeUaQ0jvXo9SZIQGRIky2r6C42vO0BEVBcpM5T+OkyFiIiIXFNmMOFkXol1OyEiGPERwT7skW8xoCQi8gJlhpJFeYiIiOqGYznFEFU+J27n5eykv2NASUTkBcohrizKQ0REVDco50+mJTKgJCIiD1MW4WGGkoiIqG5Qzp9khpKIiDxOnaHkHEoiIqK6QJWhbBjho574BwaUREReoAwgOeSViIiobjhyuVi2zQwlERF5nHKIawUzlERERAFPCCHLUOq0ElrGhfuwR77HgJKIyAuUGUlmKImIiALfRX059OVG63abhAgEaet3SFW/3z0RkZdw2RAiIqK6hxVe1RhQEhF5gcGsnEPJIa9ERESBThlQ1vf5kwADSiIir1AOcWWGkoiIKPAdYYZShQElEZEXKIvwMENJREQU+FQZyiQGlAwoiYg8zGwWMKmGvDJDSUREFOiOZCszlPV7DUqAASURkccZzOrgkUNeiYiIAlupwYTTV0qt2w0jg9EgPNiHPfIPDCiJiDzM1vBWDnklIiIKbEeziyGqPM7TWJAHAANKIiKPs5WNZIaSiIgosLHCq20MKImIPMx2hpIBJRERUSBTzp9kQFkpYALKzz77DFOmTEGXLl3QsGFD6HQ6xMTEoGfPnnjhhRdQVFRU/YsQEdUCW8GjsuorERERBZbDl7hkiC1Bvu6As959911s374d7du3R7du3RAXF4dLly5hx44d2LlzJ/7zn//gp59+QuPGjX3dVSKq52wNb2WGkoiIKLAxQ2lbwASUr776Ktq2bYu4uDjZ/tzcXNx6663YunUrHnvsMXz++ec+6iERUSUW5SEiIqpbhBCyOZTBWg1axIX7sEf+I2CGvPbq1UsVTAJAfHw85s+fDwDYsGFDbXeLiEiFRXmIiIjqlvMFZSiuMFm32yZGQKuRfNgj/xEwAaUjQUGVidaQkBAf94SIyPbwVg55JSIiClxHLivnT0b4qCf+J+ADSr1ej7lz5wIARo8e7dvOEBHB9vBWZiiJiIgCF5cMsS9g5lBabNiwAcuWLYPZbLYW5dHr9bjxxhvx0ksveeQa586dk23r9XqPvC4R1Q+2i/JwDiUREVGgOpJdLNtOY0BpFXAB5cGDB7F06VLZvjvuuAOvvfYaYmJiPHKNpk2beuR1iKh+4jqUREREdcvhy/IEEzOUVwXckNdHHnkEQghUVFTg2LFjePXVV/Hdd9+hQ4cO+Pnnn33dPSIiO0V5mKEkIiIKVKoMJdegtAq4DKWFTqdD69atMWPGDPTt2xd9+vTBXXfdhSNHjiAsLKxGr3327FnZtl6vR4cOHWr0mkRUf7AoDxERUd1RXG7EmSul1u1GUSGICdP5sEf+JWADyqp69eqFDh064MCBA9i1axf69+9fo9dLSUmRbRcWFtbo9YiofuGyIURERHXH0RzOn3Qk4Ia82hMRUVm69/Llyz7uCRHVd7bmUJoFYDJz2CsREVGgYYVXx+pEQJmTk4O9e/cCAFJTU33cGyKq7+wNb/X3Ya/rDlzE6MW/4Z//PYIKo3/3lYiIqLZwDUrHAiKgPHjwID777DOUlZWpjmVmZuL2229HeXk5evfujc6dO/ugh0REV9krwOPPS4dcLCzDrUt2Yt3BS5i7IROf7D5XfSMiIqJ6gBlKxwJiDuXly5dx11134f7770fXrl2RkpKCiooKnDlzBnv27IHZbEb79u2xYsUKX3eViMh+htLsv1m/XecKUHVE7taTebinVzPfdYiIiMhPHMlWZCgZUMoEREDZsWNH/Otf/8KWLVtw+PBhZGRkwGAwIC4uDkOGDMHYsWNx9913IyQkxNddJSKyW4DHn4eRKvumLzf6qCdERET+w2wWsgxlSJAGzRuE+7BH/icgAsrExETMnj3b190gInKKvaGt/jzkVRkE68sYUBIREZ3NL0Wp4eozMi0xElqN5MMe+Z+AmENJRBRI7A159eelQ8qZoSQiIlLh/MnqMaAkIvIw+0V5/DegVGUoGVASERHhEAPKajGgJCLyMPsZSj8e8soMJRERkYoyQ9k+iQGlEgNKIiIPsze0lRlKIiKiwMIhr9VjQElE5GF2i/KY/ThDqegzA0oiIiLg0CW99e+SBKQmRviwN/6JASURkYcF5LIhij4bTALlRpOPekNEROR7eSUVuFxUYd1u3iAM4cEBsUhGrWJASUTkYfaGtvrzkFdllVeAS4cQEVH9doTDXZ3CgJKIyMPsDXn152VDbGVP9eXMUBIRUf116BIDSmcwoCQi8jD7RXn8eQ6lrYCSGUoiIqq/VBVeG0b5qCf+jQElEZGH2S/K48cZSgaUREREMqzw6hwGlEREHma/KI8fZyht9I0BJRER1WeHGFA6hQElEZGH2S3KwwwlERFRQCg3mnAit9i6HReuQ2JksA975L8YUBIReZjdojx+vGwIq7z6p4qKCrz55pvo168f4uLiEBoaipSUFIwYMQIrVqyw2WbTpk0YOXIkEhISEBYWhnbt2uGpp55CUVGRzfMtjh07hvT0dKSkpCAkJAQpKSlIT0/HiRMnvPHWiIj82rGcElRdPrpdw0hIkuS7DvkxBpRERB5mtyiP2Y+HvDJD6XfOnTuHrl274uGHH8aRI0fQt29f3HrrrWjevDl+/vlnrFy5UtVmwYIFGDZsGL7//nt07NgRN998MwoKCjB//nx0794dOTk5Nq+1bds2dOnSBUuXLkVsbCzGjBmD2NhYLF26FNdccw1++eUXb79dIiK/cuiSXrbN4a72cWVOIiIPszfk1Z8zlAwo/UtpaSmGDRuGw4cPY+7cuZg9ezZ0Op31eElJCTIzM2VtMjIy8Nhjj0Gr1WLdunUYMWKE9dzRo0fjhx9+wPTp07Fq1SpZu5KSEowfPx4lJSWYNWsW5s+fbz02e/ZsvPDCCxg/fjyOHDmCsLAwL75rIiL/wQqvzmOGkojIwyrsVXn152VDbK5DyYDSV1544QUcPnwY06ZNw7PPPisLJgEgPDwc1157raqNEAJ33323NZi0nLt48WJoNBqsXr0ahw8flrX76KOPcOHCBaSmpmLevHmyY/PmzUNqairOnj2Ljz/+2LNvkojIj6kqvCYxQ2kPA0oiIg9jUR6qCYPBgHfffRcA8MQTTzjVpqKiAuvXrwcA3HHHHarjzZs3R9++fQEAa9askR2zbE+cOBEajfzXAo1GgwkTJgAAvvzySxfeBRFRYGOFV+dxyCsRkYfZXzbEnwNKLhviL/bs2YOcnBw0btwYbdq0wb59+/Dll1/iwoULaNCgAfr3748RI0bIgr/MzEyUlJQAALp3727zdbt3744tW7YgIyNDtt+y7ahd1fNq6ty5c7JtvV5v50wiIt8wm4UsQxms1aBlXLgPe+TfGFASEXmYvaGt/lyUp9xoUu1jlVff+OOPPwAAKSkpmDlzJl5++WUIcfXfzksvvYSuXbviq6++QrNmzQAAJ0+eBADExsYiKsr2PJ+mTZvKzgUqg7nc3FwAsL6WvXbZ2dkoLi5GRERETd6e9fWIiPzV+YIylFRcfS6mJkZAq2GFV3s45JWIyMPsDW0NvAylOsgk77MEeBkZGXjppZfwf//3fzhy5AgKCgqwceNGpKamIiMjA6NGjYLBYABwNcvnKNiLjKwcrlVYWGjdVzU7aK+tpZ2yLRFRXXXoMiu8uoIZSiIiD6sw2stQ+nFAyaI8fsOSjTQYDJg0aRLeeust67GhQ4di48aNSEtLw/79+7F8+XJMnjzZV111y9mzZ2Xber0eHTp08FFviIjUVBVeWZDHIWYoiYg8zH6G0n+HvLIoj/+oOmT1/vvvVx1v1qwZRo0aBQDYtGmTrE1xcbHd1y0qqvwFKTo62ua17LW1tFO2dVdKSorsq0mTJjV+TSIiT1JVeGWG0iEGlEREHmZvaKtfZygZUPqNVq1a2fy7rXOysrIAAC1atAAA5Ofn2y1yY8kMWs4FKgPKuLg4AMCZM2cctktISKjx/EkiokBw6BIDSlcwoCQi8jB7xXf8eR3Kcg559RvdunWDJFUWf8jJybF5jmW/ZX5jWloawsMrKxDu2rXLZhvL/m7duqmu5047IqK6SpmhTEtkQOkIA0oiIg+ztw6lfxflUfetqNwoqy5KtaNRo0bo168fgKtDWqsyGAz46aefAAA9e/YEAAQHB1uHwS5btkzV5vTp09i+fTsAYMyYMbJjlu3ly5fDrMiim81mrFixAgAwduxYt98TEVGgyC814KK+3LrdrEEYIkJYdsYRBpRERB4khHCwbIgfB5Q25neaBWRl06n2PPvsswCAF154Ab/88ot1v9FoxGOPPYYTJ04gKioKd999t/XYzJkzIUkSlixZgu+//966v6SkBPfccw9MJhPGjRuHdu3aya6Vnp6Oxo0bIzMzE3PmzJEdmzNnDjIzM5GSkoIpU6Z4460SEfkVVUEeDnetFsNtIiIPMjpYa9JfM5RCCJsZSqBy2Cs/ma19Q4YMwfPPP485c+agf//+6NmzJxo1aoQ9e/bg1KlTCAsLw+eff46kpCRrm27duuHVV1/FjBkzMHLkSAwcOBANGzbEli1bkJWVhbS0NCxatEh1rfDwcHzxxRcYPnw45s+fj6+//hqdOnXC/v37sX//fkRERGDlypUICwurzVtAROQThzl/0mXMUBIReZCjoNHe3EpfcxQEcx6l7zz99NP473//i2HDhuHw4cNYt24dTCYT0tPTsWfPHusQ16oeffRRbNy4EX/5y1/wxx9/YO3atYiMjMSsWbOwc+dOJCQk2LxW3759sXfvXkyZMgV5eXlYvXo18vLyMGXKFOzduxe9e/f29tslIvILrPDqOn7sTETkQY6CRntzK33NURDMgNK3hg8fjuHDh7vUZujQoRg6dKjL12rTpg2WLl3qcjsiorrk0GV5pWyuQVk9ZiiJiDzIUdBY4adVXssd9JkBJRER1SfqDGWUnTPJghlKIiIPsjcXEQjUDCWL8hARUe0TQqCwzIjzBWU4X1CGK6UGFJYZUFhuRGGZEfpyIyqMZrROiECnRlHo1CgKSVEh1mWX3FFhNON4bol1OzZMh4aRwZ54O3UaA0oiIg9ytNako2DTlxz1S1/GDCUREXmf0WTGeztO48t9F3GuoBTnC8pQ7GKl8fhwHTolR2Ngq3g8MqAlGoTbDwZ/PJaDGWsP4FxBmXWfWQiYqkxdad8wskYBan3BgJKIyIMcZyj9c8iro6G4HPJKRES14dPd5/Hgmv01eo3cEgN+Op6Ln47n4rM957D2rz3RsZF6yOrSnWdx7xd7HRalA1iQx1mcQ0lE5EEBmaFkUR4iIvKxr/ZnefT1jueWoM+bW7HuwEXrPiEE5v73CNKX/15tMAkAvZrHerRPdRUzlEREHuRw2RC/zVAyoCQiIt/KzCmWbYfpNGgSE4YmMaFoEh2KhMhgxIQGITpEh+jQIESHBkGIyqqs+y/qsT9Lj2O5xRBVHrX6ciNuWbIT80e0w4yBrTFt5V4s3XVOdh1JAoK18hybTivhpvZJmHxditfeb13CgJKIyIMM5sArylPODCUREfmQySxwPOdqMZyIYC3080e4PH+xpMKIhVtPYda3h6yBpRDArG8PY+HWU7hQWCY7PzEyGOv+2hO9mjeo8XuozzjklYjIgwJyyCszlERE5ENn80tlz6K2CRFuFcMJDw7Ck4PbYN1feyIqRJ43UwaTaYkR+OWhfgwmPYABJRGRBwVkUR5HGUpWeSUiIi87mi0f7to2MaJGrzeqQxJ+fbgfWseH2zzev1Uctj/UD63ia3YdqsSAkojIgxwNa2WGkoiISC0zu0i23Tah5oFe+6Qo/PZIfwxpmyDbP/HaxtgwrTfiHCwpQq7hHEoiIg9ytASHv86h5LIhRETkS0cVBXlSEz2zXEdceDC+v68XXtl8HBszczC6YxL+3q8lNBquLelJDCiJiDzIcYbSP4e8sigPERH5kjKg9ESG0iJIq8HMIW0xc0hbj70myXHIKxGRBzmaJ2kyCwjhf0Gl4yGvplrsCRER1UeZHp5DSbWLASURkQdVN0/SHwvzOCzKwwwlERF5kcFkxsm8q0uGxIbpkBDB+Y2BhAElEZEHVTdP0h8L87AoDxER+cqpvBKYzFc/bHV3yRDyHQaUREQeVH2GMrACypIKk+xBT0RE5EnenD9JtYMBJRGRB1U3pNUfC/NUGB33qYhZSiIi8hLOnwx8DCiJiDwoEDOU5SbHhXc47JWIiLzlaLZyyRAGlIGGASURkQdVl6H0z6I8jvvEgJKIiLzlaE6RbLttgmfWoKTaw4CSiMiD6lpRHoABJREReQ+HvAY+BpRERB4UiENelX0O1sofDfoyBpREROR5ZQYTzuSXWrcTI4MRG6bzYY/IHQwoiYg8qPqiPH4YUCrWoYyPkD/MmaEkIiJvOJFbAlHlsckKr4GJASURkQdVn6H0wzmUij7Hh8sXlGZASURE3sAlQ+oGBpRERB6kDBiVw0f9MUNZrspQKgNKx1VgiYiI3JGZLS/Ik5rIgjyBiAElEZEHKedIRgRrFcf9MUMp71OCKqBkhpKIiDxPlaFkQZ6AxICSiMiDlBnIcFVA6X8ZSvWQV86hJCIi71OuQckhr4GJASURkQcpM5DKDKU/DnlVF+VhhpKIiLxPuWRIGwaUAYkBJRGRBykDxsAY8lpNUR4uG0JERB5WXG7EhcIy63bj6FBEhgT5sEfkLgaUREQepJ5DKX84+mWGklVeiYiolh3L5fzJuoIBJRGRBykL3KgzlP4XUKqrvHIOJREReZdy/mQqA8qAxYCSiMiDqqvyqgw4/YEyQ8kqr0RE5G3K+ZMsyBO4GFASEXmQuihPkOK4/2UoK4zyPrMoDxEReZtqyRAGlAGLASURkQdVv2yI/2coOYeSiIi87Wh2kWy7bWKkj3pCNcWAkojIg6of8uqHGUpFn6JCgqDTStZtVnklIiJPy6ySoZQkoHV8uA97QzXBgJKIyIOqXzbE/wJKZVEenVZCVJXS7fpyU213iYiI6rCCUgOyiyqs281iwxCq0zpoQf6MASURkQdVN4fS34vy6LQSJEkeUFaYzKgw+l8gTEREgYnzJ+uWgAgoDQYDfvjhBzzxxBPo0aMHYmNjodPp0KhRI4wePRrr16/3dReJiABUP+TVHzOUVYPFYG3lYyFKsbg051ESEZGnZCrmT6Zy/mRAC6r+FN/76aefMGzYMABAo0aN0K9fP0RERODgwYNYt24d1q1bh2nTpmHRokWQJKmaVyMi8h5lBjJcF1hFeUKC7AeUyuqvRERE7lCuQdmWa1AGtIDIUGo0GowbNw4///wzsrKy8M0332DFihXYt28fli9fDq1Wi/fffx+ffPKJr7tKRPWcMgOprPLqn0V5rga59jKURcxQEhGRh3DIa90SEAHl4MGDsWrVKvTv3191bMKECUhPTwcAfPzxx7XcMyIiuaoBo1YjWTN+Fv425NVkFjCZqwSUlgxlKIe8EhGRdygDylRmKANaQASU1enatSsA4OzZsz7uCRHVdwZZtk+yZvws/C1DqewP51ASEZE3CSGQWWXIq1YjoUUclwwJZHUioDx69CgAIDk52cc9IaL6Tl4xVSNbzxHwvzmUyuqtwX/2lwElERF5Q25xBfJLDdbtlnHh0GnrREhSbwVEUR5HLl68iI8++ggAMG7cOI+85rlz52Tber3eI69LRHWfQTEfMXAzlPK5n/oyrkVJREQ1x/mTdU9AB5RGoxF33XUXCgoK0LlzZ9x///0eed2mTZt65HWIqH4RQsBglq/pqPzU1e8ylIqA0lGVVyIioprKVFR4TWvIgDLQBXR+efr06fjhhx8QHx+PVatWITiYJe2JyHdMZgFRJV60OeTV7GcZSqM8wA1mQElERF7ENSjrnoDNUD788MNYvHgxGjRogI0bNyI1NdVjr60s7qPX69GhQwePvT4R1U0GsyI4szXk1ehnAaW9Ia+s8kpERF6gzFCmcshrwAvIgPKxxx7Dm2++idjYWGzYsMFa5dVTUlJSZNuFhYUefX0iqpuUwWIgDHktVxXlYYaSiIi8RxVQMkMZ8AIuoPzHP/6B1157DTExMdiwYQO6d+/u6y4REQFQrzFZmaGUD3n1/6I8rPLqLJPJhKNHj+LKlSswGAwOzx0wYEAt9YqIyH+ZzQJHc64OeQ3TadAkJtSHPSJPCKiAcubMmfj3v/+NmJgYbNy4ET169PB1l4iIrJRDXm1nKP0soFRmKDmHslqnTp3C7NmzsXbtWpSVlVV7viRJMBp5/4iIzheUodRw9bnTNiESGo3koAUFgoAJKJ9++mm89NJL1mGuDCaJyN+ohrxqbC0b4l9DXp2u8lrGgAgADh8+jP79+yMvLw9COPe9dPY8IqK6Tl2Qh/Mn64KACCi//vpr/Otf/wIAtGnTBm+//bbN8xISEvDKK6/UZteIiKxURXmCbFR59bcMpd11KJmhtGXmzJnIzc1Fo0aN8PLLL2PIkCFISkqCRhPQRdOJiGpFZo5y/iQDyrqgRgFlq1atXG4jSRKOHz/uUpu8vDzr33ft2oVdu3bZPK958+YMKInIZ9QZShtDXs3+la2yW5SHVV5t+umnnyBJElatWoXrr7/e190hIgooXDKkbqpRQHnq1CmnzpMkyTrkR5JcHyednp6O9PR0l9sREdUm5RqTwUE2ivL4+7Ihfw55jQzWyvYzoKxkNpsRERHBYJKIyA3qCq/MUNYFNQoolyxZ4vB4QUEBdu7cidWrVyM8PBz//Oc/ERnJTyKIqG5SLgliO0PpZwGlUb12JgAEaTUI02msxRP05aZa75s/SktLwx9//AGj0YigoICYNUJE5De4ZEjdVKOn4dSpU50679lnn8Xw4cPx8ccfY8uWLTW5JBGR37JVMTVIo8xQ+teQV3tFeYDKeZSlhgoAlRlKIYRbo0zqkmnTpmHatGlYuXIlJk2a5OvuEBEFjAqjGSfzSqzbceE6xEcE+7BH5Cm1UkWgTZs2WLRoEXbu3ImXXnqpNi5JRFTrlNlHnUYDSZJkhXn8LkNppygPIC/MYzILlPnZcF1fuPfeezFx4kRMnz4dn332Wa1d9x//+AckSYIkSZg3b57d8zZt2oSRI0ciISEBYWFhaNeuHZ566ikUFRXZbQMAx44dQ3p6OlJSUhASEoKUlBSkp6fjxIkTnn4rRFRPncwrgalKHQFmJ+uOWhuvM2zYMISGhmLZsmWYM2dObV2WiKjWKLOPlkBSp9XAYKocMqocFutrqqxqleDX1tIhYTr53Mr6aNmyZXjmmWcwZcoUzJ49Gx06dEBycrLd8yVJwuLFi92+3vbt2/Hqq6/K6hHYsmDBAsyYMQOSJKF///5ISkrCli1bMH/+fKxevRpbt25FQkKCqt22bdswfPhwlJSUoGPHjujXrx/279+PpUuXYtWqVdi0aRN69+7tdv+JiAAuGVKX1eoEEI1Gg9OnT9fmJYmIao2tojxAZdavBJUBpTIj6GvldoryALYrvTaMCqmVfvmzt99+G2+88QYA4OzZszh79qzN8ywBYE0CypKSEqSnpyM5ORk9evTAV199ZfO8jIwMPPbYY9BqtVi3bh1GjBhhbT969Gj88MMPmD59OlatWqV6/fHjx6OkpASzZs3C/Pnzrcdmz56NF154AePHj8eRI0cQFhbm1nsgIgJYkKcuq7WAcvv27SgpKUF8fHxtXZKIqFaplw2pDM5kQ179LKBUZyhtD3kFWOkVAFasWIG///3vAIDo6Gj07t0bDRs2hFbrncztrFmzcPToUaxfvx5ffPGF3fNeeOEFCCFw9913W4NJAAgPD8fixYvRqlUrrF69GocPH0a7du2sxz/66CNcuHABqampqqG08+bNw+rVq5GZmYmPP/4Y999/v+ffIBHVG1wypO7yekBpNBqxbt06PProo5AkCQMGDPD2JYmIfEK5xmRwUGUgWTVIM5iEXxW3qTDZrvIKMKC0xbLW8a233opPP/0U4eHhXrvW5s2bsXDhQkyZMgUjR460G1BWVFRg/fr1AIA77rhDdbx58+bo27cvtmzZgjVr1mDWrFnWY2vWrAEATJw4ERqNvKyCRqPBhAkT8Pzzz+PLL79kQElENcIMZd1Vo4CyVatWDo+XlZXh8uXLEKLyF6iIiAjMnTu3JpckIvJbyuyjrQwlABjNQrXPV6qr8loVA0rg0KFDkCQJH3zwgVeDyaKiIvz1r39FUlISXn/9dYfnZmZmoqSksnJi9+7dbZ7TvXt3bNmyBRkZGbL9lm1H7aqeR0TkLmVA2SaeAWVdUaOA8tSpU06f27t3b7z55pvo3LlzTS5JROS3VGs6VplDKT/PrFqf0ldcGvJaxoAyMjISwcHBXp++8fjjj+PkyZNYs2YNGjRo4PDckydPAgBiY2MRFRVl85ymTZvKzgUAvV6P3NxcAECzZs0ctsvOzkZxcTEiImr+C+C5c+dk23q9vsavSUT+rajciAuFZdbtlJhQRIRwLd+6okbfySVLljh+8aAgNGjQAJ07d7Y+lIiI6ir1siFXq7zKz/OfSq+qZUOCHFR5ZYYSffv2xdq1a5GdnY3ExESvXGPDhg147733MHHiRNx6663Vnm8JyBwFe5GRlXOVCgsLVe0ctbW0s7T1REDJ3weI6p+jquGunD9Zl9QooJw6daqn+kFEFPBURXn+DCQtgaWFPxXmKWdRHpc89dRTWL9+PZ5++mm89957Hn/9goIC3HPPPUhMTMTChQs9/vpERL7AJUPqNuaaiYg8RFWU58/grOpSHIB/LR2iylBWDShD5ZVL9eWmWumTP+vWrRtWr16NyZMn48SJE3jyySfRuXNnJCUleeT1H3nkEZw7dw4rVqywuWakLZZhrsXFxXbPKSqq/GUuOjpa1c5RW0s7ZduaUC6zotfr0aFDB4+8NhH5p8wcFuSpyzweUObn5yM7OxsAkJiYiNjYWE9fgojIobySCjz17WHklxrwjxvaoGtKTK1cV1WU58/CO+oMpT8PeWWG0pGqy4P873//w//+979q20iSBKPRuXu3Zs0aBAUF4Z133sE777wjO3b48GEAwOLFi7Fp0yY0atQIy5cvR4sWLQBUPn/1er3NeZSWIM5yLlAZUMbFxSEvLw9nzpxBly5d7LZLSEjwyHBXAEhJSZFtVx2GS0R1E5cMqds8ElBevnwZr732GlauXKkq1NOiRQuMHz8ejz76KBo2bOiJyxEROfTwV/vx6e7zAIC1By5i+V3XYXSnRl6/rr3gzK8zlIpCQiEc8uqQEN7/MMBoNOKnn36ye/zUqVM4deoUmjdvDgBIS0tDeHg4SkpKsGvXLtxwww2qNrt27QJQmWGtqlu3bti0aRN27dqFm2++2el2RESu4JIhdVuNA8pNmzZhwoQJyM/Pt/mgPXnyJF5++WW8//77WLFiBYYOHVrTSxIROfTL6Xzr30sNZoz5aCcW3XYN7uvd3KvXVWYerUV5FOv7BWyGklVe8eOPP3r19fPz8+0eS09Px9KlS/H888/j6aeftu4PDg7GqFGjsHLlSixbtkwVUJ4+fRrbt28HAIwZM0Z2bMyYMdi0aROWL1+OZ599VrYWpdlsxooVKwAAY8eOrelbI6J6SgghCyi1Ggkt4ry37BLVvhoFlIcOHcLNN9+M8vJyJCYm4oEHHsDAgQPRpEkTAMCFCxfw008/YdGiRbh06RJGjx6N3bt3o3379h7pPBGRLcUV8sDHLIBpK//A+YIyPDs8FZLknTUglcGZtSiPYs1JZfEeX3I4h5IZSpWBAwf6ugs2zZw5E6tWrcKSJUswbtw43HjjjQCAkpIS3HPPPTCZTBg3bhzatWsna5eeno5//etfyMzMxJw5c/Cvf/3LemzOnDnIzMxESkoKpkyZUqvvh4jqjpziCuSXGqzbreLC/WbpLPKMGgWUc+fORXl5OXr06IHvv/9etVZWamoqBg0ahIceegg33ngjdu7cieeeew6ff/55jTpNRORIcYXt4jH/3JCJ8wVleHdcZwR54WGmzDzaK8qjXF7El9RVXqssGxLKgDJQdOvWDa+++ipmzJiBkSNHYuDAgWjYsCG2bNmCrKwspKWlYdGiRap24eHh+OKLLzB8+HDMnz8fX3/9NTp16oT9+/dj//79iIiIwMqVKxEWFuaDd0VEdQGHu9Z9NfqN6scff4QkSVi8eLHDhZcbNGiADz/8EACcKmBAROQuIYTdgBIAPvz1DMZ8tMsrWUJ1hrKODXllQOnXHn30UWzcuBF/+ctf8Mcff2Dt2rWIjIzErFmzsHPnTrtVY/v27Yu9e/diypQpyMvLw+rVq5GXl4cpU6Zg79696N27dy2/EyKqS1iQp+6rUYayqKgI0dHR6NSpU7Xndu7cGTExMbIS5EREnlZhMsNUZfmO+HAd4sKDcbRKyfJvDl7Coh2n8FD/Vh69trLK69UMpWLIq18V5eGQ15q4ePEiLly4gOLiYocFewYMGFDja3300Uf46KOPHJ4zdOhQt2oVtGnTBkuXLnWzZ0RE9jFDWffVKKBs0aIFTp48CZPJJCulbovRaERZWRlatmxZk0sSETmkzE42ig7Fjw/0wU2Lf8NvZ/Kt+/dl6T1+bVVRHrsZSj8KKBV9CamSoYwI1kKSAEucxICyktlsxoIFC/DOO++oKpvb4sqyIUREdQ0zlHVfjYa8TpgwARUVFVi+fHm1565YsQLl5eWYNGlSTS5JRORQcbk8oIwI1iIxMgQvjZIXAytxMCzWXfYK3KiXDfGnIa+2530ClYFQZPDVzx0ZUFYGk7feeiv+8Y9/4OTJkxBCVPtl9qM5s0REtY0ZyrqvRgHlzJkz0atXL0yfPt1hULlixQpMnz4dffr0wZNPPlmTSxIROaSs8BoRrP3zzyCH53mCOkP5Z5VXjaQ4z38CDFVRHkXwW3XYa1G5CWaz/wTDvrB06VJ88803iIqKwmeffYa8vDwAQKNGjWA0GnH+/Hl88sknaN++PRISErBhwwYGlERUb5nNQjblJDxYi8bRoT7sEXlDjYa8vvTSSxg0aBAOHTqEO++8E7Nnz7a5bMipU6cQExODQYMG4cUXX7T5Ws8880xNukJEBAAoMSgzlJU/5sKDtQ7P8wS7RXm0AVSUR6sMKOX3rbjCpKr+Wp98+umnkCQJL774omrEjUajQXJyMu68806MGzcOQ4cOxZgxY7Bz507Vch1ERPXB2fxS2QeXbRMioNF4Z+ku8p0aLxtiWc9NCIFTp07h9OnTsnMsRQoKCgrsBpMAA0oi8gzlHMqrGUp1YORpdovyaJVDXv0nY1W1KI9GqlxwuipbS4fU54By7969AIA777xTtt9kkv97Cg0NxVtvvYVu3brhhRdeYMEbIqqXONy1fqjRbwUDBgzw2gLhRETusBdQhusUGUqvBJR2hrxq/XfIa9XgVhn4Aqz0qlRUVISYmBhERUVZ9wUHB9usYH7ttdciKioKP/74Y212kYhIprjciCx9ObIKy5BVWPnn5aJyFFWYUFxuQnGFEcUVJpQYTAjWatAqPhxtEyLQ5s+vFnFhkCBBX268+lVW2abMaEKZ0Ywyg+XPymeKViNBIwHbT12R9YUFeeqmGgWUmzdv9lA3iIg8Qz2HMujPP72foVQPH60MJNVFefwzoAwJUgeUkbUw9zSQNGzYEAUFBbJ9cXFxuHTpErKyspCcnGzdL4RAeXk5Ll++XNvdJCLC9pN5uH/VH9h/0fNVzd3FDGXdVKOiPERE/sZehjJMmaH0whxKZebRflEeP5pDabzaF2XgCwCRigxlUbnn71sgadq0KYqKiqzFeACgS5cuAIA1a9bIzv3uu+9QUVGBBg0a1GofiYgA4IHV+/wqmASYoayrXA4olyxZgrFjx+KRRx5x6nwhBB5++GGMHTsWn376qauXIyJyiTKgtBTj0WgkhOk0ds/zBOUSHDo/z1AKIaod8qrM7BbV8wxlnz59AABbtmyx7rvtttsghMCMGTPw3HPP4dtvv8Vrr72GyZMnQ5IkDB8+3FfdJaJ6KqeoHH9kFfq6GzJtEiLQPSXG190gL3BpyOuVK1fwyCOPoLi4GNu2bXOqjSRJmDhxIvr164eff/4Zt9xyi2zuCRGRJ9lah9IiXKdF6Z/zO7wzh9J2UR6dxj+rvCr7YSugjFRUea3vGcrbbrsNr732GpYuXYpbbrkFAJCeno7//Oc/2LFjB/75z39azxVCIDExEc8995yvuktE9VTGeXkw2SgqBNe3aIDk6FAkR4egUVQoYkKDEBGsRXiwFhHBlX/XlxtxLKcYx3JKcCynGEdzinHmSil0WglRIUFXv0KDEBmsRZhOi1CdBqFBWoQGaRASpIEkSTALAZNZwCwAsxCICQ3CpK5NEGTjOUOBz6WActmyZdDr9Rg/fjx69erldLs+ffrgtttuw6pVq7B8+XLcd999LneUiMgZ9tahBICIkCDklhgAVGYJjSazRx9u6mVD/Lsoj705n1VxDqVc7969VetKarVabNiwAc899xxWrVqFc+fOISYmBsOGDcO8efPQvHlzH/WWiOqrPeflc73v79Mcc/+S5lTbns04TJ9c49JvUt999x0kScLdd9/t8oX++te/QgiBdevWudyWiMhZ9tahBGxUevXwPEp7GT9/XTZE2Y+QIK3qHM6hdE5ERAReeuklHD9+3FqI57PPPkPLli1RWOhfw86IqO7bc04eUHZrwqGm5D0uBZSW9bcGDhzo8oUGDBggew0iIm+wV5RH+Xdb59aUuiiPJPvz6nn+MeS16hqUABAcZCtDyTmU7iooKMDcuXPRsmVLX3eFiOqZDEWGshvnLpIXuTTkNTc3FzExMQgNDXX5QmFhYYiJiUF2drbLbYmInOUooAwP9u5alPaGvAZKhtJ2UR5lhpIBZXXy8/OxYMECvPnmm8xOElGtKywz4GhOsXU7MTIYTWJc/92dyFkuBZRarRYVFRVuX8xgMECj4WRcIvIee+tQVv7d2xnKq5lHjVS5sDNwNbC0dZ4vlSszlE4U5fFGddxAsHHjRnz00Uc4cOAAzGYzWrVqhalTp2LMmDHWc8rKyvDqq6/i3//+N/R6PYQQCA8Px7333uvDnhNRffO7oiBPtyYxkCT1CBQiT3EpoExMTMTp06eRnZ2NxMREly6UnZ2NkpISFicgIq9ymKH08hzKqhm/qkGkcsir/2QonanyyjmUs2fPxksvvQSgsnIrABw4cADr1q3D9OnT8fbbb2Pfvn24/fbbcfToUQghEBsbiwcffBAPP/ww4uPjfdl9IqpnlAV5ONyVvM2ldGG3bt0AAN9++63LF1q/fr3sNYiIvMHeOpSAevhmsYeHb1bNPFYNzpSBmt9UeVXNobQRUNbzOZQ///wzXnzxRQghEB8fj5EjR2LEiBGIi4uDEAKLFi3CsmXLMHjwYGRmZiIxMREvv/wyzpw5g+eee47BJBHVOhbkodrmUkA5atQoCCEwf/58lJaWOt2utLQU8+fPhyRJGDVqlMudJCJylqNlQ1RzKD1e5bVqhlKq8nf/HPKqrvLKOZRK77//PoDKwnKZmZn45ptvsH79ehw5cgT9+vWDEALp6enIzc3FQw89hBMnTuDxxx9HZGSkj3tORPUVM5RU21wKKO+8806kpKTg2LFjuO2225wqNlBYWIhx48bh2LFjaNKkCSZPnux2Z4mIqqMe8lp7cyirBmjyDKW/Dnl1fQ5lUT2bQ/nLL79AkiQsWLAAsbGx1v1xcXFYsGABAMBkMuHBBx/E66+/jvDwcB/1lIgIKKkw4tAlvXU7JjQILeP4c4m8y6WAMjg4GIsXL4ZWq8X333+Pjh074pVXXsGRI0dU5x45cgT//ve/0alTJ/z3v/9FUFAQPvzwQ+h0Oo91nohIyaU5lB4MjkxmAXOVxKPjDKV/BJTqojw2lg1RzKFUZoDruosXLyIoKAjXXnut6ljXrl0RFFR5f/7+97/Xcs+IiNT+yNLLnkVdWZCHaoFLRXkAYNiwYVi6dCnuvfdenD9/Hk8++SSefPJJhISEoEGDBgCAK1euoLy8HEBlAYPQ0FB88MEHGD58uGd7T0SkUDVI1GklWTDnzQylMkh0NIdSWQzHV1QZSptzKOt3UZ6SkhI0atTI5i9kGo0G8fHxuHz5Mlq1auWD3hERyanmT3K4K9UCt9bwmDRpEnbu3IlbbrkFQGXQWFZWhqysLGRlZaGsrMxaCe+WW27Bzp07ceedd3qu10REdlTNoCnn/3lzDqVyXqSjKq/+kqFUFeWxMeRVec/q2xxKZ2m12upPIiLysgzl/EkW5KFa4HKG0qJDhw5Ys2YNsrKysHnzZhw8eBC5ubkAgPj4eHTo0AGDBg1CcnKyxzpLROSI2SxQargaJCkzkqoqrx4cvqnM9gVGUZ7qlw3RaiSE6TTW+1rf5lASEQUSFuQhX3A7oLRITk7GpEmTPNEXIqIaUWYc1QGl9+ZQujbk1U8ylE5UeQUq51GWGioA1L85lACQl5eHwYMH2z0GwO5xAJAkCT/88INX+kZEZFFhNGNf1tWCmeHBWqQmsuI0eV+NA0oiIn/hqCAPoC7K49k5lHVzyCtQOY8yG5UBpcEkUGE025xvWVdVVFRg8+bNDs9xdJwFMYioNhy4qJc9i65tHA2thj9/yPsYUBJRnaHMnikDSFWG0oNzKNVLcEhV/u6fGcpyVVEe2794qJcOMSIuKNhr/fInU6dO9XUXiIicohruyvmTVEsYUBJRneFoDUpAXWDGm1VeHWco/WQOpZMZSuV9LCo3Ii68fgSUS5Ys8XUXiIicoqzw2pUBJdWS+jNmiYjqPFVAGeK4KI8n51AqC9zoAiBDqc6q2hvy6r1AnIiIPIMFechXGFASUZ2hDBBVcyhVgZHnCsw4Ksrjv1Veq1+HEqgsylNVfVuLkojI3xlNZuy9cDWgDNZq0CEpyoc9ovqEASUR1RnKAFGZkfTmHEqDORCL8sj7HGIvQ2ljDiUREfmPI9nFsmWzOidH1aviaeRb/JdGRHWGL6u8OpqPKEkSgqpU2vPbIa92fvmwNYeSiIj8RwaHu5IPMaAkojqj2oCyFtehVGYlq277y5DXcqeXDVFkKDnklYjIrygL8rDCK9UmBpREVGdUN+RVp9XIAjuPZiirKXBTddtvM5Rae8uGyO+jJ+eeEhFRzbEgD/kSA0oiqjOUAaJyiCsgDzI9W5THfpXXym2N3XN9xemiPMohr6zySkTkN8xmIRvyqtVI6Jwc7cMeUX3DgJKI6ozqhrwC8iCz1GCG2eyZ4M5gtr8OZeW2fA6lEL4PKpXzPu0V5VEuv8I5lERE/uNEXgkKy67+XG7fMBJhNj5QJfIWBpREVGeoh7zaylDK95V6qNKrsmKqoyGvAGDyUCBbE8q1M+1nKDmHkojIX6nmT3K4K9UyBpREVGeoMpSKuX+AjcI8Hgoo1RlK+0NeK8/3h4DSyaI8nENJROS3lAFlVxbkoVrGgJKI6gxl1VZnMpSeKszjaNmQym15gKk83xecr/LKOZRERP5q97l82fZ1zFBSLWNASUR1hqtzKAHPLR2izDhWm6H0g0qvqiDY3pBXzqEkIvJLQgjsrpKhlCRmKKn2MaAkojqjumVDKvf5KkMp31bOX/QFZ5cNUd7HIg55JSLyC6evlOJKqcG6nZYYqZqmQORtDCiJqM5wKkOpCI5KDJ4JjtTLhtiv8lp5vh9kKBV9CHEyQ+nJ9TuJiMh9yuGu3ZidJB9gQElEdYYzAaW3MpSqojyaOlSUR5mh5JBXIiK/sFtRkOe6pgwoqfYxoCSiOkMZHCrnSwI2qrx6a8hrUAAW5XF6DiUzlERE/kC1ZAgzlOQDDCiJqM5QzqG0tbCz9zKUiiGvGuWQV2WG0vcBZXXzPi3CdFpIVeJhzqEkIvI9ZUEegAV5yDcYUBJRnVE1OAwP1kKjUReZUVV59dA6lOoMpfzaqqI8Rn8Y8irvg72AUpIkWSDODCURke+dzS9FTnGFdbttQgRiwnQ+7BHVVwwoiahOEELIAkpb8ydt7S/2UHCkmkMZgEV5lH2squo8yuIKI4TwfUBMRFSfqYa7cv1J8pGACSiPHDmChQsXIj09HZ07d0ZQUBAkScK8efN83TUi8gMGk4CpyrBTewGlag6lhzKUqiqvmmoylH4WUAZrNZAkBwFllTL0ZgGU+cEcUCKi+kxVkIcBJflIwCxU8+677+KNN97wdTeIyE85swalrf3Kdu5SVUwNqmYOpT+sQ1klKFQO0VVSBuhF5Uabc1SJiKh27DmvDChjfdMRqvcCJkPZqVMnPP744/jss89w6NAhTJ482dddIiI/4sySIYCNOZSeKsqjylBWM+TVD4ryVK3yam/+pEWkKqDkPEoiIl+xXZAn2ke9ofouYDKU9957r2xbowmYWJiIaoGzAaW3qry6XpTH9wGlcsirI1WHvAKey+wSEZHrLhSW4ZK+3LrdKj4cDcKDfdgjqs8YlRFRneDskFevzaFUFuWpNkPp2yGvJrNA1S7YW4PSQhlQFnkoECciItcpC/Jw/iT5UsBkKGvTuXPnZNt6vd5HPSEiZykzjcqhrRa1l6GUB2j+lqFUzfl0ecgrM5RERL6iHO7ajetPkg8xoLShadOmvu4CEbnI53MoFRlHZUbS34ryKAPakGoylMqMLwNKIiLfUVd4jfVNR4jAIa9EVEeoh7zay1B6Zy6gcl1J1ZBXxTIivl42RJ2hdFzlNTLEO5ldIiJyHdegJH/CDKUNZ8+elW3r9Xp06NDBR70hImcoM421PYeyQpFxVA15DVJmKH0bUJYrh+i6WJSniEV5iIh84mJhGS4Ullm3mzcIQ3wEC/KQ7zCgtCElJUW2XVhY6KOeEJGzVENeQ2p3DqU6Q6kY8qrIWPq6KE9162YqcdkQIiL/oB7uyuwk+RaHvBJRneDsHMqQIA2qxnqemkNZXYCmXEbE50V5XMxQcg5l7TEYDPjhhx/wxBNPoEePHoiNjYVOp0OjRo0wevRorF+/3mH7TZs2YeTIkUhISEBYWBjatWuHp556CkVFRQ7bHTt2DOnp6UhJSUFISAhSUlKQnp6OEydOePLtEVEN7TnP4a7kXxhQElGd4GxAKUmSbNir5zKUiqI8ygylsiiP2ddzKBVDdKsd8so5lLXlp59+wtChQ/HKK6/g3Llz6NevH8aOHYvExESsW7cON910E+6//34Ioc5yL1iwAMOGDcP333+Pjh074uabb0ZBQQHmz5+P7t27Iycnx+Y1t23bhi5dumDp0qWIjY3FmDFjEBsbi6VLl+Kaa67BL7/84u23TURO2n02X7bNgjzkawwoiahOcHYdSuWxEoPJ5i/mrlINedVWt2yIfw15ra7Ka6QyQ8k5lF6j0Wgwbtw4/Pzzz8jKysI333yDFStWYN++fVi+fDm0Wi3ef/99fPLJJ7J2GRkZeOyxx6DVarF+/Xr89NNP+OKLL3D8+HEMGTIER44cwfTp01XXKykpwfjx41FSUoJZs2Zh//79WL58Ofbv349Zs2ahuLgY48ePR2lpaW3dAiJygEuGkL9hQElEdYKz61Aqj5nMwiMVV6sryqNcRsTXGcoaF+XhHEqvGTx4MFatWoX+/furjk2YMAHp6ekAgI8//lh27IUXXoAQAnfffTdGjBhh3R8eHo7FixdDo9Fg9erVOHz4sKzdRx99hAsXLiA1NRXz5s2THZs3bx5SU1Nx9uxZ1fWIqPZd1pfjXMHVgjwpMaFoGBXiwx4RBVBAuWfPHvTu3dv6ZZlD8t5778n2Z2Vl+binROQLzg55tXXME/MoXS7K4+t1KFVzPh0vG6K8Z8xQ+k7Xrl0ByCuSV1RUWJ+Ld9xxh6pN8+bN0bdvXwDAmjVrZMcs2xMnToRG8e9Uo9FgwoQJAIAvv/zSQ++AiNylnD/JgjzkDwKmymthYSF+/fVX1f5z587h3Llz1u3y8vLa7BYR+Qln16EE1EuHFFeY0CC8ZtevGqBJEqBVBJSqojy+XoeyxhlKBpS+cvToUQBAcnKydV9mZiZKSkoAAN27d7fZrnv37tiyZQsyMjJk+y3bjtpVPY+I1ExmASEELB8VCgEICJRUmKAvN6KwzAh9eeVXmcGMMJ0WYToNwoO1CNNpEa7TokG4DlEhQZAk+x/w7T6XL9vuxvmT5AcCJqAcNGiQR+Y5EVHdpM5QOppD6fkCM1UzjjqNRvULgTpD6euiPC4GlF5aboVcc/HiRXz00UcAgHHjxln3nzx5EgAQGxuLqKgom22bNm0qOxeoXGc5NzcXANCsWTOH7bKzs1FcXIyIiIgavYeqHwJb+kAUCC4WluGzPedxPLcYF/XluPTn10V9ucd+JoYHa5EcFYJGUSFIjg5Fw8gQBFWZMrExM1t2PjOU5A8CJqAkInJEOWzV3jqUgHp+pSeGvFYN0GwNH1XOqQy4ojycQ+lzRqMRd911FwoKCtC5c2fcf//91mOWoMxRsBcZGQlAvrZy1WDOXltLO0vbmgaUlgCVKJCUVBjR761tOJ5b4uXrmHA8t8Tp6zCgJH8QMHMoiYgccW0OpTw4Ug6XdUfVjKMyG1m5z7+K8igDWleXDeEcyto3ffp0/PDDD4iPj8eqVasQHBzs6y4R1RvfHLzs9WDSVSkxoWgUHerrbhAxQ0lEdYMry4Yo51CWGDw85FWrzlAqlxFRzmGsbaoqr9VkKIO1Gmg1EkzmyvfJOZS16+GHH8bixYvRoEEDbNy4EampqbLjlmGuxcXFdl+jqKgIABAdHa1q56itpZ2yrbuqFhMCKrOkHTp0qPHrEnnTNwcv2T0WHqxFfLgOmj+nOlhmPEiQEKbTICokCFEhQYgOrfwzVKdFmcGEUoMZJQYTSg0mFFeYkFNcgazCMqeHzz47PLX6k4hqAQNKIqoTalLltaZzX4QQMJqvBpS2sn3KgM1g9q8hr9VlKCVJQmSwFgVllYEk51DWnsceewxvvvkmYmNjsWHDBmuV16patGgBAMjPz4der7c5j9ISyFnOBSoDyri4OOTl5eHMmTPo0qWL3XYJCQk1Hu4KACkpKbLtqkNwifyRySzw3eHLsn1f/7UHOiRFISkqRDUloKb0ZUZc1Jchq7AcOcUVuFrq56puTWLRMr6G1eSIPIQBJRHVCVUDHJ1WUmUEq/L0HErlEiC2rq0a8up3RXkcLxsCVM6jrBpQms0CGk317ch9//jHP/Daa68hJiYGGzZssFuJNS0tDeHh4SgpKcGuXbtwww03qM7ZtWsXAKBbt26y/d26dcOmTZuwa9cu3HzzzU63I6ovdp7NR05xhXW7XcNI3NyxkdeuFxUahKjQSLRNjKz+ZCI/wDmURFQnVB3yqgwYlTydoXQmOFMV5fG3gLKaIa+AutKrJ4YKk30zZ87Ev//9b8TExGDjxo3o0aOH3XODg4MxatQoAMCyZctUx0+fPo3t27cDAMaMGSM7Ztlevnw5zIq5vWazGStWrAAAjB071v03QxTA1iuGu45q39BHPSHyTwwoiSjgmc0CpYarvwg7mj8JeH4OpTLb6FyG0sdDXhVzKEOqGfIKABFci7LWPP3003jppZcQGxtbbTBpMXPmTEiShCVLluD777+37i8pKcE999wDk8mEcePGoV27drJ26enpaNy4MTIzMzFnzhzZsTlz5iAzMxMpKSmYMmWKZ94cUYBZf0gRUHZI8lFPiPwTh7wSUcBTBoSO5k9WHvdslVdlcGgr2+d/Gcrq+6zEtShrx9dff41//etfAIA2bdrg7bfftnleQkICXnnlFet2t27d8Oqrr2LGjBkYOXIkBg4ciIYNG2LLli3IyspCWloaFi1apHqd8PBwfPHFFxg+fDjmz5+Pr7/+Gp06dcL+/fuxf/9+REREYOXKlQgLC/POGybyYxcKypBx/uo83+jQIPRrGefDHhH5HwaURBTwVGtQVhNQenoOpTI4VGYjK/cpivL4OENZbpS/5+qK8gA21qLk0iFekZeXZ/37rl27rHMYlZo3by4LKAHg0UcfRefOnfHqq6/it99+Q3FxMZo1a4ZZs2Zh1qxZNov1AEDfvn2xd+9ePP/889i0aRNWr16NxMRETJkyBc888wxat27tuTdIFEC+VWQnh6cmOpyjT1QfMaAkooDnSoVXAIgI8WymzamiPIp5lX6XoXQmoAxWDnllhtIb0tPTkZ6e7nb7oUOHYujQoS63a9OmDZYuXer2dYnqovWH5NVdb+JwVyIVfsRCRAHPlTUoARsZyhrOoXRmCQ7VsiE+DyiVRXmcqfIqv2+cQ0lEdVm50YSNmdnWbUkCRrRjQR4iJQaURBTwVBnKEBervNYw06YuyuP/Q16VRXmcyVAqA3UOeSWiuuyn47my50uPprFoGBXiwx4R+ScGlEQU8Fwd8urpKq/OZSj9bcirosqrM0V5PDxUmIjInymHu45qz+GuRLYwoCSigKcc8lr9OpTerfLqXIbSvwJKzqEkIrpKCMH1J4mcxICSiAKeOkPp4hzKGhflqX4dSo1GgrZK9VdlUZzaVu7GkFfOoSSi+iIzuxjHc0us242iQtC1SYwPe0TkvxhQElHAc7nKq4fXU3S2YmrV5UR8nqFUBpRODHnlHEoiqi/WK5YLGdm+ITQ2loQiIgaURFQHqKu81u4cSmeK8lTuv/oj1+dFedxaNoRzKImoflh/kPMniZzFgJKIAp5yyKqrQ15rnqF0bvhosLbqkFd/m0PpzLIhyjmUzFASUd1TWGbAzydyrds6rYRhqYk+7BGRf2NASUQBz9UhrxqNhNAqQzxrPodSWZTHzpBXWYbSvwLKkCDH9wywNYeSGUoiqns2ZmbDaL76c31Aq3hEhTr+oJKoPmNASUQBz9WAUnlOTTOUyuDQXrav6jxFswBMZt8Ne1UV5QmqPkPJOZREVB+oh7uyuiuRIwwoiSjgqeZQhlT/SXLVeZQVJjOMNcgYKrN9djOUioIOvsxSqorycA4lERHMZqEqyDOqA+dPEjnCgJKIAp57GUp50FmTwjzOrENZuV/+I9eX8yjdWoeScyiJqI7bfa4Al4sqrNttEyKQmhjpwx4R+T8GlEQU8JQBpbLoji2qSq81yLY5X5RHvt+XlV5VVV6dWDZEFVAyQ0lEdYw6O8nhrkTVYUBJRAHP1WVDbJ1Tk+Gbzhfl8aMhr25kKJX3jBlKIqprvjmoCCi5XAhRtRhQElHAUw95rX4OpTI4qsmQV2eX4FAGbT4d8lplDqVWI0HrxILdOq1G9h4YUBJRXZJVWIbd5wqs25EhWgxoFe/DHhEFBgaURBTw3JlD6cm1KJWZRuczlP5R5dWZNSgtqi4dwqI8RFSXfHdIXt11eGqiU9MBiOo7/i8hooCnnP/oVlGemgSUZueK8vhVhtJUNaB0/lFQdR5lmbFm1XGJiPzJN8r5kxzuSuQUBpREFPCUmbIwN4ryKOdhusLZJTiUmUvfFuWpElC68Ak8lw4horqo3GjCxsxs2b6RXH+SyCkMKIko4FUNBsODtdA4MR9QNYfSB0V5fJWhFELI+uxKhlKZ2S2qQSBOROQvtpzIQ1H51edA96YxaBQd6sMeEQUOBpREFPCqZsmcGe4KeHYOpfvLhvgmoFQGwCGuZChDmKEkorpHWd31Jg53JXIaA0oiCmgVRjOMVeYwOrMGJeDpZUOURXlsZ0j9ZcirO0uGWEQqM5Ss9EpEdcB6RUGeUR0YUBI5iwElEQU0d9agBNRzKGuybIiyKI/9DKV/DHktd3LOpy1Vi/IAkA0RIyIKRJnZRTiWU2zdTooKQbcmMT7sEVFgYUBJRAHNnTUobZ3nyaI8zmcofRNQqjKUQc4vG6IM2DmHkogCnXK466j2DZ2ai09ElRhQElFAc2cNSkA9NLZmy4Y4tw6letkQHw15rVGGknMoiahuWX9QMdyV8yeJXMKAkogCmjtrUNo6r0ZFeYzODXlVZi79JkPJOZREVE8Vlhnw84lc67ZOK2FYaqIPe0QUeBhQElFAU8+hdG7Iq2fnUAZaUZ6aVHnlHEoiqjs2HMmWFXYb2CoeUaHOPUeIqBL/xxBRQHN3yKtnq7wGVlGeGg155RxKIqolZrNAUYUR+aUGFJQZUVJhQkSwFjGhOsSG6RAZooUk1WyuI6u7EtUcA0oiCmhuz6FUZihrNOTVuTmU/lKUp1xVlMf5gFKZAeaQVyJyR7nRhL+t3o9vD1+CwSQgSYAEQJIkSABKDSYUlhshHAzk0EhATKgOIUEaGM0CRrOAySxgNJthFpWjL8J1WoTptAgP1iJMp0GwVgOTWcAsALMQOHhJL3vNmxhQErmMASWRA2azQHZxBZKiQnzdFbLD3SGvnqzyqhzyqsxEXt3PojxERAAw57sjWPzbmRq9hlkAV0oNdo+XG80oLHP+Z3tqYgTaJETUqE9E9RHnUBLZkVVYhjYv/A+N5m7AxE92Qzj6mJR8RhnQKDOP9qiqvNZgDqXzGUp/Lcrj/JAxzqEkopo6crkIr2854etuqNzaqZGvu0AUkJihJLLj3z8ex8m8EgDAit8v4IHrm2Ng6wQf94qU/GIOpVn+YYOzRXl8NoeyBkNeOYeSiGrq0bUHZHPPNRKg1UgQAhCoHIoaGqRBTKgOMaFBiAmr/DMiOAjFFUYUlF2dV1lQaoDBLKCVJARppco/NRIkqTJDWWowwezE58HXt2iA2UPaeu9NE9VhDCiJ7PjtzBXZ9vZTVxhQ+iF/nENpvyiPn1R5VfQ3xIUhr5xDSUQ1sf7gJXx3WF4IZ/vf+6FX8wZeuZ4QAhUmM0oNlcFlhdEMrUaCRpKgkQCNJCE4SIPYMJ1Xrk9UHzCgJLJBCIF9F+UT9fecK/BRb8gR9RxK5wJKnVYDnVayBnWezVD695DXcmUA7NKyIZxDSUTuKTea8MjaA7J9U7uneC2YBCqL/IQEaRESpGXQSOQlnENJZMOZK6Wqify7GVD6JWVm0dmiPIB8HmWN1qF0ck6iuiiPnwx5dakojyJDySGvROSk138+iWM5xdbtyBAtXhjV3oc9IiJPYEBJZMMfWYWqfSfzSpBXUuGD3pAj7g55rTz3anBUUmGC2ZmJNjYoAzTnM5Q+GvLq5LqZtkSqhrwyQ0lE1btQUIZ5mzJl+54Zlork6FAf9YiIPIUBJZENtgJKgMNe/VFNAkrlPMoyo3vBkTIwDNIEWIYyyPkqr8p7xjmUROSMmesPyT6AapsQgYf7t/Jhj4jIUxhQEtmwL0tvcz+Hvfofd9ehrDzXM/MBqwZoOq0ESXKuyqu/FOVxJUOp1UgI0109n3Moiag6O07l4ZPd52T7Xr+1o0vzt4nIf/F/MpENzFAGDlWGMsSFDKVyLUo3g6OqgaG94a6Vx+SBpr9kKENc/KWu6jxKzqEkIkfMZoGHvtov2zeyfUOMbJ/kox4RkacxoCRSKDOYkJldbPPY7nP5tdsZqpYyoFQGiY54KkNZtSiPo2yfetkQP6ny6kKGEpDPozSYhCrjSURksWTnWew6e/XDWJ1WwoJbOvqwR0TkaQwoiRQOXSqCyU5xluO5JcgvNdRyj8gRd5cNAWysRelmpVflkFd7/KcoTw0DSkUWmFlKIrIlv9SAWd8eku17pH8rpCZG+qhHROQNDCiJFOwNd7XgsFf/oi7K48ocSvm5yuDUGUIIWWDoSobSZ0NejYoqry4OeVXdN1Z6JSIb/rnhCLKLrlZHbxQVgqeHtfVhj4jIGxhQEinsUwSUjaJCZNsMKP1L1axikEZyKTjyxBxKoyKb7ThD6R9DXmucoVRWemWGkogUDlzUY+HWU7J9L93UHtGhOt90iIi8hgElkYIyQzn5uhTZNudR+peqGUpXhrsC6gI+7syhVAaFOo0rGUp/GfLq/LIhgLwoD8C1KIlITgiBh7/aL5s+0qd5A9zVLcVBKyIKVAwoiRSUS4ZM7dFUts2lQ/yH2SxkWUVXhrsCNjKUbsyhVAaFjjKk6jmU/pGhdL3KKzOURGTfmn0X8cPRHOu2JAFvjukEjZ01eokosDGgJKrisr4cF/Xl1u2WceHokBSJhIhg676jOcUoYGEev1BqUM6fdDFD6YEqr+oMpQtDXu0Uf/K2mlZ5VQbuReUMKImoUqnBhBlfH5Dtu6dnM3RvGuubDhGR17n2cT5RHaecP9k5OQqSJOG6lBj890i2dX/G+QIMapNQ290jBXVBHtcCSlWVV7cCSuczlMqhpb5abkN5XVeL8ijnULq73AoReZYQAvpyIyqMZlSYBCpMZpQbzTCYzNBIEoK0EoI0li8NNBIgSRIkVGYRAcBRDlGjqTxXI0l/flXu00hX9738v2M4faXU2iYmNAj/GtHOm2+biHyMASVRFfsuyoe7XpMcDQCqgHIPA0q/oFqDshYzlOVGE346nouVe7Nk+13JUF4qKkdRuVE1J9Hbar5sCDOURP7mq31ZmPXtYRy+XOTrrsj88y9paKgobkdEdQsDSqIq/rggz1Be09gSUMbK9u8+y3mU/qAma1BWni//EVhdhlIIgVV/ZGF5xnlsyMy2WYzGUbZPOWfzRG4Jer6xBaumdEeHRlEu9LxmVPM+Xa7yqggomaEk8hkhBF783zHM/vawr7ui0iEpEv/Xt4Wvu0FEXsY5lERVKCu8dv7zl/xuKTGy/az06h9qsgYloA7wHK1DeTqvBMPe+wXjP96NL/ddtFvZdECreLuvEROmQ7+WcbJ9hy4VoccbW/Dp7nMu9LxmlENeXS3Ko6yOywwlkW+UG01IX/67XwaTAPDGrZ1UIzOIqO5hhpLoTyazwIEqQ15DgzRokxABAGjeIAxx4TrklVQW48nMKYa+zIioUP4X8qWazqF0ZsirEALv/3Iaj6876HB5jCYxobi7R1PMGtLG4TXXpHfHnZ9lYEPm1SHUJRUmTF6WgS0ncvHGrZ0QqnPtfbiqXDnklXMoiQJOdlE5xizZiW2nrsj2RwRr0SYhAsFaDYK1lWvz6jQaCAgYzZVfpip/ClT+nAMAIQAB2/MoxZ/HzaKyjVn82f7PfWYBmISA2SwQFRqEh/q1xNDURC/fBSLyB/xtmOhPx3KKUVYlc9OxURSC/vxk1VKYZ2NmZRl0IYDfLxSgv4NsVKCyrBum9UF59wqjGb+euYIfjubgyOUiJEeHomOjKHRsFIUOSZHWBbHNZoHzBWXYo1jCpcZFeRRVY89cKcG9X+y1ft+VejaLxU0dknBT+yRc2yQaklT9PUuIDMG39/XC/B+O4tn/HoGoMvr0/V/OYF+WHj880AdhXgoqhRA2qrzWdB1KZiiJatOBi3rctPhXnMorle1vHR+Ob+7piXZJtTeEnoiIASXRn9QVXqNl29elxMoCi93nAjegPHK5CB/tPIvvDl9GXkkFyoxmlBnMKDWYYDQLBGs1+FvfFnjppvZeH650+JIe3x2+jE1Hc/DT8VyH2a6msaEI02lxKq9UVVgGcH3Iq6MM5cq9F3DPir3Q2wiW7u3VDM/dmIbk6FCXrmeh1UiYMywV1zdvgDs+24PLRRXWYztOX8GbW07iycGOM53OMJsF3tl+Cp/sPoeL+nIUlBqgLzdCuVoJ51ASBY7/Hr6M2z/erfrZNLB1PFZP7Y74KstcERHVBgaURH9Szp+8Jln+CW+gz6MsKDVgxe8X8NHOs9hx+orDcytMZiz4+QT+yCrEyinXoUG4539BKakw4sEv92PJzrNOtzmbX+bweGKka/1UzqG0FOXZcy4fkz7dY83WWqTEhOLD8V3wl3YNXbqOPUNSE5ExYyAmfbobP5/Is+5/8X/HMK13sxrd9yslFbhrWQa+PXS52nNdHfKqHOq9/VQeKoxml1+HiFzz7vZT+Pua/aqfTff0bIZ3xnXm/0Ei8gn+5CH6k7LCqzpDqQwoA6PSa2GZAfev3ItGczfg/lV/VBtMVvXD0Rz0fnMrjmZ7tgz9sZxi9Hlzm0vBZHWiQoJwR9cmLrVRZjSLK4wwmsyYtvIP1S9sf+3ZFPufGOSxYNKicUwoNt7fB63jw6378ksNePnH426/5r6sQvR4fYtTwWSr+HA0CNO59PqdG0XJsruZ2cVY8PMJl/tJRM4xmQUeXbsf/7d6n+xnkyQBr9zcAR+Mv4bBJBH5DDOURH+ytwalRcu4yl+8r5RWFuY5fLnIJ2sIusJoMuOW/+zE5uO5Ds8L0kgI02kRqtPAZBbW4kNAZbDQ642tWDW1Owa3rfnam2v2ZSF9+e8oLFMPJdVIlUOLh6Ym4PoWcbhYWIYDl/Q4cFGPAxeLcKGwMkMZFRKE1vHhaBUfjlbxEWgVH47xXRq7PNTL1hzKt7adkn1YEKSRsObuHripQ5Ib79Y5wUEaPH9jO9zx2R7rvje2nMBD/Vu6PKx2ecZ53PPFXptLoITpNIgO1SEmNAgxoTq0jAvHnGFtnZr7WVVESBCeGtpWVlnyuY2ZuKNrEzRtEObSaxGRY0XlRkz6dA++OXhJtj8iWItld3bD6E6NfNQzIqJK/vubsB0rV67E22+/jb1796KiogJt2rTBnXfeiUcffRQ6nWufshNZ6MuMOJFbYt1OigpRLcQsSRK6pcTgh6NXC/PsvVCIvoplIPzJzPWHbAaT4cFa3HZNMtJ7NEW/lnGyeZKlBhPuWbEXn2ect+67UmrAX97/BW+P7YxpfZq71RejyYxZ3x7GK5vVmbdBrePxUP+WGNQ63uEwz4JSA0xCoEGYzuUgyBblHMrzBWV4+jt5+f3HBrb2ajBpMeHaxnjpx2PY+2emvNRgxvMbM/HOuGucam80mfHk+kN47Sd1pvD2Lsn4cHwXa1EjT5gxsBU+2nkWmdnFACqHCz/69QGsmtrdY9cg8hWDyYx1By5h7YGLyC81wGytZCpgNgMCAhpJgkaSoNVI0EiVc6NlFU/NwtrGUj218k/56AcJEiSpsrKqRpKg0eDqa0vAoctF1v9nFo2jQ/HNPT3RVTFyhojIFwIqoHzkkUfwxhtvICgoCIMHD0ZkZCT+97//4cknn8S6deuwYcMGhIXx03Fy3YFL8uxkZzuLzF9XJaAEgF9OX8H1LRp4JLjxtC9+v4BXFcFF96YxeKBPC9zepbHdJU/CdFp8dmdXtE+KxDPfH7HuN5oF7l/1B36/UIAFt3RESJDzVUjPXCnBXcsysKXKPEGLp4a2xT//kuZUVdkYF4dmVickSANJgrXSatXMLFCZlX5meFuPXtMejUbC/JHtMOrD36z7PvjlDGYMbG1dvsaey/pyTPhkt+rDA40EvDiqPR4f1Nrj/0ZDgrR4a0xnDH//F+u+1X9k4b+HL3t8WDDVnvr+oe3ZK6X48Ncz+ODX08gqLPd1d2zq2iQa6+7piSYx/H2HiPxDwASUX331Fd544w1ERkbip59+Qrdu3QAAOTk5GDx4MLZu3Yo5c+bglVde8XFPKRAp509e0zja5nndmsg/DX583UE8tzETreLC0TohAm3iIzD2mkbo2ayB1/rqjAMX9fjrit9l+7qlxODnv/V1ajkKSaqsQtquYSSmfp6BUsPViqrvbj+N3ecKsGpKd6eGNy7bcw7/t3ofChRDXGPDdPjkjq61kv2zR5IkRARr7a4vuei2zgh3sXJsTYxo1xD9W8VZA2+jWeCZ749g2V3d7Lb57cwVjPtoF84VyAsWxYfrsGLydRjixXXghqUl4vYuyVi5N8u67+9r9mPfEwNd+sCB/EN9/dDWaDJjY2Y23ttxGusOXlJVQfYnozsm4bM7u/n1VAsiqn8CZgb3/PnzAQAzZ860BpMAkJCQgHfeeQcA8NZbb6GgIDAKpbjKbBYw2lgmwRaTWaCkwr114YrLjfju0CXM/e8RvPS/Y/j19BWnr+uuy/py7DiVhzNXSqyLKzvLZBbYdTYfL/3vGOZ8dxhr919EYZmh+oYK6gqvtgPK65rGqvYVlhnx+4VCrP4jCy/9eAy93tiKER/8gt/OqIvfmMwC6w9ewpglO9Hknxtx04e/4uNdZ5Ff6nqf7SkoNWDMkp2yJTDiw3X4cmp3l9c2vL1LY/z8t75IjpYP//3tTD66LfgZmzKz7ba9UlKBSZ/sxp2fZaiCyW4pMdjz6ACfBpMWykqvFnd0bYLhabWbaZMkCS+MbC/b93nGefx+3vbPtcW/nkH/t7argsnrUmKw+9EBXg0mLV4b3VE2dPhoTrHNYc3k36p+aPvrr7/iv//9L1avXo2jR4+ic+fO1g9t6wohBDLOFWDG2gNIeX4TRn74G9Ye8N9gUpKAxwe1xpfpPRhMEpHfkYSrv8H7wPnz55GSkgIAOHHiBFq2bKk6p1mzZjh79iyWLVuGSZMmefT6hYWFiImJQUFBAaKjbQca7igzmFBiMMFkFpVfovLPMqMZRy4X4cBFPQ5eKsKBS3ocuqRHudGMNgkR6Jwcjc6NotA5ORrtkyJxSV+OvRcK8UdWIfZeKMSBi3qUGc1oHB2KTo2i0Ck5qvLPRtFoGBlsnaOh/XOOxrmCUmw4ko0NmdnYdvKKan2/mNAgDG6bgKFtE3FDm3hEhQRZ54FY/vVI0tU5H5o//151hJ3lPLMQOJZTjF/P5OO3M/n49cwVnL5ydWHmxMhgXJcSg+4psbguJQbtGkZCp9VAq5Gg/XOuSqnBhM3Hc7HhSDY2Hc1WDVPUaiT0bhaL4WkNMSw1Aa3jrw4XVPbJLCpns9y2dBe2n7oaAO5+tD+6pcSqvmdCCFy/cBt+cbJS6k0dkjB3eCqSokKw+NczWPzbGZtLXwRrNfhLWiLGX9sYQ9omQKeRrPNtLP2OCglCaDUBodksMOajnfj6wNXiDRoJ+P6+3hiW5n5wcaGgDOM/3oVtp+TvWyMBz9/YDvf1boaqAyr3nC/APSv2qgIdAJjepzkW3NKx2vdSW1r96weczCuR7WsQpsPhJ29QzaOtLaMX/4Z1VQpwjGjXEN/e18u6XWYw4ZG1B/DejtOqtuk9muKdcZ1d/vCgJv794zH845tD1u0wnQa/PzYQTaJDYVb8rLAnPFjr1pqn3vr5XN/07NkTO3fuxLx58/DUU0/Jjm3duhX9+/dHSEgILl26hJgYz87bq43vYUmFEWeulOLUlVJknC/AZ3vO44CiEJtSi7gw3N+7OYamJiJII8mec0Dl88Ayt9LyDK/6DFQ+DyVUfmhk+bt1TuWfz6GqzyTLXE2zqHzd5KhQFrwiolrn7M/ngAgov/nmG9x8882Ii4tDbq7tapVjx47FmjVr8MQTT+Dll1+u0fXOnTsn29br9ejQoYNbD7t1By7i413nkF9qQEGZ8c8/DcgvNdpcmJ18TyMBxS+MtBvwXCws+7MSaD6O55Tg1JUSGEyO/xtpJHjkk++QIA1iw3RoEKZDbJgOEcFaWSBXWG7Eb2fyZW3mj2yHWUNqPg/QYDLjiXUH8caWk261T4wMxuLxXXBzR/+qSNjp35tVv1h+OL4L7unVzEc9qlz2o8urP8mCsPZJkdCXGZFfZrA5RFenlfDGrZ0wvU/zWp/TW2E049rXfsKhS+4vL/PNPT0xyo2MNQPKmgvkD223nsjFPzdk2j1eUGbEqSslyC6qcOr1NBIwqn0SHri+OYanNXRqbjcRUV3l7M/ngBg3cfJk5S+wzZrZ/wWvadOmsnNrwvJannAitwSr/siq/kTyG6mJkQ6zZ42iQzFvRDvrtskscC6/FMdyivHRrrNYtue8Knj01DCqcqMZl/TluKR3rljEmM6NMHNwG49cW6fV4PVbO6F38wZ2l6Ww56YOSfhwfBck+Sjj54iy0uuAVnH4a0/P/QxwR+fkaNzZrQk+3X210q6jYC05OgSrpnTH9T6qOBwcpMHbYztj8Ls7fHJ9qpmMjAwAQFxcnM1gEgC6d++Os2fPIiMjo8YBpa0Pbd11uagCm6oUSnNX6/hwTL4uBXf3bIpmDcKrb0BERFYBEVBaHjYREfYrHUZGRgKojKT9SayHqlKGBGkQptM6NdcuNEiDuPBg65p9rtBpJfRtEYehqQnILzViY2a2dRkDb7EMzT2RV4JjOcXVN1Do2CgKw1MT0SgqBD8czcHPJ3JRZnQ/+3uri2t6aTUSmseFo3lcOIakJuKpIW3x3MajWP77eZvD/FJiQnFPr2YYd00ydpy6gi/2XsCPx3I8PncnLTECH0281uPZqoldm6BzcjTGfrRTVcpeKTxYi9dGd8C03rWfNXPWdSkx1qxusFaD9267xi/6+s+/pGHF7xeqzX73bdEAK6d2d3m9Sk+7oU0CJnVtIltuhgJDIH9oWxNx4TpMuLYxJl+Xgt7N/bNaNxFRIAiIgLK2nT17VrZtGfLqjhgbSzNoNRJiQoOsQxYtcwMt8wSDtBKaxoShY6ModGwUhQ5JkWgVHwGNBGQVlmNfViH2Zemx/2IhjuYUo0GYDl0aR+Oa5Gh0aRyNNgkRCNJqUFBqwMFLeuy/WPl18KIeJQaTbM6HWQgEazXo3bwBhqUmYmDreNWE/8v6cvxwNAcbM7Nx6HIRzEJcnQuCq/MSZet0icr5fLaezw3CgtGjaSx6NotFr+axstLn+aUG7DlXgN3n8rH7XAEuF5VXmWMKGM1mCAGkJUZieFoihqYmyNr/Y3AblBlM2HoyDxuOZGP7qTyUGs3WYj+WAE+gcmiT9OccFwmV939Q63jMruHw0HZJUVh2Vzc8NbQtntuQiZV/XICEyizdtN7NcWO7q8OoOidHY1qf5risL8eX+7Kw9sBFXCgot86xwZ/31ywqi//klxqQX2aodj5aswZh+OruHh5dd7Cqjo2isPOR/nj5x+PYcCQbBhvDt7s2icHMIW2QmhjplT54ypxhqcguqsD5gjI8d2Ma2iXZXjKmtrWKj8Cbt3bCg2v2w1Tl04aIYC1iQnVIjAzGhGsb47GBrREc5B/11d677RqEBGmw/VQehLg6t7rq/DF7IkP8Y05tfRTIH9o6Q5KAJtGhaBEXjuYNwtC8QRh6NWuAG9s19Jv/O0REgSwgAsqoqMpf8IqL7WdDiooqh4N5Yg6NZS6JRU0eoP1bxWPbg30RG6ZDTFgQYkN1CA/Wuv1JaOOYUDSOCXVqnbeYMB36tIhDnxY1GwbXMCoEk7o1waRuTWr0Os6IDdNhcNsEDG6b4PZrhOq0GJqaiKG1UOHSkY6NorBiynV4t6QztJLkcA3FhlEhmH59C0y/vkW1r2s2C+jLjbhSakCpQT3sVKuR0CouHEFuFDhxRXSoDvNGtJMN/w1EydGhWDm1u6+7YdP061vgrutSkF1UgZiwIESHBHn9+1oTUaFBWDLxWl93g/ycJz+0HZaaiEP/GGT3eEiQFk1iQhk4EhF5UUAElC1atACgfghVZTlmOddfxEcE+2xeE/mHuPBgj76eRlMZnDoKUKnuiAwJ4jIB5FWB/KFtVGgQ2oX6x6gCIqL6KiA+suvatSsAIDc31+78jV27dgGAbI1KIiIiciyQP7QlIiLfC4iAMiUlBT169AAALFu2THV869atOHv2LEJCQjBy5Mja7h4REVHA4oe2RERUEwERUALA7NmzAQAvvvgi9uzZY92fm5uL//u//wMAPPjggx5fcJmIiKgu44e2RERUEwETUN5666146KGHUFRUhN69e2PEiBG47bbb0KZNG+zbtw99+/bF888/7+tuEhERBRx+aEtERO6ShKhuAQL/8sUXX+Dtt9/G77//DoPBgNatW+Ouu+7Co48+iuBgzxY/sSgsLERMTAwKCgo8UpCAiIg8gz+fPefhhx/Gm2++CZ1OhyFDhiAiIgI//PAD8vPz0bdvX2zcuBFhYWHVv5CL+D0kIvJPzv58DriA0hf4sCMi8k/8+exZ/NCWiIgsnP35zFr0REREBAAYP348xo8f7+tuEBFRAAmYOZRERERERETkXxhQEhERERERkVs45NUJlmmmhYWFPu4JERFVZfm5zHIAgYvPWCIi/+TsM5YBpRP0ej0AoGnTpj7uCRER2aLX67mkRYDiM5aIyL9V94xllVcnmM1mXLhwAVFRUZAkyeX258+fR4cOHQAABw8eRJMmTTzdRaqC97t28X7XLt5vOSEE9Ho9GjduDI2GszgCEZ+xgYX3u3bxftc+3vOrnH3GMkPpBI1Gg5SUFLfbVx3GExUVxbLoXsb7Xbt4v2sX77caM5OBjc/YwML7Xbt4v2sf77mcM89YfpxLREREREREbmFASURERERERG7hHEoiIiIiIiJyCzOURERERERE5BYGlEREREREROQWBpRERERERETkFgaURERERERE5BYGlEREREREROQWBpRERERERETkFgaURERERERE5BYGlEREREREROQWBpRERERERETkFgaURERERERE5BYGlEREREREROQWBpRERERERETkFgaURERERERE5BYGlEREREREROQWBpRERERERETkFgaUXrZy5UoMGjQIDRo0QEREBLp06YKXX34ZBoPB113zmfT0dEiS5PCrrKzMZtvdu3fj9ttvR1JSEkJDQ9GyZUv8/e9/x+XLlx1e89KlS3jwwQfRsmVLhISEICkpCbfffjv27NnjsF1FRQVeeukldOnSBREREWjQoAEGDRqEVatWuf3+veHIkSNYuHAh0tPT0blzZwQFBUGSJMybN6/atps2bcLIkSORkJCAsLAwtGvXDk899RSKiooctjt27BjS09ORkpKCkJAQpKSkID09HSdOnHDYTq/XY/bs2UhLS0NYWBgSEhIwatQo/O9//3PYzmw247333kOvXr0QFRWFqKgo9OrVC++//z6EENW+T09y537PnTu32n/3hw8fttu+Pt9vInv4jFXj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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_2397991/1239110600.py:7: FutureWarning: The behavior of `series[i:j]` with an integer-dtype index is deprecated. In a future version, this will be treated as *label-based* indexing, consistent with e.g. `series[i]` lookups. To retain the old behavior, use `series.iloc[i:j]`. To get the future behavior, use `series.loc[i:j]`.\n", + " axs[i].plot(resources[\"seconds\"][:last_sample], resources[f\"{s}_{k}\"] / 1_000, label=\"Current\")\n" + ] + }, + { + "data": { + "image/png": "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BS4hhBBCCCGEkJSAApcQQgghhBBCSEpAgUsIIYQQQgghJCWgwCWEEEIIIYQQkhJQ4BJCCCGEEEIISQkocAkhhBBCCCGEpAQUuIQQQgghhBBCUgIKXEIIIYQQQgghKQEFLiGEEEIIIYSQlIAClxBCCCGEEEJISkCBSwghhBBCCCEkJaDAJYQQQgghhBCSElDgEkIIIYQQQghJCShwCSGEEEIIIYSkBBS4hBBCCCGEEEJSAgpcQgghhBBCCCEpAQUuIYQQQgghhJCUgAKXEEIIIYQQQkhKQIFLCCGEEEIIISQloMAlhBBCCCGEEJISUOASQgghhBBCCEkJKHAJIYQQQgghhKQEFLiEEEIIIYQQQlICClxCCCGEEEIIISkBBS4hhBBCCCGEkJSAApcQQgghhBBCSEpAgUsIIYQQQgghJCWgwCWEEEIIIYQQkhJQ4BJCCCGEEEIISQkocAkhhBBCCCGEpAQUuEnO2rVr8dhjj2HKlCkYPnw43G43HA4H7r33XtNf68svv8R9992HCRMmoG/fvnA4HHA4HFi0aFHY5y1btgwPPfQQJk6ciAMPPBBOpxMOhwMvvfSS6ddICCGEEEIISV/c8b4AEhtPPfUUZsyYYctrXX/99VixYoXh591999343//+Z8EVEUIIIYQQQsg+6OAmOQcddBD+/Oc/4+WXX8bq1atx8cUXW/ZaJ510EqZPn463334b5eXl2H///XU978gjj8Ttt9+OefPmYePGjTjuuOMsu0ZCCCGEEEJI+kIHN8m54oorVLedTuv2LP71r39F9bxp06aZfCWEEEIIIYQQIkMHN03xeDx49tlncfzxx6Nz587IyspCv3798Mc//hFlZWXxvjxCCCGEEEIIMQwFbhpSX1+Pk046CX/4wx/www8/4OCDD8ZZZ52FrKwsPP300xg5ciSWL18e78skhBBCCCGEEENQ4KYhV199Nb744guceeaZ2LhxI7744gvMnTsXa9aswSOPPIKqqipceOGF8Hq98b5UQgghhBBCCNENBW6asXr1arz66qvYb7/98Morr6Bbt26qx2+88UacfvrpWL9+Pd5///04XSUhhBBCCCGEGIcCN8147733oCgKTjvtNBQUFGgec/zxxwMAvv76axuvjBBCCCGEEEJigynKacamTZsAAM899xyee+65sMdWVFTYcUmEEEIIIYQQYgoU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2hUJCQnOeAlEROQGGGPldWaMpdaECS6RmwoPD7f4uFqttvuc6upq2ePGlSErKirsurtr7x1gewUFBeGtt97CPffcg6NHj+KRRx4BAHTs2BHp6emYMWMGxo4da7HOlZWVuHz5skN1Np4fGxvrrJdARERugDFWXmfGWGpNOBaAiOym1+sBAA899BCEEA3+++c//+n0OowZMwanTp3C3//+d0ybNg0xMTG4evUq3n33Xdxxxx0YN26cbBELY51vv/12u+q8Z88ep9eZiIioIYyxRM7BBJeI7GYcVuXsYVGO8vf3x3333YeNGzfi9OnT+OWXX/D4448DqN2/75VXXjGd25Q6G4dbnT592gm1JiIiso4xlsg5mOASkd2GDBkCAPj6669RUlLi4trUSUpKwl/+8hfceeedACC7Q2ys87Fjx3Dy5EmHrjt48GBT2dzcXOdUloiIyALGWCLnYIJLRHbLzMyEn58fysrKsHjxYpvnlpeXo6qqyqnP39D1vL29AdTOBTIaOXIkYmNjIYTAggULFHvw1VddXW1aCMNYNiYmBkIIPP744zbLEhERNQVjLGMsOQcTXCKyW3BwMJ5//nkAtZvcT5s2TbbNQXV1NQ4dOoSlS5ciISEBV65ccerzr1ixAnfeeSfeeecdXLp0yfR4aWkpVq9ejS1btgCAbFN4jUaDdevWQaVSYdu2bbj99tvx7bffmgKpwWDATz/9hBUrVqBLly74/vvvTWU9PDywcuVKAMBHH32E8ePHy46XlZVh06ZNFrdGiIuLgyRJyMrKcl4DEBGR22KMZYwl5+AqykTkkIcffhjl5eVYuHAh3n33Xbz77rvw9vaGt7c3iouLTQtOAIAkSU59boPBgO3bt2P79u0AAJ1OB41Gg6KiItM5EyZMwIMPPigrN3bsWLz11lu4//77sXPnTuzcuRNarRa+vr4oKSmRrWRpXueJEydi7dq1mDt3rum5ja/32rVrEEIgICDAqa+TiIjaJ8ZYxlhqOvbgEpHDnnjiCfz000947LHH0L17d6jVapSUlKBDhw4YPnw4nnrqKRw5cgSRkZFOfd5Zs2bhlVdeQWZmJrp16waNRoOysjKEhoZizJgxeOedd7B161bZNg1G06ZNQ05ODhYtWoQ+ffpAq9WiqKgIfn5+GDRoEB5//HFkZ2cjNTVVUXb27Nn44Ycf8NBDDyExMRFCCNTU1KBr16747W9/i82bNzv1dRIRUfvFGMsYS00jCSGEqytBRLRnzx6MGDECANCePpaysrLw+uuvY+bMmc2y5QMRERFjLGNse8IeXCIiIiIiInILTHCJqNWRJAmSJKFPnz6urkqzWLlypek1vv76666uDhERtSOMseTuuMgUEbUKnp6epg3jjUJCQlxUm+al0+kUr5WLaBARUXNhjGWMbU84B5eIiIiIiIjcAocoExERERERkVtggktERERERERugQkuERERERERuQUmuEREREREROQWmOASERERERGRW2CCS0RERERERG6BCS4RERERERG5BSa4RERERERE5BaY4BIREREREZFb+H9L3epsU9yT0AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# monitoring CPU and RAM usage of the single Pods\n", + "resources = number_services.dropna()\n", + "for s in [\"cache\", \"manager\"]:\n", + " fig, axs = plt.subplots(1, 2, figsize=(9.6, 4.8))\n", + " plt.suptitle(s)\n", + " for i, k in enumerate([\"cpu\", \"ram\"]):\n", + " axs[i].plot(resources[\"seconds\"][:last_sample], resources[f\"{s}_{k}\"] / 1_000, label=\"Current\")\n", + " axs[i].set_xlabel(\"Time [sec.]\")\n", + " axs[i].set_ylabel(k.capitalize())\n", + " plt.tight_layout()\n", + " plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"resources_{s}.pdf\"))\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting data from Prometheus" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# define period\n", + "yesterday = datetime.date.today() - datetime.timedelta(days=1)\n", + "duration = '[' + str(yesterday.day) + 'd]'" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "results values: {'status': 'success', 'data': {'resultType': 'matrix', 'result': [{'metric': {'__name__': 'optical_security_active_services', 'instance': '10.1.19.194:9192', 'job': 'opticalattackmanagerservice'}, 'values': [[1675004940, '720'], [1675005008, '720'], [1675005076, '720'], [1675005144, '720'], [1675005212, '1440'], [1675005280, '1440'], [1675005348, '1440'], [1675005416, '1440'], [1675005484, '1440'], [1675005552, '1440'], [1675005620, '1440'], [1675005688, '1440'], [1675005756, '1440'], [1675005824, '1440'], [1675005892, '1440'], [1675005960, '1440'], [1675006028, '1440'], [1675006096, '1440'], [1675006164, '1440'], [1675006232, '1440'], [1675006300, '1440'], [1675006368, '1440'], [1675006436, '1440'], [1675006504, '1440'], [1675006572, '1440'], [1675006640, '1440'], [1675006708, '0'], [1675006776, '0'], [1675006844, '0'], [1675006912, '0'], [1675006980, '0'], [1675007048, '0'], [1675007116, '0'], [1675007252, '120'], [1675007320, '480']]}, {'metric': {'__name__': 'optical_security_active_services', 'instance': '10.1.19.220:9192', 'job': 'opticalattackmanagerservice'}, 'values': [[1675007456, '1921'], [1675007524, '1921'], [1675007592, '1921'], [1675007660, '1921'], [1675007728, '1921']]}, {'metric': {'__name__': 'optical_security_active_services', 'instance': '10.1.19.228:9192', 'job': 'opticalattackmanagerservice'}, 'values': [[1675007796, '0'], [1675007864, '0'], [1675007932, '0'], [1675008000, '0'], [1675008068, '0'], [1675008136, '0'], [1675008204, '0'], [1675008272, '0']]}, {'metric': {'__name__': 'optical_security_active_services', 'instance': '10.1.19.250:9192', 'job': 'opticalattackmanagerservice'}, 'values': [[1675008136, '0'], [1675008204, '0'], [1675008272, '0'], [1675008340, '0'], [1675008408, '0'], [1675008476, '0'], [1675008544, '0'], [1675008612, '0'], [1675008680, '0'], [1675008748, '10'], [1675008816, '10'], [1675008884, '10'], [1675008952, '10'], [1675009020, '60'], [1675009088, '60'], [1675009156, '60'], [1675009224, '60'], [1675009292, '60'], [1675009360, '120'], [1675009428, '120'], [1675009496, '120'], [1675009564, '120'], [1675009632, '120'], [1675009700, '120'], [1675009768, '120'], [1675009836, '120'], [1675009904, '120'], [1675009972, '120'], [1675010040, '120'], [1675010108, '120'], [1675010176, '120'], [1675010244, '120'], [1675010312, '120'], [1675010380, '120'], [1675010448, '120'], [1675010516, '120'], [1675010584, '120'], [1675010652, '120'], [1675010720, '120'], [1675010788, '120'], [1675010856, '0'], [1675010924, '0'], [1675010992, '0'], [1675011060, '0'], [1675011128, '0'], [1675011196, '0'], [1675011264, '0'], [1675011332, '0'], [1675011400, '120'], [1675011468, '120'], [1675011536, '120'], [1675011604, '120'], [1675011672, '120'], [1675011740, '240'], [1675011808, '240'], [1675011876, '240'], [1675011944, '240'], [1675012012, '240'], [1675012080, '240'], [1675012148, '240'], [1675012216, '240'], [1675012284, '240'], [1675012352, '240'], [1675012420, '240'], [1675012488, '240'], [1675012556, '240'], [1675012624, '240'], [1675012692, '240'], [1675012760, '240'], [1675012828, '240'], [1675012896, '240'], [1675012964, '240'], [1675013032, '240'], [1675013100, '240'], [1675013168, '240'], [1675013236, '0'], [1675013304, '0'], [1675013372, '0'], [1675013440, '0'], [1675013508, '0'], [1675013576, '0'], [1675013644, '0'], [1675013712, '0'], [1675013780, '0'], [1675013848, '240'], [1675013916, '240'], [1675013984, '240'], [1675014052, '240'], [1675014120, '480'], [1675014188, '480'], [1675014256, '480'], [1675014324, '480'], [1675014392, '480'], [1675014460, '480'], [1675014528, '480'], [1675014596, '480'], [1675014664, '480'], [1675014732, '480'], [1675014800, '480'], [1675014868, '480'], [1675014936, '480'], [1675015004, '480'], [1675015072, '480'], [1675015140, '480'], [1675015208, '480'], [1675015276, '480'], [1675015344, '480'], [1675015412, '480'], [1675015480, '480'], [1675015548, '480'], [1675015616, '0'], [1675015684, '0'], [1675015752, '0'], [1675015820, '0'], [1675015888, '0'], [1675015956, '0'], [1675016024, '0'], [1675016092, '0'], [1675016160, '0'], [1675016228, '480'], [1675016296, '480'], [1675016364, '480'], [1675016432, '480'], [1675016500, '960'], [1675016568, '960'], [1675016636, '960'], [1675016704, '960'], [1675016772, '960'], [1675016840, '960'], [1675016908, '960'], [1675016976, '960'], [1675017044, '960'], [1675017112, '960'], [1675017180, '960'], [1675017248, '960'], [1675017316, '960'], [1675017384, '960'], [1675017452, '960'], [1675017520, '960'], [1675017588, '960'], [1675017656, '960'], [1675017724, '960'], [1675017792, '960'], [1675017860, '960'], [1675017928, '960'], [1675017996, '960'], [1675018064, '0'], [1675018132, '0'], [1675018200, '0'], [1675018268, '0'], [1675018336, '0'], [1675018404, '0'], [1675018472, '0'], [1675018540, '0'], [1675018608, '720'], [1675018676, '720'], [1675018744, '720'], [1675018812, '720'], [1675018880, '720'], [1675018948, '1440'], [1675019016, '1440'], [1675019084, '1440'], [1675019152, '1440'], [1675019220, '1440'], [1675019288, '1440'], [1675019356, '1440'], [1675019424, '1440'], [1675019492, '1440'], [1675019560, '1440'], [1675019628, '1440'], [1675019696, '1440'], [1675019764, '1440'], [1675019832, '1440'], [1675019900, '1440'], [1675019968, '1440'], [1675020036, '1440'], [1675020104, '1440'], [1675020172, '1440'], [1675020240, '1440'], [1675020308, '1440'], [1675020376, '1440'], [1675020444, '0'], [1675020512, '0'], [1675020580, '0'], [1675020648, '0'], [1675020716, '0'], [1675020784, '0'], [1675020852, '0'], [1675020920, '0'], [1675020988, '0'], [1675021056, '960'], [1675021124, '960'], [1675021192, '960'], [1675021260, '960'], [1675021328, '1920'], [1675021396, '1920'], [1675021464, '1920'], [1675021532, '1920'], [1675021600, '1920'], [1675021668, '1920'], [1675021736, '1920'], [1675021804, '1920'], [1675021872, '1920'], [1675021940, '1920'], [1675022008, '1920'], [1675022076, '1920'], [1675022144, '1920'], [1675022212, '1920'], [1675022280, '1920'], [1675022348, '1920'], [1675022416, '1920'], [1675022484, '1920'], [1675022552, '1920'], [1675022620, '1920'], [1675022688, '1920'], [1675022756, '1920'], [1675022824, '0'], [1675022892, '0'], [1675022960, '0'], [1675023028, '0'], [1675023096, '0'], [1675023164, '0'], [1675023232, '0'], [1675023300, '0']]}]}}\n", + "1675008136.0 0.0\n", + "1675008204.0 0.0\n", + "1675008272.0 0.0\n", + "1675008340.0 0.0\n", + "1675008408.0 0.0\n", + "1675008476.0 0.0\n", + "1675008544.0 0.0\n", + "1675008612.0 0.0\n", + "1675008680.0 0.0\n", + "1675008748.0 10.0\n", + "1675008816.0 10.0\n", + "1675008884.0 10.0\n", + "1675008952.0 10.0\n", + "1675009020.0 60.0\n", + "1675009088.0 60.0\n", + "1675009156.0 60.0\n", + "1675009224.0 60.0\n", + "1675009292.0 60.0\n", + "1675009360.0 120.0\n", + "1675009428.0 120.0\n", + "1675009496.0 120.0\n", + "1675009564.0 120.0\n", + "1675009632.0 120.0\n", + "1675009700.0 120.0\n", + "1675009768.0 120.0\n", + "1675009836.0 120.0\n", + "1675009904.0 120.0\n", + "1675009972.0 120.0\n", + "1675010040.0 120.0\n", + "1675010108.0 120.0\n", + "1675010176.0 120.0\n", + "1675010244.0 120.0\n", + "1675010312.0 120.0\n", + "1675010380.0 120.0\n", + "1675010448.0 120.0\n", + "1675010516.0 120.0\n", + "1675010584.0 120.0\n", + "1675010652.0 120.0\n", + "1675010720.0 120.0\n", + "1675010788.0 120.0\n", + "1675010856.0 0.0\n", + "1675010924.0 0.0\n", + "1675010992.0 0.0\n", + "1675011060.0 0.0\n", + "1675011128.0 0.0\n", + "1675011196.0 0.0\n", + "1675011264.0 0.0\n", + "1675011332.0 0.0\n", + "1675011400.0 120.0\n", + "1675011468.0 120.0\n", + "1675011536.0 120.0\n", + "1675011604.0 120.0\n", + "1675011672.0 120.0\n", + "1675011740.0 240.0\n", + "1675011808.0 240.0\n", + "1675011876.0 240.0\n", + "1675011944.0 240.0\n", + "1675012012.0 240.0\n", + "1675012080.0 240.0\n", + "1675012148.0 240.0\n", + "1675012216.0 240.0\n", + "1675012284.0 240.0\n", + "1675012352.0 240.0\n", + "1675012420.0 240.0\n", + "1675012488.0 240.0\n", + "1675012556.0 240.0\n", + "1675012624.0 240.0\n", + "1675012692.0 240.0\n", + "1675012760.0 240.0\n", + "1675012828.0 240.0\n", + "1675012896.0 240.0\n", + "1675012964.0 240.0\n", + "1675013032.0 240.0\n", + "1675013100.0 240.0\n", + "1675013168.0 240.0\n", + "1675013236.0 0.0\n", + "1675013304.0 0.0\n", + "1675013372.0 0.0\n", + "1675013440.0 0.0\n", + "1675013508.0 0.0\n", + "1675013576.0 0.0\n", + "1675013644.0 0.0\n", + "1675013712.0 0.0\n", + "1675013780.0 0.0\n", + "1675013848.0 240.0\n", + "1675013916.0 240.0\n", + "1675013984.0 240.0\n", + "1675014052.0 240.0\n", + "1675014120.0 480.0\n", + "1675014188.0 480.0\n", + "1675014256.0 480.0\n", + "1675014324.0 480.0\n", + "1675014392.0 480.0\n", + "1675014460.0 480.0\n", + "1675014528.0 480.0\n", + "1675014596.0 480.0\n", + "1675014664.0 480.0\n", + "1675014732.0 480.0\n", + "1675014800.0 480.0\n", + "1675014868.0 480.0\n", + "1675014936.0 480.0\n", + "1675015004.0 480.0\n", + "1675015072.0 480.0\n", + "1675015140.0 480.0\n", + "1675015208.0 480.0\n", + "1675015276.0 480.0\n", + "1675015344.0 480.0\n", + "1675015412.0 480.0\n", + "1675015480.0 480.0\n", + "1675015548.0 480.0\n", + "1675015616.0 0.0\n", + "1675015684.0 0.0\n", + "1675015752.0 0.0\n", + "1675015820.0 0.0\n", + "1675015888.0 0.0\n", + "1675015956.0 0.0\n", + "1675016024.0 0.0\n", + "1675016092.0 0.0\n", + "1675016160.0 0.0\n", + "1675016228.0 480.0\n", + "1675016296.0 480.0\n", + "1675016364.0 480.0\n", + "1675016432.0 480.0\n", + "1675016500.0 960.0\n", + "1675016568.0 960.0\n", + "1675016636.0 960.0\n", + "1675016704.0 960.0\n", + "1675016772.0 960.0\n", + "1675016840.0 960.0\n", + "1675016908.0 960.0\n", + "1675016976.0 960.0\n", + "1675017044.0 960.0\n", + "1675017112.0 960.0\n", + "1675017180.0 960.0\n", + "1675017248.0 960.0\n", + "1675017316.0 960.0\n", + "1675017384.0 960.0\n", + "1675017452.0 960.0\n", + "1675017520.0 960.0\n", + "1675017588.0 960.0\n", + "1675017656.0 960.0\n", + "1675017724.0 960.0\n", + "1675017792.0 960.0\n", + "1675017860.0 960.0\n", + "1675017928.0 960.0\n", + "1675017996.0 960.0\n", + "1675018064.0 0.0\n", + "1675018132.0 0.0\n", + "1675018200.0 0.0\n", + "1675018268.0 0.0\n", + "1675018336.0 0.0\n", + "1675018404.0 0.0\n", + "1675018472.0 0.0\n", + "1675018540.0 0.0\n", + "1675018608.0 720.0\n", + "1675018676.0 720.0\n", + "1675018744.0 720.0\n", + "1675018812.0 720.0\n", + "1675018880.0 720.0\n", + "1675018948.0 1440.0\n", + "1675019016.0 1440.0\n", + "1675019084.0 1440.0\n", + "1675019152.0 1440.0\n", + "1675019220.0 1440.0\n", + "1675019288.0 1440.0\n", + "1675019356.0 1440.0\n", + "1675019424.0 1440.0\n", + "1675019492.0 1440.0\n", + "1675019560.0 1440.0\n", + "1675019628.0 1440.0\n", + "1675019696.0 1440.0\n", + "1675019764.0 1440.0\n", + "1675019832.0 1440.0\n", + "1675019900.0 1440.0\n", + "1675019968.0 1440.0\n", + "1675020036.0 1440.0\n", + "1675020104.0 1440.0\n", + "1675020172.0 1440.0\n", + "1675020240.0 1440.0\n", + "1675020308.0 1440.0\n", + "1675020376.0 1440.0\n", + "1675020444.0 0.0\n", + "1675020512.0 0.0\n", + "1675020580.0 0.0\n", + "1675020648.0 0.0\n", + "1675020716.0 0.0\n", + "1675020784.0 0.0\n", + "1675020852.0 0.0\n", + "1675020920.0 0.0\n", + "1675020988.0 0.0\n", + "1675021056.0 960.0\n", + "1675021124.0 960.0\n", + "1675021192.0 960.0\n", + "1675021260.0 960.0\n", + "1675021328.0 1920.0\n", + "1675021396.0 1920.0\n", + "1675021464.0 1920.0\n", + "1675021532.0 1920.0\n", + "1675021600.0 1920.0\n", + "1675021668.0 1920.0\n", + "1675021736.0 1920.0\n", + "1675021804.0 1920.0\n", + "1675021872.0 1920.0\n", + "1675021940.0 1920.0\n", + "1675022008.0 1920.0\n", + "1675022076.0 1920.0\n", + "1675022144.0 1920.0\n", + "1675022212.0 1920.0\n", + "1675022280.0 1920.0\n", + "1675022348.0 1920.0\n", + "1675022416.0 1920.0\n", + "1675022484.0 1920.0\n", + "1675022552.0 1920.0\n", + "1675022620.0 1920.0\n", + "1675022688.0 1920.0\n", + "1675022756.0 1920.0\n", + "1675022824.0 0.0\n", + "1675022892.0 0.0\n", + "1675022960.0 0.0\n", + "1675023028.0 0.0\n", + "1675023096.0 0.0\n", + "1675023164.0 0.0\n", + "1675023232.0 0.0\n", + "1675023300.0 0.0\n", + "1675023736.0 0.0\n", + "1675023804.0 0.0\n", + "1675023872.0 0.0\n", + "1675023940.0 0.0\n", + "1675024008.0 1921.0\n", + "1675024076.0 1921.0\n", + "1675024144.0 1921.0\n", + "1675024212.0 1921.0\n", + "1675024280.0 1921.0\n", + "1675024348.0 1921.0\n", + "1675024416.0 1921.0\n", + "1675024484.0 1921.0\n", + "1675024552.0 1921.0\n", + "1675024620.0 1921.0\n", + "1675024688.0 1921.0\n", + "1675024756.0 1921.0\n", + "1675024824.0 1921.0\n", + "1675024892.0 1921.0\n", + "1675024960.0 1921.0\n", + "1675025028.0 1921.0\n", + "1675025096.0 1921.0\n", + "1675025164.0 1921.0\n", + "1675025232.0 0.0\n", + "1675025300.0 0.0\n", + "1675025368.0 0.0\n", + "1675025436.0 0.0\n", + "1675025504.0 0.0\n", + "1675025572.0 0.0\n", + "1675025640.0 0.0\n", + "1675025708.0 0.0\n", + "1675025776.0 0.0\n", + "1675025844.0 0.0\n", + "1675025912.0 0.0\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABF4AAAMyCAYAAABU1QVQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3gUZdcG8Ht2N70HQgoh9A4iXXqvKlVAQCFY4BUbr10Uu7z2TywgKoqCSBUUsdCUJiBdIiAdQidAet3d+f6IWbIzCcludufZzdy/6+K6mN2ZnbOZLTNnz3MeSZZlGURERERERERE5HIG0QEQEREREREREVVWTLwQEREREREREbkJEy9ERERERERERG7CxAsRERERERERkZsw8UJERERERERE5CZMvBARERERERERuQkTL0REREREREREbmISHQC5ltVqxblz5xASEgJJkkSHQ0RERERERFQpybKMjIwMxMXFwWAova6FiZdK5ty5c6hRo4boMIiIiIiIiIh0ITk5GfHx8aXez8RLJRMSEgKg8MCHhoYKjoaIiIiIiIiockpPT0eNGjVs1+GlYeKlkikaXhQaGsrECxEREREREZGbldXmg811iYiIiIiIiIjchIkXIiIiIiIiIiI3YeKFiIiIiIiIiMhNmHghIiIiIiIiInITJl6IiIiIiIiIiNyEiRciIiIiIiIiIjdh4oWIiIiIiIiIyE2YeCEiIiIiIiIichOT6ABIPFmWkZGRgfT0dNGhkJcKDQ1FSEgIJEkSHQoREREREZFHYeJF52RZxoULF+Dv74+4uDgYDCyCIsdYrVakpaXh4sWLiImJER0OERERERGRR+FVts5lZWXBZDIhIiKCSRdyisFgQEREBIxGI7KyskSHQ0RERERE5FF4pa1zWVlZCAsLEx0GVQJhYWHIzMwUHQYREREREZFHYeJF5woKCuDr6ys6DKoEfH19UVBQIDoMIiIiIiIij8LECxERERERERGRmzDxQkRERERERETkJky8EBERERERERG5CRMvRERERERERERuwsQLEREREREREZGbMPFCVE7z5s2DJElo3Lix6FDsfPPNNxg3bhxatGiBatWqwcfHB2FhYWjXrh3+97//lTnF85IlS9C9e3dEREQgKCgILVq0wFtvvcUZioiIiIiIiFyAiReictq1axcAoFWrVoIjsTdr1izM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jezsbIwbN84VD0tERERERJWQMl/hLdUP6ooX9ngpL0+qeJmweRFyLWYAwPMteusm8VI9KAzVg8JEh6FLFf6keO+99xATE4MOHTpg1KhRmDBhgt39qampaN68ORo1aoQLFy5UdHdEREREROTlJCgvwr0j88KKF+eph5eJO+bF98wp5EkLFUq83HvvvXjyySdx5coV+Pr6QirhRRseHo727dvjyJEjWLx4cUV2R0RERETkUocuZuDTrafw+bZT+GL7aew+kyo6JF1QTgbkHWmXkqaTZsVLeSlzVCJzbcWTPky7kBacHmq0YsUKfPnllwgNDcWnn36K4cOHIz4+HpcuXVKtO3bsWHzxxRdYu3YtHnnkkQoFTERERETkKltOXsOkpX/Zll/o0wCt4sPFBaQT6mEn3pF66VInEvHh/iiwyDBbZfiyuW65KX+kF3nMjw1/FlZYIctAmK+/sDhIP5xOvHz66aeQJAlvvPEGRo4cecN127VrB0mSsH//fmd3R0RERETkcsqLP44c0YZqdhVriat5nJnDbxIdgteKDPBBVLDvv41d1YkYLdUIDhe2b9InpxMvO3fuBADcfffdZa4bFBSE0NBQXLx40dndERERERG5nCrxwsyLJlSzGnnNYCNy1pr/dBAdgu6tPP03hv/2NWRZhhUy/hr8OJpGxIgOSxecTrykpaUhNDQUQUFBroyHiIiIiEgzyplVmHfRhrfOakTkzWQABVZLsWW+8bTidDeoyMhIpKenIzc3t8x1z58/j7S0NERHRzu7OyIiIiIil7NalUONmHnRgif1+yDSC1WlGd92mnG64qVNmzb46aefsH79egwcOPCG63766acAgE6dOjm7OyIiIiIil1NXvDDxogVPmuGG9EWWZfyTdhmSBBggoap/ECL8AkWHpYkGoVF48eY+//bZkVAtIFh0SLrhdOIlMTERq1atwtSpU9GxY0eEh4eXuN6yZcswffp0SJKEe++919ndERERERG5HJvriuGtsxqlZObBZDTAZJBgMkjw9zGKDokcZJataLz8LdvyW21uxZPNewiMSDsNwqLwUst+osPQJacTL8OHD8ett96KVatWoW3btpgwYQLy8vIAAIsXL8bp06fx448/YtOmTZBlGWPGjEGPHvp4QRMRERGRd1Be7rPiRRvKP7O39Hip8epa5JoLp2CKDPTBlVf7C46IHCWrkq18z5P7OZ14AYBFixZhwoQJWLJkCaZNm2a7ffTo0QCuv6hHjRqFOXPmVGRXREREREQux4oXMd65vQle6NMABkmCQQISIgJEh1QuBcUyRCa+WBwyZv5ubDt1DTJkWGVgw+SOqBWp/RAf5XteUk1uTuR6FUq8BAYGYtGiRZg8eTLmzJmDrVu34vz587BYLIiOjkbHjh1xzz33oHfv3q6Kl4iIiIjIZaxW+2X++q2NhAjv66khyzIsdokXp+cp0aVz6bk4cTXbtlxgsd5gbffxMRjxXc/xkGXACituiogTEgfpS4USL0W6deuGbt26ueKhiIiIiIg0o654YeKFSmZWjIfyMfK14ghVQ2UxYcBoMGBozeaC9k565ZLECxERERGRN+JQIyovZeKFQ40coxzSo5zKndxvd8oZPLRtOWQAVtmKOZ1HollErOiwdKFCiZf09HQYDAYEB994GqrMzExYrVaEhoZWZHdERERERC6lmk6aF9NUCuXQGB8jhxo5wlMqXvQsvSAXWy+fsi1nFOQJjEZfnP60WLZsGSIiIjBp0qQy17377rsRERGB77//3tndVUhycjIeeugh1K1bF35+fqhatSr69euHVatW3XA7q9WKr776Cr1790ZUVBT8/PwQGxuLnj17YubMmaVut2vXLowYMQLR0dHw9/dH7dq18fDDD+PSpUuufmpEREREVEHFRxcx7UKlYcVLxXjrTFaVieSl07hXBk5XvCxatAgAcO+995a57sSJE/H9999j4cKFGDx4sLO7dMqOHTvQv39/XL16FbGxsRgwYACuXLmC3377DatXr8YLL7yAl19+WbVdWloaBg0ahI0bNyI0NBQdO3ZEeHg4zp49iz179iA9PR2TJ09Wbbd06VKMHj0aZrMZbdu2Re3atbFz50589NFHWLJkCTZv3ox69epp8dSJiIiIqAxTe9fH1N71IcsyeA2inbl/JmPziauwyjKssozHu9dF81jPro43W9jjpSKU/ZOU0zqT+1XxC8St8Y1hkCRIkBDh5x2ziVUGTide9u7dC6PRiE6dOpW5bs+ePWE0GrFnzx5nd+eU3NxcDB8+HFevXsWoUaPw5ZdfIiCg8MW1Y8cODBgwAK+88go6d+6MPn362LaTZRlDhgzBxo0bMWnSJLzzzjt2w6ny8/Px119/qfZ37tw5jB8/HmazGbNnz8bE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4uPjceTIEcTFxTX5z7eCx6uh0tO4FM/oMEetN80Kt/eEnU8inKqpYCc1L7qu15mSWptIl6PW7QNVHi/c3rpfK1Euh6n6Psnh9mqmWhxGqoJagyQNfb0cU9frhsQ42b28Lg5VQaTL/CbvZK8DBWBAPohUur3+YtphDhVhtQRf63NfqEtd7yFIjobcp2PquE7LqjwN6o/jVBVE1HKvIDGqPRqqazQzqOv9+cneq9WF93QSob7rb74Sm1Bubi4AXxZKXY5979hjydexJKaJgyC1veGm0KIoSp1vvBoi3OkA/yY3Dy6H2uh6O031eiGxmvpeztdB81KfBfEfuS9QcGmK65OL7OYlzFl7QNWI79UoFPAvVRPq1asXAODgwYN1Fs/Nz88HAOTlmbtuEBEREREREVFoYeClCWVlZaFv374AgNmzZ5u+v2zZMhQUFCA8PBxjxowRPT0iIiIiIiIiEoyBlyZ21113AQAeffRRrF692v/1gwcPYtq0aQCAG264AfHx8bU+n4iIiIiIiIhCB4vrWuBYAV2Xy4URI0YgOjoaixcvRlFREQYNGoQvvvgCkZHWtFFrjsV1iYiIiIiIiJqb+q6/GXixyH//+18899xzWLt2LdxuN9q2bYuLL74Yt956K8LCwiwbl4EXIiIiIiIiIusx8GJTDLwQERERERERWa++62/WeCEiIiIiIiIisggDL0REREREREREFmHghYiIiIiIiIjIIgy8EBERERERERFZhIEXIiIiIiIiIiKLMPBCRERERERERGQRBl6IiIiIiIiIiCzCwAsRERERERERkUUYeCEiIiIiIiIisggDL0REREREREREFmHghYiIiIiIiIjIIgy8EBERERERERFZhIEXIiIiIiIiIiKLMPBCRERERERERGQRBl6IiIiIiIiIiCzCwAsRERERERERkUUYeCEiIiIiIiIisggDL0REREREREREFmHghYiIiIiIiIjIIgy8EBERERERERFZxCl7AtS0dF0HABQXF0ueCREREREREVHoOrbuPrYOrwsDLyGmpKQEAJCdnS15JkREREREREShr6SkBPHx8XV+X9FPFpqhZkXTNOzevRuxsbFQFEX2dE5q165d6NKlCwDgl19+QcuWLSXPiGTha4EAvg7oOL4W6Bi+FugYvhboGL4W6BjZrwVd11FSUoIWLVpAVeuu5MKMlxCjqiqysrJkT6Peam6Jio2NRVxcnMTZkEx8LRDA1wEdx9cCHcPXAh3D1wIdw9cCHRMMr4UTZbocw+K6REREREREREQWYeCFiIiIiIiIiMgirPFCRERERERERGQRZrwQEREREREREVmEgRciIiIiIiIiIosw8EJEREREREREZBEGXoiIiIiIiIiILMLACxERERERERGRRRh4ISIiIiIiIiKyCAMvREREREREREQWYeCFiIiIiIiIiMgiDLwQEREREREREVmEgRciIiIiIiIiIosw8EJEREREREREZBEGXoiIiIiIiIiILMLACxERERERERGRRRh4ISIiIiIiIiKyCAMvREREREREREQWYeCFiIiIiIiIiMgiDLwQEREREREREVmEgRciIiIiIiIiIos4ZU+A7KOkpASffPIJ1qxZg23btqG4uBgAEBcXh9zcXOTl5WHMmDGIjY2VPFMiIiIiIiKipsHAC1muqqoKM2fOxLPPPouqqioAgK7rAY9RFAUAEB4ejhtvvBEPPPAAwsPDhc+VxPF6vdi0aVOtQbgOHTrA4XBIniGJsnfvXqxdu7bW10KvXr2QkZEheYYkCu8LREREFIoU3bgCJmpCHo8HI0aMwLJly6DrOrKzs9GnTx9kZ2cjJiYGAFBaWoqCggLk5+ejoKAAiqJg8ODBWLx4MZxOxgZDzbp16/DII49gwYIFKCsrq/Ux0dHRGDduHKZPn45u3boJniGJ8sknn+Dhhx/GDz/8cMLHnXrqqbj77rsxevRoQTMj0XhfoNosX778hFmy/fv3lzxDEoUBegJ4T6DjmuU9QSey0OOPP64riqL36NFDX7Zs2Ukfv3TpUr179+66qqr63/72NwEzJJH++c9/6k6nU1dVVVcURVcURY+Pj9dbtmypt2zZUo+Pj/d/XVEU3el06s8++6zsaZMF7rjjjoDXQXJyst6zZ0990KBB+qBBg/SePXvqycnJ/u+rqqrfcccdsqdNFuB9gYyee+45PSsrS1dV9YT/ZWdn688//7zs6ZKFPv74Y33gwIEnfS0MGjRI/+STT2RPlyzCewId05zvCcx4IUudcsopKCgowKZNm5CUlFSv5xw8eBDt27dHdnY2fvzxR4tnSKJ8+eWXGDlyJFRVxdSpUzFlyhT06dPHVNOnpKQE+fn5eOedd/Dmm29C0zQsXrwYp512mpyJU5ObO3cu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9UsuuURXFEW/6aabBMyQROF9gWraunWrHhMToyuKonfs2FG/99579fnz5+tr1qzRN23apG/atElfs2aNPn/+fP3ee+/VO3bsqCuKosfFxelbt26VPX1qQoqi6FdccYXp64899piuqqquKIqempqqDxw40P86UFVVP+WUU3S32y1hxmQF3hPomFC4JzDwQkRC1LbAmj17tq4oij5u3LhanzNv3rwTfp+ap9atW+vt2rXTNU2r93O8Xq/etm1bvXXr1hbOjETjfYFqmjp1qq4oin733XfX6/6gaZp+11131fo6ouattnN64MABPTIyUnc4HPpTTz2le71e//dWrVql5+bm6qqq6v/6179ET5cswnsCHRMK9wR2NSIiadasWQNFUTB9+vRav3/uueeiffv2WLVqleCZkZX27NmDPn36QFGUej9HVVX07dsXe/bssXBmFAx4X7CvRYsWoVu3bnjooYfqdX9QFAUPP/wwunXrxq1nNjB//nxUVlbikksuwS233AJVPb6MycvLw5tvvgld1/Hf//5X4iypKfGeQCfS3O4JDLwQkTRHjhwBAHTp0qXOx3Tp0gUHDhwQNSUSID4+Htu2bWvw87Zv3474+HgLZkTBhPcF+9q/fz+6devW4Od169bNVGyTQs+6deugKApuvPHGWr8/dOhQdOvWDT/++KPgmZFVeE+gE2lu9wQGXohImqSkpJM+JjIyEmFhYQJmQ6IMGTIEK1euNBVUPZF//etfWL58OYYMGWLhzCgY8L5gX6mpqVi3bl2Dn7du3ToW3baB0tJSAEDHjh3rfEyHDh1w+PBhUVMii/GeQCfS3O4JDLwQkTBr167FAw884P/vl19+AQDs2LGjzufs2rULycnJoqZIAsyYMQMOhwPXXHMNzjrrLLz55ptYv349SkpKoGkaNE1DSUkJ1q9fjzfffBNnnnkm/vznP8PpdOKuu+6SPX1qYrwv0DEjRozA+vXrMXPmzHo/55577sH69esxcuRIC2dGwSAtLQ0ATJ1LanI6nYiMjBQ1JbIY7wl0Is3tnsB20kQkRM19l4BvH66u61AUBbNmzcKdd95pek5VVRVSU1PRv39/7tUNMXPmzMHUqVP97YFPRNd1REVF4Y033sDEiRMFzZBE4H2BatqyZQt69uyJiooKdOjQARdeeCH69OmDnJwcREdHAwDKysqwc+dO5Ofn491338XGjRsRFRWFH3/8EW3atJH8L6Cmoqoq2rVrh8GDB/u/tnnzZnz77bdYvnw5+vTpU+vzBg4ciH379mHz5s2ipkoW4j2BjgmFe4JT9gSIyB7uu+++Or/XsmXLWr8+Z84clJaWom/fvlZNiySZOHEiBg0ahKeeegoffvhhnX8Q27Vrh/POOw+33HILMjMzBc+SrMb7AtXUtm1bfP755zj//POxYcMGPPDAAyd8vK7raNGiBf773/9ygRWCNm/eXOvfhvnz59e6yCotLcWaNWswYsQIEdMjAXhPoJqa+z2BGS9EFLQKCgpw6NAhZGdn16vuAzVfpaWl2L59O0pKSgAAsbGxaNWqFWJjYyXPjIIN7wuhr6KiAq+//jo+/PBDrFmzBgcPHgz4flJSEvLy8nDeeedh6tSpQZNGTk3nzTffrPN7GRkZOPPMM01ff/7553HDDTfg3nvvxf3332/h7Eg03hMoFO4JDLwQERERUdAqLS0NCMrGxMRInhEFo4qKClRXVyMqKgoul0v2dMhCvCdQfQTbPYGBFyIiCjq7du1CYWEhYmNj0bFjRzgcDtlTIgssW7YMvXv35qeTREREFNLY1YiIhPr3v/+NUaNGoXPnzhg+fDief/55eDyeOh9/xx13oG3btgJnSFarrq6G1+ut9XvffPMN8vLykJOTg4EDB6J79+5ISUnB/fffD03TBM+UrDZ06FBkZmbiuuuuw8qVK2VPh4iIiMgSzHghImGuu+46vPzyy6h521EUBT169MCcOXNqDbBcfvnleOutt+pcqFPz43A4MHXqVLz66qsBX//8889xzjnnoLq62vQcRVEwZcoUvP3226KmSQIc62p0rLNV165dcdVVV+Hiiy9m/Rab27hxI+bNm4c1a/6/vTsPrunu4zj+OSdBglgSayNEWpRRxhBrCSWG2hkULRdddAljq13peIwaWtraZuxKU0trSmIpHcuU2hJaO7XvU9lIKhI5zx/GVY+I5XHP4Xq/ZjKTnHN+yeeOr+Tkm9/5/eJ18uRJpaSkSJIKFCig0NBQ93oO5cuXdzgpAKdkZmZqx44d7hmyNWrUcG8xDO/y3XffKSIiQiEhIU5HeWLMeAFgi9jYWM2aNUumaap379769ttv1a9fPxUoUED79u1T3bp19ccffzgdEzawLEv/2/O/efOmevXqpZs3b6pNmzbau3ev0tPTdeHCBU2ePFl58uTRkiVLtG7dOodSw1Nq1qypZs2ayTAM7d+/X/3791dwcLDeeust/r1fQAkJCerUqZMqVqyo4cOHa+nSpdq1a5eOHDmiI0eOaNeuXVq2bJmGDx+uihUrqnPnzkpISHA6NjwgMzNT48aNU/ny5eXv76+wsDB9+umnSkxMfOCYnj17yteXTVu9xdGjR3X58uVsz33//fcqVaqUGjRooK5du6pVq1Z66aWX5HK5lJaWZnNSeFr37t1VtmxZNW/eXMuXL1dGRobTkR4bM14A2KJNmzZavXq1oqOj1bFjR/fxy5cvq1u3bvr1118VFBSk9evXq1q1au7zzHjxPqZpyuVyae7cue5jK1euVPv27VWvXj1t3br1vjFz5szRe++9p06dOik6OtrOuPCgf9fChQsXNG/ePC1YsMC9XaRhGCpVqpR69uwpl8ul0NBQZwPDo1JTUxUeHq7Dhw/LNE3Vq1dPNWrUUEhIiHvxzOvXr+vs2bPavXu3tm3bpqysLL366qvauXOn8uXL5/ArwNPUunVrxcTE3DdLNjg4WEuXLlXt2rXvG8M9g3d50AzZRYsWyeVyybIs+fj4qFixYkpOTlZaWpoMw9Abb7yhX375xaHU8IQ7M2Sl298HAgMD9c4776hXr16qXLmyg8kegwUANihRooRVpUqVbM9lZmZavXv3tgzDsIKCgqw9e/a4z7lcLss0TbtiwgaGYVg9e/a859iwYcMs0zStDRs2ZDsmKyvLKlOmjBUaGmpHRNgku1qwLMvavHmz1b17dytfvnyWYRiWaZqWj4+PFRkZaUVHR1vp6ekOpIWnjRgxwjIMw2rSpIl1+vTph15/6tQpq3HjxpZpmtbIkSNtSAi7LF682DIMw8qfP781btw4KyYmxpoyZYoVFhZmGYZh5c2b11q/fv1947hn8C7Z/Yy4du2aVahQIcs0Tatv375WQkKCZVmWdevWLevHH3+0goKCLNM0rR9++MGJyPAQwzCsxo0bWx999JFVuHBh972BaZpWrVq1rFmzZlkpKSlOx8wRjxoBsMXVq1dVqVKlbM/5+Pho9uzZioqKUkJCgiIjIxUXF2dzQjjp6tWrkqSqVatme94wDFWuXPmBU47hXRo0aKAFCxbo4sWLmjlzpsLDw5WVlaUNGzaoa9euKlmypPr27et0TDxlK1asUMmSJbVq1SqVLl36odeXKVNGq1atUokSJbRs2TIbEsIu8+fPl2EYio2N1YgRI/Tmm2+qX79+2r9/v7p3765//vlHbdq00dq1a52OCputWrVKycnJatmypaZOnarChQtLuj0jol27dpo9e7Ysy9LixYsdToqnrXTp0po2bZouXryoRYsWqWHDhpKknTt36sMPP1TJkiXlcrm0ZcsWZ4M+AI0XALbIly+fUlNTc7xm6tSp6t+/vxITExUZGak9e/bYlA5OCwgIkKQctxUuVKiQexFWvBgCAgL0/vvv6/fff9eBAwfUv39/FS1aVImJiZo2bZrT8fCUnT59WvXr15efn98jj/H391f9+vV15swZDyaD3eLj4xUeHq769evfc9zf31/z58/X2LFjdePGDbVr105r1qxxKCWcEB8fL8MwNHTo0GzPt23bVuXKleMe0ovlyZNH3bp108aNG3XixAmNGjVKISEhSktL08KFC9WoUSOVL19eX3zxhS5duuR0XDcaLwBs8ag/BCdPnqxBgwYpMTFRTZs21cGDB21IB7sdP35cCxcudL/9/fffkpTjL0+XL19WUFCQXRHxjKlYsaImT56sc+fOacWKFWrRooXTkfCU5cuX74lmtV25coX1XbxMcnKywsLCHnh+1KhRmjRpktLT09W+fXuaLy+Q5ORkSXrgLOo75+7cV8C7lSlTRmPHjtXJkye1bt06derUSblz59bx48c1fPhwlS5dWq1bt3Y6piQaLwBsEhERoUuXLmnbtm0PvXbixInunQt2795tQzrY7bffflPPnj3dbwsXLpQkbdy4Mdvrb926pbi4OJUtW9bOmHgG+fr6ql27dvr555+djoKnLDw8XFu3btX69esfecy6deu0efNm1axZ04PJYLcCBQrkuHuRJA0YMEBTp05Venq6OnTooNjYWJvSwUmBgYEPvcbf31+5c+e2IQ2eFYZhKDIyUtHR0bpw4YKmTp2qqlWrKjMzUzExMU7HkySx3xoAWzRv3lyTJ0/WlClTVLdu3YdeP2HCBPn6+mr8+PE8XuJlevTo8cBzD9qJIjY2VomJiapRo4anYgFw2IABA7R27Vq1bNlSvXr1UpcuXVSjRo37ZrOkpqZq9+7dWrJkiebNmydJGjhwoBOR4SEVK1bU7t27ZVlWjvcAUVFRMk1TUVFR6tChQ46zZPB82rt3rz7//HP3x3dm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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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/Pg88MADedOb3pRDDz20M10CAAAAVIXSM1Wee+65HHXUUZkzZ07e8Y535Oqrr86gQYNW2PZDH/pQiqLI+PHjSxcKAAAAUE1KhyoXXXRR5s+fn2OOOSa//vWvc+yxx6ZXr14rbLv//vsnSR566KGy3QEAAABUldKhyp133plKpZJzzz13tW1HjBiRPn365IUXXijbHQAAAEBVKR2qTJ06NX379s3mm2/eofZ9+/bNggULynYHAAAAUFVKhyobbLBBWlpaOtR20aJFmT17dhobG8t2BwAAAFBVSocqW265ZVpaWvLMM8+stu1tt92W1tbWbLfddmW7AwAAAKgqpUOVQw45JEVR5KKLLlplu5kzZ+YLX/hCKpWKzykDAAAA64zSocopp5yS173udbnyyivzmc98JlOnTm23/1//+ld+/OMf561vfWueffbZbLrppjn55JM7XTAAAABANagURVGUPfihhx7KgQcemFmzZv37ZJVKiqLIBhtskEWLFiVJiqLIkCFDcuedd2b77bfvmqrXsubm5jQ2NqapqSkNDQ3dXQ4AAACsk2rt+bv0TJUk2XnnnfP444/nuOOOS69evdLW1paiKLJw4cIURZH6+vq8//3vzyOPPFKzgQoAAADAinRqpsqrLVy4MI888khefPHFtLa2ZujQodl5553Tr1+/rjh9t6q1pAwAAABqUa09f9d31Yl69+6d3XffvatOBwAAAFDVOvX6DwAAAMD6qstmqixYsCCzZ89OS0vLKtuNHDmyq7oEAAAA6DadClWampry9a9/PTfeeGP+/ve/r7Z9pVLJkiVLOtMlAAAAQFUoHapMmzYte+65Z1544YV0dK3bLloTFwAAAKDblQ5VTjvttDz//PMZMGBAPv/5z2fffffN0KFD06NHj66sDwAAAKAqlQ5Vbr/99lQqlVxzzTV55zvf2ZU1AQAAAFS90l//WbBgQfr06ZODDz64K+sBAAAAqAmlQ5VRo0ZZIwUAAABYb5UOVY4//vgsXLgwd9xxR1fWAwAAAFATSocqp556asaOHZsPfvCDuf/++7uyJgAAAICqV3qh2vr6+vz617/O5z73uYwZMyZve9vbsu2222bYsGGrPO6ss84q2yUAAABA1agUnVgY5ZZbbsmnPvWpTJ48OZVKpUPHtLa2lu2u2zQ3N6exsTFNTU1paGjo7nIAAABgnVRrz9+lZ6rcddddOfzww9PW1pZKpZKtttoqr3vd69KjR4+urA8AAACgKpUOVc4999y0trbmbW97W6677rpssskmXVkXAAAAQFUrvVDt448/nkqlkmuvvVagAgAAAKx3SocqPXv2TENDQ0aOHNmV9QAAAADUhNKhyk477ZS5c+emubm5K+sBAAAAqAmlQ5XPf/7zaWtry0UXXdSV9QAAAADUhNKhyr777ptLL700F154YT70oQ/l2Wef7cq6AAAAAKpapSiKosyBo0aNSpLMmDEjCxYsSJL07t07Q4cOXXlnlUqee+65Mt11q1r7TjYAAADUolp7/i79SeUXXnhhuW0LFixY4falKpVK2e4AAAAAqkrpUOWqq67qyjoAAAAAakrpUOWEE07oyjoAAAAAakrphWoBAAAA1mdrNFRZsGBBmpqa1mQXAAAAAN2idKgyZcqUXHnllRk/fvxy+/76179m9OjRGTBgQAYPHpzdd989Tz/9dKcKBQAAAKgmpUOVK664IieffHIeeOCBdtvnzJmT/fbbLw899FDa2tpSFEUmTpyYfffdN7Nmzep0wQAAAADVoHSoctdddyVJjjrqqHbbr7jiikyfPj3Dhg3LuHHjMn78+Gy99dZ56aWXcvHFF3euWgAAAIAqUTpUmTx5cpLkDW94Q7vtv/jFL1KpVPL1r389hx12WA488MBcfvnlKYpiha8KAQAAANSiSlEURZkD+/btmz59+uSVV15Ztq2lpSUDBgxIURR55ZVX0r9//2X7evXqlb59+2b27NmdLnpta25uTmNjY5qamtLQ0NDd5QAAAMA6qdaev0vPVKlUKpk3b167bQ8//HAWL16cHXbYoV2gkiSNjY1ZuHBh2e4AAAAAqkrpUGXkyJFpaWnJY489tmzbzTffnEqlkj333LNd27a2tjQ3N2fIkCGlCwUAAACoJqVDlX322SdFUeRjH/tY/vjHP+aWW27JD37wgyTJO9/5znZtn3rqqbS0tGT48OGdqxYAAACgStSXPfC0007LNddckwcffDC77bZbkqQoiuyxxx7Za6+92rX91a9+lUqlsqwdAAAAQK3r1Os/EyZMyF577ZXevXvnda97XU466aTcfPPN7doVRZEf/ehHKYoi++67b2frBQAAAKgKpb/+01Gtra2ZMmVKkmT48OGpry89Oabb1NrqwwAAAFCLau35e40nHD169Mimm266prsBAAAAWKtKv/6zOm1tbXn66afz+OOPp62tbU11AwAAANAtSocqTz31VM4666xcddVVy+2bMGFCNt1007z5zW/OjjvumM033zz33ntvpwoFAAAAqCalQ5Wf/OQn+epXv5oZM2a02z5jxowceuihmTp1aoqiSFEU+ec//5l3vvOdy9ZWAQAAAKh1pUOVCRMmJEkOP/zwdtsvu+yyzJkzJ2984xvz8MMP5y9/+Ut22223zJ07NxdffHHnqgUAAACoEqVDlalTp6ZSqWSzzTZrt/3WW29NpVLJBRdckB133DHbbLNNvve976Uoitxxxx2drRcAAACgKpT+pHLv3r3Tv3///Otf/1q2bcGCBWloaEjPnj0ze/bs9OrVq137Xr16pbm5ufNVr2W19kknAAAAqEW19vxdeqZKz549lwtIJk6cmNbW1uy8887tApUk6d+/f1paWsp2BwAAAFBVSocqo0aNSmtra+67775l237+85+nUqlkzz33bNd2yZIlaWpqytChQ8tXCgAAAFBF6sseeOCBB+aJJ57IBz7wgZx33nl56aWXcsUVVyRJ3vOe97Rr+/jjj6e1tTWbbLJJ56oFAAAAqBKlQ5XPf/7z+b//+788++yzOfroo5MkRVHk0EMPzVvf+tZ2bX/5y1+ucAYLAAAAQK0qHapsuOGGmThxYr785S/ngQceSENDQw466KCcdtpp7dq1tLTkRz/6UYqiyL777tvpggEAAACqQemv/6xPam31YQAAAKhFtfb8XXqhWgAAAID1WenXf16ttbU1jzzySCZPnpz58+fn+OOP74rTAgAAAFStTs9U+da3vpWNN944u+22W4466qicdNJJ7fbPnj072223Xd74xjfmpZde6mx3AAAAAFWhU6HKBz/4wXz+85/PK6+8kl69eqVSqSzXZuDAgdl1110zadKk3HDDDZ3pDgAAAKBqlA5Vbr755lx11VUZMGBArr/++sydOzdDhgxZYdtjjjkmRVHkrrvuKl0oAAAAQDUpvabKZZddlkqlkgsuuCBHHnnkKtvusssuqVQqeeKJJ8p2BwAAAFBVSs9Uefjhh5Mkxx133Grb9uvXLw0NDZk+fXrZ7gAAAACqSulQZek3o/v169eV9QAAAADUhNKhyuDBg9Pc3JyFCxeutu2LL76YpqamDB06tGx3AAAAAFWldKiy0047JUl+97vfrbbtZZddliTZfffdy3YHAAAAUFVKhyonnnhiiqLIl770pcyePXul7X7+85/n/PPPT6VSyQc/+MGy3QEAAABUldJf/zn88MNz8MEHZ/z48dl5551z0kknZdGiRUmSG264IZMnT86vfvWr3HvvvSmKIu9///uz9957d1nhAAAAAN2pUhRFUfbg+fPn56STTsqNN96YSqWy3P6lpz7qqKPy4x//OBtssEH5SrtRc3NzGhsbly3OCwAAAHS9Wnv+Lv36T5L07ds3P/vZzzJhwoQcc8wxGTVqVPr06ZNevXplk002yfve97785je/yXXXXVezgQoAAADAinRqpsr6otaSMgAAAKhFtfb83amZKgAAAADrq9IL1a7Ov/71rzz88MNZtGhRxowZk0GDBq2prgAAAADWutIzVf74xz/m+OOPz4UXXrjcvuuuuy6jRo3KwQcfnMMOOywjR47MDTfc0KlCAQAAAKpJ6VDlmmuuyTXXXJO+ffu22/7888/nxBNPzNy5c//dQV1d5s2bl+OOOy5PP/1056oFAAAAqBKlQ5V77703SfKud72r3fbLLrssLS0t2W233TJjxozMnDkz73rXu9LS0pJLLrmkc9UCAAAAVInSocpLL72UHj16ZMSIEe22jx8/PpVKJeeee2423HDDDBgwIBdddFGSZMKECZ2rFgAAAKBKlP6k8gYbbJABAwbkX//617Jtzc3NGTRoUPr165fZs2enru7/ZTZ9+/ZNpVLJvHnzOl/1WlZrn3QCAACAWlRrz9+lZ6r07t07s2fPTmtr67Jt9957b4qiyOjRo9sFKknSp0+f8lUCAAAAVJnSocrWW2+doihy++23L9t2/fXXp1KpZMyYMe3aLly4ME1NTdl4443LVwoAAABQRerLHnjooYfm4Ycfzgc+8IF89rOfzUsvvZRrr702lUolRxxxRLu2Dz/8cNra2rLZZpt1tl4AAACAqlA6VDn11FNz7bXX5sknn8wXv/jFJElRFPnIRz6Srbfeul3bm266KZVKJWPHju1ctQAAAABVonSo0rdv30ycODHf/va388ADD6ShoSEHHXRQjjvuuHbtWlpaMmHChIwcOTLveMc7Ol0wAAAAQDUo/fWf9UmtrT4MAAAAtajWnr9LL1QLAAAAsD4r/frP6vz1r3/Nvffem0WLFuXtb3973vSmN62prgAAAADWutIzVe68886MGTMmp59++nL7Lrzwwuywww75+Mc/ns985jPZfvvt861vfatThQIAAABUk9Khyo033pj7778/b3zjG9ttf+KJJ3L66aentbU1gwcPzpAhQ9La2povfOELefDBBztdMAAAAEA1KB2qTJw4MUmW+6LP5ZdfnqIocvDBB2fatGl56aWX8sEPfjBtbW35/ve/37lqAQAAAKpE6VBlxowZ6dmzZ4YNG9Zu+x133JFKpZIzzjgjPXv2TJKcc845SZL77ruvE6UCAAAAVI/SocqsWbPSr1+/dtv+9a9/ZdKkSRk0aFBGjx69bPvrX//69OvXL9OmTStfKQAAAEAVKR2q9O/fP7Nnz86iRYuWbbv77ruTJG9729uWa9+zZ8/U16+xjw0BAAAArFWlQ5U3v/nNSZJx48Yt23b11VenUqlk7Nix7drOnTs3TU1Ny70qBAAAAFCrSk8dOeqoo3L//ffnwx/+cO6///689NJL+dWvfpWePXvmyCOPbNf2gQceSFEU2XLLLTtdMAAAAEA1KB2qfOQjH8lNN92Uu+++Oz/84Q9TFEWS5Oyzz84mm2zSru0NN9yQSqWSvfbaq1PFAgAAAFSL0qFKfX197rzzzlx33XWZOHFiGhoacuCBB2bMmDHt2rW0tGTq1KkZM2ZMDjrooE4XDAAAAFANKsXSKSasVHNzcxobG9PU1JSGhobuLgcAAADWSbX2/F16oVoAAACA9ZlQBQAAAKCE0muqvNq9996b+++/P9OmTcu8efOysjeKKpVKrrjiiq7oEgAAAKBbdSpU+ctf/pL3v//9+etf/9pue1EUqVQqK9wmVAEAAADWBaVDlZdeein77rtvXn755QwZMiRve9vb8stf/jJ9+vTJ4YcfnunTp+fBBx9Mc3NzNtpooxx88MFdWTcAAABAtyodqnzzm9/Myy+/nNGjR+e2225LY2Nj6urq0tjYmKuvvjpJsmDBgnzjG9/Iueeem549e+ayyy7rssIBAAAAulPpUOW2225LpVLJhRdemMbGxhW26dOnT84+++wsWbIk559/fsaOHZtjjjmmdLEAAAAA1aL013/+8Y9/pK6uLqNHj263ffHixcu1/cxnPpNKpZLLL7+8bHcAAAAAVaVTn1QeOHBgevTosez3/fr1S1NTU9ra2tq1GzRoUBobG/PEE090pjsAAACAqlE6VBk+fHjmzp3bbtuIESPS1ta2XHgyZ86czJ49O/Pnzy/bHQAAAEBVKR2qbLXVVlm8eHEmTZq0bNtuu+2WJDnvvPPazVY566yzUhRFtthii06UCgAAAFA9Socq++67b4qiyK9//etl2z760Y8mSW666aa88Y1vzJFHHpkddtghl1xySSqVSk444YTOVwwAAABQBUp//ed973tfHn/88Xav9Oy88875+te/ntNPPz3PPvtsnn322WX7DjvssHz2s5/tXLUAAAAAVaJSFEXR1Sd98skn8/Of/zxTpkxJY2Nj9t9//+y///5d3c1a09zcnMbGxjQ1NaWhoaG7ywEAAIB1Uq09f5eeqbIq22yzTbbZZps1cWoAAACAqtCpTyoDAAAArK+EKgAAAAAlCFUAAAAAShCqAAAAAJQgVAEAAAAoQagCAAAAUIJQBQAAAKAEoQoAAABACUIVAAAAgBKEKgAAAAAl1Hek0ahRo7qks0qlkueee65LzgUAAADQnToUqrzwwgur3F+pVFIUxWr3VSqV11YdAAAAQJXqUKhy1VVXrXD7zJkzc+6556apqSl77LFH9t577wwfPjxJMnXq1Nx999259957M3DgwJx11lkZNGhQ11UOAAAA0I0qxcqmmKxGc3Nzdt5558yaNSs33nhjxo4du8J29957bw4//PBsuOGG+eMf/5gBAwZ0quDu0NzcnMbGxjQ1NaWhoaG7ywEAAIB1Uq09f5deqPYrX/lKnn322fzoRz9aaaCSJHvuuWd+9KMf5Zlnnsl5551XtjsAAACAqlJ6pspWW22VadOmZe7cuatdK6UoivTv3z+vf/3rM2nSpFKFdqdaS8oAAACgFtXa83fpmSpTpkxJfX19hxafrVQqqa+vz9SpU8t2BwAAAFBVSocqgwYNyty5c/Pwww+vtu3DDz+cOXPmZODAgWW7AwAAAKgqpUOV/fbbL0VR5IMf/GCmT5++0nYzZszIBz/4wVQqley///5luwMAAACoKqXXVPn73/+eHXbYIfPmzUtDQ0NOOumkjB07dtknladNm5Z77rknV111VWbPnp0BAwbksccey+abb96lP8DaUGvvdAEAAEAtqrXn79KhSpLcf//9ee9735vp06evdG2Voiiy8cYbZ9y4cXnb295WutDuVGuDCgAAALWo1p6/S7/+kyS77757nn766Zx77rnZfvvtU1dXl6IoUhRF6urqsv322+e8887LU089VbOBCgAAAMCKdGqmyn9qaWnJzJkzkySDBw9Oz549u+rU3arWkjIAAACoRbX2/F3flSfr2bNnhg4d2pWnBAAAAKhKXRaqzJgxI5MnT878+fMzZsyYrjotAAAAQFXq1JoqSXLTTTdlhx12yLBhw7Lrrrtmn332abd/9uzZOeCAA3LAAQekqamps90BAAAAVIVOhSrnnHNOjjjiiPz5z39etkDtfy7RMnDgwDQ2NubOO+/MjTfe2KliAQAAAKpF6VDlnnvuyTnnnJP6+vpccMEFmTx58krXUzn++ONTFEXuuOOO0oUCAAAAVJPSa6pccsklqVQqOfvss/OFL3xhlW133333JMljjz1WtjsAAACAqlJ6psrEiROTJB/72MdW23bgwIEZMGBApk2bVrY7AAAAgKpSOlR55ZVX0tDQkIEDB3aofY8ePdLW1la2OwAAAICqUjpUaWxszJw5c9LS0rLatjNnzkxTU1M22mijst0BAAAAVJXSocr222+foijywAMPrLbtNddck6Iosssuu5TtDgAAAKCqlA5Vjj766BRFkTPPPHOVs1UeeOCBnHHGGalUKjnuuOPKdgcAAABQVUqHKieddFJ22WWX3HvvvRk7dmyuvfbaLFmyJEny0EMPZdy4cTnxxBOz1157Ze7cudlnn31y6KGHdlXdAAAAAN2qUhRFUfbgl19+OYceemgmTpyYSqWywjZFUWSPPfbILbfc0uFFbatNc3NzGhsb09TUlIaGhu4uBwAAANZJtfb8XXqmSpIMGTIkv//973PllVdm9913T69evVIURYqiSF1dXXbddddcdtllmTBhQs0GKgAAAAAr0qmZKv+pra0tM2fOTGtrazbccMPU19d31am7Va0lZQAAAFCLau35u0tTj7q6Op9NBgAAANYLXRqqzJ49Oy+//HKSf78a5JUfAAAAYF3VqTVVkmTGjBk5/fTTs8UWW2TDDTfMG9/4xrzxjW/MhhtumC222CJf/OIXM2PGjK6oFQAAAKBqdGpNlbvuuitHHXVUZs+enZWdplKpZODAgfnZz36W/fbbr3Sh3anW3ukCAACAWlRrz9+lX/956qmn8q53vSuLFi3KkCFD8tGPfjRjx47N8OHDkyTTpk3LPffckx/84AeZPn16DjnkkDzyyCN505ve1GXFAwAAAHSX0jNVjjrqqNx4443Zeeedc/vtt2fQoEErbDdr1qwccMABeeihh3LUUUfluuuu61TB3aHWkjIAAACoRbX2/F16TZUJEyakUqnkiiuuWGmgkiSDBg3Kj370oyTJ7373u7LdAQAAAFSV0qHK3Llz09DQkG233Xa1bbfbbrs0NjZm7ty5ZbsDAAAAqCqlQ5XNNtssCxcuTGtr62rbLlmyJAsXLsymm25atjsAAACAqlI6VDnqqKOyePHiXH/99att+7Of/SyLFi3K0UcfXbY7AAAAgKpSeqHaRYsWZe+9984TTzyRyy+/PO973/tW2O5nP/tZPvShD2X77bfPhAkT0qtXr04V3B1qbaEcAAAAqEW19vxdOlQ599xzs3Dhwlx66aVpbm7OpptuusJPKr/wwgtpbGzMRz/60WywwQYrPNdZZ51V/idYC2ptUAEAAKAW1drzd+lQpa6uLpVKJUmy9BRLf7/Uyrb/p46sy9Kdam1QAQAAoBbV2vN3fdkDx4wZs9qwBAAAAGBdVTpUufvuu7uwDAAAAIDaUvrrP93lxhtvzF577ZVBgwalX79++a//+q984xvfSEtLS3eXBgAAAKxHaipUOfXUU3PkkUfm/vvvzy677JIDDjggkydPzmmnnZZ99tknCxYs6O4SAQAAgPVE6dd/Xm327Nm59dZb8+ijj2bGjBlJkte97nXZcccd8653vSsDBw7sdB8333xzLr744vTv3z/33HNPdtxxxyTJv/71r+yzzz657777cuaZZ+aiiy7qdF8AAAAAq1P66z9JsmTJkpx99tn59re/nYULFyZZ/os/vXv3zqc//emcffbZ6dmzZ+lCd9lllzz00EM577zzcsYZZ7Tbd99992XPPffMBhtskOnTp6exsbF0PytSa6sPAwAAQC2qtefv0qFKW1tb3vnOd+aOO+5IURTp27dv3vrWt2b48OFJkmnTpuXhhx/O/PnzU6lUcsABB+RXv/pVqS8GTZ06NSNGjEiS/P3vf8/mm2++XJuRI0fmn//8Z6699tocffTRZX6klaq1QQUAAIBaVGvP36XXVLnkkkty++23p66uLl/5ylcyffr03HPPPbn22mtz7bXX5u67786MGTPy1a9+NXV1dbn99tvzne98p1Rff/rTn5IkgwcPXmGgkiQ77bRTu7adMWXKlHa/pk6d2ulzAgAAAOuW0muqXHXVValUKrnwwgtz6qmnrrBN375988UvfjF9+vTJZz7zmVx55ZX51Kc+9Zr7ev7555P8ezbKymyyySbt2nbG0nMBAAAArEzpmSqTJk1KfX19PvKRj6y27Uc+8pHU19dn0qRJpfqaM2dOkqRfv34rbdO/f/8k/54qBAAAALCmlZ6p0r9//7S2tqZ3796rbdu7d+/0798/9fVd8rGhNe6f//xnu9/PmTMn22yzTTdVAwAAAFSj0jNVdt1118yePTuTJ09ebdt//OMfmT17dnbbbbdSfQ0YMCBJMm/evJW2mTt3bpJ0yUI2I0aMaPdr6eK7AAAAAEuVDlW++MUvpkePHvnYxz6WlpaWlbZbsmRJPv7xj6e+vj5f/OIXS/W12WabJVl+BsmrLd23tC0AAADAmlQ6VHnb296Wn/3sZ7n//vuz00475eqrr84//vGPLFmyJEuWLMnkyZPz05/+NDvttFP+8Ic/5IYbbsjo0aNL9fWWt7wlSfLKK6+sdCHahx9+OEmy4447lvuBAAAAAF6DSlEURZkDe/To0TUFVCpZsmTJatvtsssueeihh3LeeefljDPOaLfvvvvuy5577pkNNtgg06dPT2NjY5fUtlStfScbAAAAalGtPX+XnqlSFEWX/eqIL33pS0mSCy64II8++uiy7a+88ko+9rGPJUk+8YlPdHmgAgAAALAipT/HM2HChK6sY7UOPfTQfOpTn8oll1yS0aNHZ999902/fv3y29/+NrNnz87uu++er3zlK2u1JgAAAGD9Vfr1n+5yww035Hvf+14ee+yxtLS0ZIsttsixxx6bT3/60+nVq9ca6bPWph8BAABALaq15++aC1W6Q60NKgAAANSiWnv+Lv36z4q0trZm5syZSZLBgwd32WK2AAAAANWm9EK1S82dOzcXXnhhdtppp/Tp0ycbb7xxNt544/Tp0yc77bRTvvnNb2bevHldUSsAAABA1ejU6z9/+ctfcsghh+Qf//jHSr/iU6lUstlmm+WWW27Jm9/85tKFdqdam34EAAAAtajWnr9Lv/4za9asvP3tb89LL72UPn365Pjjj89+++2XESNGJEmmTJmSO++8Mz/96U/z/PPP5x3veEeeeOKJDBo0qMuKBwAAAOgupUOVb37zm3nppZeyxRZb5I477sioUaPa7d91111z+OGH5/Of/3ze8Y535Pnnn8+3vvUtnz0GAAAA1gml11S55ZZbUqlUcsUVVywXqLzaFltskSuuuCJFUeSXv/xl2e4AAAAAqkrpNVUGDBiQJJkzZ06H2vfv3z+VSqXD7atJrb3TBQAAALWo1p6/O/31n46qVCprqysAAACANa50qLL55ptn/vz5uf/++1fb9t577828efOy2Wable0OAAAAoKqUDlXe+c53piiKfOhDH8qUKVNW2m7KlCk5+eSTU6lUcsghh5TtDgAAAKCqlF5TZebMmdlmm23y8ssvp3///jnxxBOz9957Z/jw4UmSqVOn5re//W2uvvrqzJkzJ0OHDs1f//rXDB48uEt/gLWh1t7pAgAAgFpUa8/fpUOVJHnsscdyyCGHZMqUKStdM6UoimyyySb55S9/mR122KFsV92q1gYVAAAAalGtPX93aqHaHXbYIX/5y19y3nnnZfvtt09dXV2KokhRFKmrq8t//dd/5fzzz88TTzxRs4EKAAAAwIp0aqbKf2ppacnMmTOTJIMHD07Pnj276tTdqtaSMgAAAKhFtfb8XXqmyqBBg7Lhhhvm73//+7JtPXv2zNChQzN06NB1JlABAAAAWJHSocrixYvT2tqaUaNGdWU9AAAAADWhdKgycuTILF68uCtrAQAAAKgZpUOVQw45JIsWLcqdd97ZlfUAAAAA1ITSocqXvvSlbLbZZjn55JPz1FNPdWVNAAAAAFWvvuyBv/zlL/PRj3405557bt7ylrfkwAMPzG677ZYhQ4akR48eKz3u+OOPL9slAAAAQNUo/Unlurq6VCqVJElRFMv+eZWdVSpZsmRJme66Va190gkAAABqUa09f5eeqTJy5MgOBSkAAAAA66LSocoLL7zQhWUAAAAA1JbSC9UCAAAArM+EKgAAAAAlCFUAAAAASujQmiof+MAHuqSzSqWSK664okvOBQAAANCdOvRJ5aWfT15R045+AWjpZ5dbW1tfe5XdrNY+6QQAAAC1qNaevzs0U+X4449faXhy8803p6mpKX369MlOO+2U4cOHJ0mmTp2aRx55JPPnz8/AgQPz7ne/u+uqBgAAAOhmHQpVfvzjHy+3rSiKHHXUUZkzZ07OOeecfPrTn07//v3btZk3b16+9a1v5Zxzzsn8+fPzs5/9rEuKBgAAAOhupReq/d73vpef//znueCCC3LmmWcuF6gkSb9+/XLmmWfmggsuyLhx4/L973+/U8UCAAAAVIsOramyIm9961vzxBNPLHv1Z1WWvgK03Xbb5ZFHHilVaHeqtXe6AAAAoBbV2vN36Zkqf/vb3zJgwIDVBipJ0rdv3wwYMCCTJk0q2x0AAABAVSkdqvTs2TOzZ8/O1KlTV9t26tSpmTVrVurrO7SECwAAAEDVKx2q7LzzzkmSU089dYWfWl6qKIp8+tOfTpLssssuZbsDAAAAqCqlQ5XTTjstRVHkpptuyh577JFbbrklTU1Ny/Y3Nzfn1ltvzZ577pmf//znqVQqOe2007qkaAAAAIDuVnqh2iS5+OKL85nPfKbdtqVrrCxYsCDJv2eqVCqV/O///m8+9alPdaLU7lNrC+UAAABALaq15+/SM1WS5JRTTsm9996bvffeO8m/A5T58+dn/vz5y14J2m+//XLffffVbKACAAAAsCKdmqnyarNmzcqf/vSnvPzyy0mSIUOG5C1veUsGDRrUFafvVrWWlAEAAEAtqrXn7y77HM+gQYOyzz77dNXpAAAAAKpap17/AQAAAFhfCVUAAAAAShCqAAAAAJQgVAEAAAAoQagCAAAAUIJQBQAAAKAEoQoAAABACUIVAAAAgBLqu+pEM2bMyOTJkzN//vyMGTOmq04LAAAAUJU6PVPlpptuyg477JBhw4Zl1113zT777NNu/+zZs3PAAQfkgAMOSFNTU2e7AwAAAKgKnQpVzjnnnBxxxBH585//nKIolv16tYEDB6axsTF33nlnbrzxxk4VCwAAAFAtSocq99xzT84555zU19fnggsuyOTJkzN06NAVtj3++ONTFEXuuOOO0oUCAAAAVJPSa6pccsklqVQqOfvss/OFL3xhlW133333JMljjz1WtjsAAACAqlJ6psrEiROTJB/72MdW23bgwIEZMGBApk2bVrY7AAAAgKpSOlR55ZVX0tDQkIEDB3aofY8ePdLW1la2OwAAAICqUjpUaWxszJw5c9LS0rLatjNnzkxTU1M22mijst0BAAAAVJXSocr222+foijywAMPrLbtNddck6Iosssuu5TtDgAAAKCqlA5Vjj766BRFkTPPPHOVs1UeeOCBnHHGGalUKjnuuOPKdgcAAABQVUqHKieddFJ22WWX3HvvvRk7dmyuvfbaLFmyJEny0EMPZdy4cTnxxBOz1157Ze7cudlnn31y6KGHdlXdAAAAAN2qUhRFUfbgl19+OYceemgmTpyYSqWywjZFUWSPPfbILbfc0uFFbatNc3NzGhsb09TUlIaGhu4uBwAAANZJtfb8XXqmSpIMGTIkv//973PllVdm9913T69evVIURYqiSF1dXXbddddcdtllmTBhQs0GKgAAAAAr0qmZKv+pra0tM2fOTGtrazbccMPU19d31am7Va0lZQAAAFCLau35u0tTj7q6Op9NBgAAANYLpV//OfbYY3PHHXekra2tK+sBAAAAqAmlQ5Vrr702Bx10UF7/+tfn1FNPzR//+MeurAsAAACgqpUOVd7znvekV69emTFjRr7zne9kt912yxve8Iace+65efbZZ7uyRgAAAICq06mFapubmzNu3Lhcc801ueeee9LW1rbs08o777xzjj322Bx11FEZMmRIlxXcHWptoRwAAACoRbX2/N1lX/958cUXc9111+Xaa6/No48++u+TVyrp0aNH9ttvvxx77LE59NBD07dv367obq2qtUEFAACAWlRrz99d+knlpf72t7/l//7v/3Ldddflueee+3dHlUr69euX5ubmru5ujau1QQUAAIBaVGvP36XXVFmVpWurTJo0KX/4wx+y4447piiKzJs3b010BwAAALDW1a+pE//5z3/ONddck+uvvz5TpkxZU90AAAAAdIsuDVUmT56ca6+9Ntdcc02efPLJJElRFOnZs2cOPPDAHHPMMV3ZHQAAAEC36XSoMmvWrNxwww255ppr8oc//CFFUaQoilQqleyxxx455phjcsQRR2TQoEFdUS8AAABAVSgdqvzsZz/LtddemzvuuCMtLS1Zut7tm9/85hx77LF5//vfn0022aTLCgUAAACoJqVDlaOPPjqVSiVFUWTEiBE5+uijc8wxx2T77bfvyvoAAAAAqlLpUKWxsTFHHHFEjjnmmIwZMyaVSqUr6wIAAACoaqVDlenTp6dXr15dWQsAAABAzagre6BABQAAAFiflQ5VAAAAANZnHXr9Z9SoUUmSLbfcMr/5zW/abXstKpVKnnvuudd8HAAAAEC16VCo8sILLyRJevfuvdy218JitgAAAMC6okOhylVXXZXk31/8+c9tAAAAAOujSlEURXcXUe2am5vT2NiYpqamNDQ0dHc5AAAAsE6qtedvC9UCAAAAlFA6VNlnn31yxBFHdLj90UcfnX333bdsdwAAAABVpUNrqqzI3XffnY033rjD7R944IFMnjy5bHcAAAAAVWWtvf7T2trq6z8AAADAOmOthCqLFi3KjBkzMmDAgLXRHQAAAMAa1+HXfyZPnpwXXnih3bbFixfn3nvvzco+IFQURWbPnp3rrrsuixcvzk477dSpYgEAAACqRYdDlauuuirnnntuu22zZs3KXnvttdpjl4Yu//3f//3aqgMAAACoUq9podpXz0ipVCornaHy6jYNDQ3Zdtttc/LJJ+f4448vVyUAAABAlakUq0tGVqKuri4bb7xxpk2b1tU1VZ3m5uY0NjamqakpDQ0N3V0OAAAArJNq7fm79CeVjz/++AwcOLALSwEAAACoHaVDlR//+MddWAYAAABAbVkrn1QGAAAAWNeUnqnyapMnT84f/vCHTJs2LfPmzVvlArZnnXVWV3QJAAAA0K1KL1SbJNOmTcuHP/zh3Hbbbav9ElBRFKlUKmltbS3bXbeptYVyAAAAoBbV2vN36ZkqTU1NGTt2bP7+97+nvr4+22yzTR5//PH06tUru+yyS6ZPn55nn302RVFk8ODB2W677bqybgAAAIBuVXpNlYsvvjjPPfdctt5660yaNCl/+tOfkiSDBw/O73//+zzzzDOZPHlyTjjhhMyaNSv77bdfJkyY0GWFAwAAAHSn0jNVfvnLX6ZSqeSb3/xmRo4cucI2w4cPz1VXXZWePXvmrLPOyo477pgDDzywdLEAAAAA1aL0TJVnn302lUol++23X7vtLS0ty7U955xzUhRFLrnkkrLdAQAAAFSV0qFKS0tLBg0alJ49ey7b1qdPnzQ3Ny/XdtiwYRk4cGAeffTRst0BAAAAVJXSocrrX//6zJ8/v922YcOGZcmSJfnb3/7WbvuiRYvS3Nycpqamst0BAAAAVJXSocqoUaOycOHCTJ48edm2XXbZJcm/F7F9tUsuuSRtbW3ZZJNNynYHAAAAUFVKhyp77713iqLIb37zm2XbPvCBD6QoivzgBz/I3nvvnS984Qs55JBDcvrpp6dSqeTII4/skqIBAAAAululKIqizIHPP/98PvCBD+Stb31rLrroomXbP/WpT+W73/3uv09eqWTp6UePHp3f/va36dOnTxeUvXY1NzensbExTU1NaWho6O5yAAAAYJ1Ua8/fpUOVVbn99ttz4403ZsqUKWlsbMz++++fE088sd2itrWk1gYVAAAAalGtPX+vkVBlXVNrgwoAAAC1qNaev0uvqQIAAACwPhOqAAAAAJRQ35FG5557bpd1eNZZZ3XZuQAAAAC6S4fWVKmrq0ulUumSDltbW7vkPGtTrb3TBQAAALWo1p6/OzRTZcyYMV0WqgAAAACsCzoUqtx9991ruAwAAACA2mKhWgAAAIAShCoAAAAAJQhVAAAAAEro0JoqK7LPPvu85mMqlUp++9vflu0SAAAAoGqUDlU6unjt0q8GFUXhC0IAAADAOqN0qHL22Wevcn9TU1Meeuih3H///Rk8eHA++tGPpr6+dHcAAAAAVWWNhSpL3XvvvXnPe96Txx9/PLfcckvZ7gAAAACqyhpfqHbPPffMpZdemvHjx+c73/nOmu4OAAAAYK1YK1//ec973pOePXvmyiuvXBvdAQAAAKxxayVUqa+vT69evTJp0qS10R0AAADAGrdWQpW//OUvmTt3bnr27Lk2ugMAAABY49Z4qPKnP/0pxxxzTCqVSnbdddc13R0AAADAWlH66z/77LPPKvcvXLgwU6ZMydSpU1MURerr63PGGWeU7Q4AAACgqpQOVe6+++4Otx0xYkS+//3vZ8899yzbHQAAAEBVKR2qnH322as+cX19Bg0alO222y6777576urWyvItAAAAAGtFpSiKoruLqHbNzc1pbGxMU1NTGhoaurscAAAAWCfV2vO36SMAAAAAJQhVAAAAAEoovabKq7W2tmbSpEmZNWtWWlpaVtl2zJgxXdElAAAAQLfqVKjywgsv5Etf+lJ++ctfZuHChattX6lUsmTJks50CQAAAFAVSocqTz/9dPbcc8/MnDkzHV3r1pq4AAAAwLqi9Joqp59+el555ZUMHTo0V199daZOnZolS5akra1tlb8AAAAA1gWlZ6rcc889qVQqGTduXN72trd1ZU0AAAAAVa/0TJW2trb069dPoAIAAACsl0qHKltvvXUWL15s4VkAAABgvVQ6VPnv//7vLF68ODfeeGNX1gMAAABQE0qvqfKhD30ov/vd7/KRj3wkbW1tOeaYY7qyLgAAAICqVik6+Z3js846K1/96lczYsSIbLPNNhk2bNjKO6tUcsUVV3Smu27R3NycxsbGNDU1paGhobvLAQAAgHVSrT1/dypU+d73vpcvfelLmTt3blZ1mkqlkqIoUqlU0traWra7blNrgwoAAAC1qNaev0u//vOzn/0sn/zkJ5MkDQ0NGT16dF73utelR48eXVYcAAAAQLUqHapcdNFFSZJDDz00//d//5e+fft2WVEAAAAA1a7013+eeuqpVCqVXH755QIVAAAAYL1TeqZK//7906tXr2y44YZdWQ8AAABATSg9U2X33XdPc3NzXn755a6sBwAAAKAmlA5VzjjjjNTX1+d//ud/urIeAAAAgJpQOlTZcccd8/Of/zw33nhj9t9//9x1112ZPn16V9YGAAAAULUqRVEUZQ4s8+nkSqWSJUuWlOmuW9Xad7IBAACgFtXa83fphWpLZjEAAAAA64TSocqECRO6sg4AAACAmlI6VBk7dmxX1gEAAABQU0ovVAsAAACwPhOqAAAAAJRQ+vWfV5s6dWqeeOKJzJo1Ky0tLatse/zxx3dFlwAAAADdqlOhyh//+MeceuqpefDBBzvUvlKpCFUAAACAdULpUOWBBx7IPvvsk0WLFqUoivTu3TsbbbRRevTo0ZX1AQAAAFSl0qHKGWeckYULF2brrbfO5Zdfnt133z2VSqUrawMAAACoWqVDlT/+8Y+pVCr5+c9/nm222aYrawIAAACoeqW//tOzZ88MGDBAoAIAAACsl0qHKtttt13mz5+fBQsWdGU9AAAAADWhdKhyyimnZMmSJbniiiu6sh4AAACAmlA6VDnssMNy2mmn5bOf/Wy++tWvZv78+V1ZFwAAAEBVqxRFUXTmBBdccEG+9KUvZYMNNshmm22WYcOGrbyzSiW//e1vO9Ndt2hubk5jY2OamprS0NDQ3eUAAADAOqnWnr9Lf/0nST73uc/l4osvTpIsWrQozzzzTJ555pmVtvfJZQAAAGBdUTpU+f73v59vfetbSZItt9wy++yzT173utelR48eXVYcAAAAQLXqVKhSqVTykY98JN/97nfNQgEAAADWK6UXqv373/+eSqWSr3/96wIVAAAAYL1TeqbK4MGDM3/+/PTv378r6wEAAACoCaVnquy7775pamrK5MmTu7IeAAAAgJpQOlQ588wzM2DAgHzqU59KW1tbV9YEAAAAUPVKv/7Tq1evXHHFFTn55JPz5je/OZ/97Gez3XbbZdiwYas8buTIkWW7BAAAAKgalaIoijIHlvl0cqVSyZIlS8p0162am5vT2NiYpqamNDQ0dHc5AAAAsE6qtefv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TJgwIZVKJWPHjl1u/7hx43L00UdnyZIl2XnnnbP55pvn4Ycfzne/+93ceOONue+++7Llllsud9zf/va37LnnnpkxY0ZGjRqVQw89NM8//3zGjRuXm2++OTfccEPe8573LHfc/Pnzs//+++cPf/hDBg4cmAMOOCBz587N7373u9xzzz357Gc/m4suuug1/fzrirU19kuWLMmOO+6YJOnfv3923nnnDB06NFOmTMnEiRNz33335eqrr84dd9yRgQMHrvDcQ4cOzQEHHLDCfVtvvfUKt8+YMSN77rln/va3v2XYsGF517velenTp+e2227Lbbfdlosvvjif/OQnO/iTr1vW9nWfJFtssUX22GOPFe4bPnz4Cre77rve2hz79773vfnXv/61wuNmzpyZW2+9NUmy9957r7CN675rlRn75557LmPGjMm0adOy4YYbZq+99krfvn3z17/+NePGjcu4cePyzW9+M5/5zGeWO9b9vnqsrbF3v68ua/uaT9zrq8XaHPt16l5fQEmXX3558bnPfa645ppriqeeeqo47rjjiiTFV77ylVLn++hHP1okKfbff//l9k2dOrXo27dvkaT44Q9/uGz7kiVLimOPPbZIUuy8885FW1tbu+Pa2tqKt7zlLUWS4rjjjiuWLFmybN8Pf/jDIknRv3//4sUXX1yuz1NOOaVIUmy33XbFyy+/vGz7ww8/XPTv379IUtx6662lftZat7bGvqWlpXjrW99a3HDDDcXChQvb7fvzn/9cDBs2rEhSnHTSScudc8KECUWSYuzYsa+5nne/+91FkmLfffct5s2bt2z7+PHjix49ehR1dXXF448//prPuy5Ym9f9VVddVSQpTjjhhNd0Ttf9mrE2x35Vvv71rxdJije84Q3L7XPdrxllxv6QQw4pkhQHH3xwMXfu3Hb7ll6H9fX1xT//+c92+9zvq8vaGnv3++qyNq959/rqsjbHflVq7V4vVKHLnHDCCaX/B3vBggXFwIEDiyTF9ddfv9z+z3/+80WSYr/99ltu35w5c4rGxsYiSXH77be32zd+/PgiSTFw4MBizpw5yx277777FkmK008/vd32mTNnFr169SqSFPfdd99yx33lK18pkhSjR49+rT/qOmlNjv2q/PSnPy2SFH369CkWL17cbl/ZP3D/+te/FkmKHj16FC+88MJy+z/4wQ8WSYr3ve99r+m866o1OfZl/0fLdb92dNd1v/XWWxdJigsuuGC5fa77taMjY7/0weSPf/zjCvdvtdVWRZLipptuarfd/b66rcmxXxX3++61Jsfdvb66ddc1X2v3emuqUBV+/vOfZ/bs2Rk8eHAOPfTQ5fb/4he/SJK8//3vX25f//79c8ghhyRJbrrpphUed8ghh6R///7LHbv0fP953K9//essXrw4I0eOzO67777S4x544IFMmzZtdT8eq7C6sV+Vt7zlLUmSBQsWrHT64Gu19L+Z3XffPZtuuuly+5eO/a233rrS97vpmM6M/aq47qtf2bG///7788wzz6S+vn6Vrxa9Vq77rte7d+8Otdtoo43a/d79vvaVHftVcb+vfmti3FfFNV89unrsa/FeL1ShKlx55ZVJkmOPPTYbbLBBu31z5szJs88+myTZaaedVnj80u1/+tOf2m1f+vvVHTdp0qTMmzevw8eNGjUqgwcPTpI89thjK/6h6JBVjf3qTJo0KUnSq1evZePxn6ZPn55zzz03H/7wh3PKKafk0ksvzeTJk1d6zo7+NzNv3rxl/VNOR8f+2Wefzf/8z//kv//7v/OZz3wmV1555Sr/p9p1X/3KXvdLjzvooIOy8cYbr7Sd6777HXjggUmSc845J/Pnz2+37/LLL8+kSZOy3XbbZbfddlu23f1+3VBm7FfH/b76dXbc3etrV1df87V4r7dQLd3uhRdeyIQJE5IkH/zgB1e4f6mRI0eu8BybbLJJkuT5559vt33p71d3XFEUeeGFF/LmN7+5Q8clyYgRIzJz5szl+qTjVjf2q1IURb7xjW8kSd75zneu9MHs6aefztlnn91uW319fT75yU/mG9/4Rurr2/8xuLqxb2hoSENDQ5qbm/P8889nm222eU1182+vZezvv//+3H///e229e7dO1/+8pdz2mmnLdfedV/dyl738+bNyw033NCh41z33e/CCy/Mk08+mfHjx2fkyJEZPXr0soULn3766Rx88MG5/PLL242F+/26oczYr4r7fW3o7Li719eurrzma/Veb6YK3e6qq65KURTZaaedsv322y+3f86cOcv+uV+/fis8x9Jpf83NzSs8dnXH/eexqztuVX3Scasb+1U555xzMnHixPTv3z8XXHDBcvsbGxtz6qmn5p577smLL76YefPm5c9//nM+/elPp1Kp5H//93/zsY99bLnjjP3a0ZGx33jjjXPGGWfkwQcfzMsvv5zm5uY89NBDOf7447No0aKcfvrpOf/885c7znVf3cpe9zfccEPmzp2bjTfeOAcddNAK27juq8fQoUNz991359hjj80rr7yS8ePH58Ybb8yTTz6Z4cOHZ5999smQIUPaHeN+v24oM/ar4n5fG8qOu3t97evKa75W7/VCFbpVW1tbfvzjHydJPvCBD3RvMaxVnRn7q6++Oueee27q6upy5ZVXZquttlquzVve8pb87//+b8aMGZONN944ffv2zXbbbZdvfetbuf7665P8e0qiqZ1rX0fH/oADDsh5552XXXbZJRtttFEGDBiQnXbaKT/5yU+Wferw3HPPzfTp09dG2XSBzlz3V1xxRZLk+OOPX+nfdrnuq8fTTz+dt7zlLbn11lvz/e9/P//85z/T1NSUu+++O0OHDs1nP/vZHHTQQWltbe3uUuliXTn27ve1o+y4u9fXvq685mv1Xi9UoVvdddddmTx5cvr06bPCRemSZMCAAcv++dXvRL7a3Llzk/x72taKjl3dcf957OqOW1WfdExHxn5FbrzxxmUPY5dffnmOOOKI19z3YYcdlh122CHJvxejejVjv+aVHftXO+WUU7LRRhtl0aJF+c1vftNun+u+epUd+7/97W/LpoWXDeBd92vPkiVLcvjhh+fZZ5/N5Zdfno9+9KMZMWJEGhoaMnbs2PzmN7/JxhtvnDvvvDNXX331suPc72tf2bFfEff72tGV4/5q7vXVryvHvpbv9UIVutXShYgOP/zwNDY2rrDNq1dnXtniQ//85z+TJJtttlm77Ut/v7rjKpVKu35Wd1ySTJkyZYV90jEdGfv/dNNNN+X9739/2tra8sMf/rBTs5ve9KY3Jfl/47jU6sa+ubl52ZRAY19OmbH/Tz169Fj2N5avdQxd992n7NgvPW6PPfbI1ltvXbp/1/3a8eCDD+bJJ5/MBhtskMMOO2y5/YMGDVq2sOFdd921bLv7fe0rO/b/yf2+tnTVuP8n9/rq15VjX8v3eqEK3WbmzJm5+eabk6x6IaKGhoZsueWWSZKHH354hW2Wbt9xxx3bbV/6+9Udt9VWW7V793J1x/3973/PzJkzk/y/z/zRcR0d+1e7+eab8773vS+tra259NJLc/LJJ3eqhldeeSVJ+78ZTTr+30y/fv3yhje8oVM1rI/KjP3KdHYMXfdrV9mxb21tXfa3W93934zrvmOW/g9r375906NHjxW2WRqqLb2mEvf7dUHZsX819/va0xXjvjLu9dWtq8a+1u/1QhW6zTXXXJNFixZliy22yNixY1fZ9j3veU+S5Nprr11u39y5c5dN7/rPhHTpcbfccssKp3otPd9/HnfQQQelV69emTx58nIrkb/6uNGjR+f1r3/9Kmtnea9l7JN/T9878sgjs2TJklx66aX58Ic/3Kn+p06dmnvvvTdJsssuu7Tbd+ihhyb59yr0K0qyl479u971rvTs2bNTdayPXuvYr8yjjz6av/3tb0mWH0PXfXUqO/a//vWv8+KLL2bAgAGlpv8v5bpfe4YPH54kmTVr1ko/S/nggw8mSTbffPN2293va1tnxj5xv69VnR33lXGvr35dNfY1f68voIuccMIJRZLiK1/5Sofa77DDDkWS4qtf/epq206dOrXo27dvkaS47LLLlm1fsmRJcdxxxxVJip133rloa2trd1xbW1vxlre8pUhSHH/88cWSJUuW7fvhD39YJCn69+9fvPjii8v1ecoppxRJiu23377417/+tWz7I488UvTv379IUtx6660d+lnXdWty7MePH1/06tWrqFQqxQ9/+MMO1/Ttb3+7ePnll5fb/vjjjy/7b2KLLbYoFi5cuFybd7/73UWSYr/99ivmz5+/bPuvf/3rokePHkVdXV3x+OOPd7iWddmaGvt58+YV3/3ud4vm5ubl9t1zzz3FZpttViQp9thjj+X2u+7XjjV53b/aoYceWiQpTj755NW2dd2vHasb+8WLFxfDhw8vkhRjxowpZsyYsWxfa2tr8bWvfa1IUiQpfv/737c71v2+uq3JsXe/r15ratzd66vfmrzmX63W7/VCFUp75JFHil133XXZr4022qhIUowYMaLd9mnTpi137KOPPlokKXr06FFMnTq1Q/3dcMMNRY8ePYokxa677locddRRxahRo4okxdChQ4tJkyat8Linn366GDJkSJGkGDVqVHHUUUcVu+yyS5GkqK+vL2666aYVHjdv3rxit912K5IUgwYNKg4//PDigAMOKHr27FkkKT7zmc90/F/WOmZtjf306dOLDTbYYNm5TzjhhJX++s8/XBsbG4sePXoUb33rW4v3vve9xZFHHlm89a1vLerq6ookxciRI4snn3xypf1utdVWRZJi2LBhxZFHHlnstddeRaVSKZIUF198cfl/eTVubY39rFmziiTFBhtsUIwePbo48sgji8MOO6zYdtttl92ct9tuuxX2UxSu+zVhbf+ZXxT/vhaX/rt/4IEHVtvedb9mlBn73/72t8vCkYaGhmL//fcvDjvssGKLLbZYdg1/6UtfWmF/7vfVY22Nvft9dVlb4+5eX33W9p/3RbFu3OuFKpQ2YcKEZRfKqn49//zzyx37iU98okhSHHTQQa+pz4cffrg47LDDiiFDhhS9evUqNt100+LjH/948dJLL63yuBdffLH4+Mc/Xmy66aZFr169iiFDhhSHHXZY8cgjj6zyuEWLFhVf+9rXim233bbo06dP0djYWIwZM6a44YYbXlPd65q1NfbPP/98h/pZUV/f+MY3ine/+93FlltuWTQ2Nhb19fXF4MGDiz322KO48MILV/i3Iq/W1NRUnH766cVWW21VbLDBBsXgwYOLAw44oLjrrrtey7+qdc7aGvtFixYVZ555ZnHggQcWm2++eTFgwICivr6+GDJkSLHffvsVP/zhD4tFixat8hyu+67VHX/mX3TRRUWS4s1vfnOH2rvu14yyY//cc88VH//4x4s3vvGNRZ8+fYqePXsWr3/964v3vOc9xW9+85tV9ul+Xx3W1ti731eXtTXu7vXVpzv+vF8X7vWVoiiKAAAAAPCaWKgWAAAAoAShCgAAAEAJQhUAAACAEoQqAAAAACUIVQAAAABKEKoAAAAAlCBUAQAAAChBqAIAAABQglAFAAAAoAShCgBQ9b785S+nUqlkr7326u5SAACWqe/uAgCAdV+lUil9bFEUXVgJAEDXEaoAAGvc0KFDV7i9qakpCxcuTM+ePTN48OCVHr/RRhtl6623zsiRI9dUiQAAr1ml8Nc/AEA3OfHEE/OTn/wkY8eOzd13393d5QAAvCbWVAEAAAAoQagCAFS9VS1Uu9dee6VSqeTLX/5yWlpacsEFF2TbbbdN3759M3z48HzoQx/Kiy++uKz9s88+mw984APZZJNN0rt372y99da56KKL0tbWtsoaHnnkkZxwwgnZbLPN0rt37zQ2Nmb06NH59re/nYULF3b1jwwA1ABrqgAA64SWlpa8/e1vz913353evXsnSaZNm5Yrrrgiv//97zNx4sRMmjQpBx54YGbPnp3GxsYsXrw4f/vb3/L5z38+U6ZMybe//e0Vnvucc87JOeecs2zR3AEDBmTevHl58MEH8+CDD+anP/1p7rjjjmy00UZr68cFAKqAmSoAwDrh+9//fp5++un86le/yrx58zJ37tzcfPPNGTBgQCZNmpSzzjorRx11VPbYY48899xzmT17dmbPnp2PfOQjSZJLLrkkTz311HLnvfTSS/PlL385gwcPzne+85288soraW5uzvz583Pbbbdlq622yqOPPpoTTzxxLf/EAEB3E6oAAOuE2bNn5/rrr8/BBx+curq69OjRI+9+97vz+c9/Psm/Q5fevXvnF7/4RUaNGpUkaWhoyPe+971sueWWKYoi48aNa3fO5ubmnH766enZs2d+/etf5xOf+MSyrxT16tUrBxxwQG677bb07ds348ePz6OPPrp2f2gAoFsJVQCAdcJuu+2WsWPHLrd9v/32W/bPn/vc51Jf3/7t57q6uuy9995JkieeeKLdvnHjxqW5uTljxozJLrvsssJ+t9hii4wePTpJ8pvf/KZTPwMAUFusqQIArBO22267FW5/3etet+yft9122xW2GTp0aJJk1qxZ7bb/4Q9/SJJMnDgxG2+88Ur7bmpqSpJMnjy54wUDADVPqAIArBOGDRu2wu09evTocJuWlpZ225d+NWj+/PmZP3/+amvoSBsAYN0hVAEAWInW1tYkyYc//OH84Ac/6OZqAIBqY00VAICVWPpakNd6AIAVEaoAAKzE2972tiTJvffem+bm5m6uBgCoNkIVAICVOOKIIzJgwIDMnTs3X/ziF1fZdt68eVm8ePFaqgwAqAZCFQCAlRg8eHC+8Y1vJEm+//3v5+ijj2732eWWlpY8+uijOfPMMzNq1KjMmDGju0oFALqBhWoBAFbhIx/5SObNm5fTTjst119/fa6//vr06dMnffr0SVNT07LFbJOkUql0Y6UAwNpmpgoAwGp89rOfzZNPPplPfvKT2WabbdKjR480Nzdnww03zJgxY/I///M/efzxxzN8+PDuLhUAWIsqRVEU3V0EAAAAQK0xUwUAAACgBKEKAAAAQAlCFQAAAIAShCoAAAAAJQhVAAAAAEoQqgAAAACUIFQBAAAAKEGoAgAAAFCCUAUAAACgBKEKAAAAQAlCFQAAAIAShCoAAAAAJQhVAAAAAEr4/wAs2gnIeTvU6QAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# http://localhost:9090/api/v1/query_range?query=optical_security_active_services&start=1670203354&end=1670217754&step=57\n", + "# http://localhost:9090/api/v1/query_range?query=optical_security_active_services&start=1670202754&end=1670217754&step=60\n", + "\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": f\"optical_security_active_services\",\n", + " # \"start\": 1675008354,\n", + " # \"end\": 1675025454,\n", + " \"start\": start_experiment,\n", + " \"end\": end_experiment,\n", + " \"step\": 68,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_services = response.json()\n", + "\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": f\"optical_security_dropped_assessments_total\",\n", + " # \"start\": 1670202754,\n", + " # \"end\": 1670217754,\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 16, 9, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 15, 0).timetuple()),\n", + " \"step\" :60,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_dropped = response.json()\n", + "\n", + "print(\"results values:\", parsed_services)\n", + "\n", + "initial_timestamp = parsed_services[\"data\"][\"result\"][3][\"values\"][0][0]\n", + "initial_datetime = datetime.datetime.fromtimestamp(initial_timestamp)\n", + "\n", + "x_values = []\n", + "y_values_active_services = []\n", + "y_values_dropped_services = []\n", + "\n", + "for value_services in parsed_services[\"data\"][\"result\"][3][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds())\n", + " # x_values.append(time.gmtime(value_services[0]))\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " y_values_active_services.append(value_services[1])\n", + "\n", + " # uncomment to check timestamps\n", + " # print(time.gmtime(float(value_services[0])), float(value_services[1]))\n", + " print(float(value_services[0]), float(value_services[1]))\n", + "\n", + "plt.figure()\n", + "plt.plot(x_values, y_values_active_services, label=r\"$L=30$\", ls=\"--\")\n", + "\n", + "x_values = []\n", + "y_values_active_services = []\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": f\"optical_security_active_services\",\n", + " # \"start\": 1675008354,\n", + " # \"end\": 1675025454,\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 21, 20, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 59, 0).timetuple()),\n", + " \"step\": 68,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_services = response.json()\n", + "for value_services in parsed_services[\"data\"][\"result\"][0][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds()-550)\n", + " # x_values.append(time.gmtime(value_services[0]))\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " x = value_services[1]\n", + " if float(x) == 1921.:\n", + " x = 1920\n", + " y_values_active_services.append(x)\n", + "\n", + " # uncomment to check timestamps\n", + " # print(time.gmtime(float(value_services[0])), float(value_services[1]))\n", + " print(float(value_services[0]), float(value_services[1]))\n", + "\n", + "plt.plot(x_values, y_values_active_services, label=r\"$L=60$\", ls=\":\", linewidth=2.5)\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Current active services\")\n", + "plt.legend(loc=2)\n", + "plt.tick_params(axis=\"x\", rotation=90)\n", + "# plt.grid()\n", + "# plt.ticklabel_format(style=\"plain\")\n", + "# plt.gca().set_xticklabels(rotation=90)\n", + "\n", + "plt.show()\n", + "plt.close()\n", + "\n", + "x_values = []\n", + "for value_dropped in parsed_dropped[\"data\"][\"result\"][0][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds())\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " y_values_dropped_services.append(value_dropped[1])\n", + "\n", + " # uncomment to check timestamps\n", + " # print(y_values_dropped_services[-1], float(value_services[0]))\n", + "\n", + "plt.figure()\n", + "plt.plot(x_values, y_values_dropped_services)\n", + "\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Cummulative dropped assessments\")\n", + "plt.show()\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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LZqkEUIIIYQQy1CS5oZWr16NYcOGISAgAF5eXujRowc++OADaDQaZzeNNMPs2bPBMEyT/2pL2dR37Ngx3HPPPQgLC4NYLEb79u3x9NNP48aNG01us6SkBE899RTat28PDw8PhIWF4Z577sHx48ebXE+tVuP9999Hjx494OXlhYCAAAwbNgxr1qyxev+JwcWLF/HFF19g9uzZ6NatGwQCARiGwTvvvGN23R07dmDChAkIDg6GRCJB586dsWjRIlRXVze53pUrVzB79mxER0fDw8MD0dHRmD17Nq5du9bkelVVVVi4cCESExMhkUgQHByMiRMnYteuXU2up9frsWzZMvTv3x8+Pj7w8fFB//798d1339EVFgtYEyOLFy82e3y5cOFCo+tTjLgItgWUlpayDMOwPB6vJTbXqj377LMsAFYgELBjxoxh7777btbf358FwA4ZMoSVy+XObiKx0EMPPcQCYAcPHsw+9NBDJv+p1eoG661evZoVCAQsALZv377svffey8bHx7MA2LCwMPby5csmt3fx4kU2NDSUBcDGx8ez9957L9u3b18unv766y+T69XU1LCDBg1iAbD+/v7s3XffzY4ZM4Zrw7x58+z6vrQ1tX/T9f+9/fbbTa738ccfswBYhmHYoUOHsvfccw8bHh7OAmATExPZmzdvmlxv//79rKenJwuATUpKYqdPn84mJSWxAFgvLy/24MGDJtcrKSlhO3XqxAJgIyIi2HvuuYcdOnQoyzAMyzAM+/nnn5tcT6vVsnfffTcLgPX09GTvuOMO9o477mAlEgkLgL3nnntYnU7XvDetjbEmRt544w0WANujR49Gjy+FhYUm16UYcR2UpLmRdevWsQBYb29v9tixY9zjN2/eZLt160ZfmG6mNkn74YcfLF6noKCAO3guW7aMe1yr1bIPPPAAl7jp9Xqj9fR6PdurVy8WAPvggw+yWq2We27ZsmVcXBUVFTXYZu0XRLdu3Yy++DMzM1lvb28WALtx48Zm7Dmpa/ny5eyLL77I/t///R97/vx59sEHHzT7BXz8+HGWYRiWz+ezmzdv5h6vqalhR44cyQJgp06d2mC9mpoaNjIykgXALliwwOi5BQsWsADYmJgYkz/2pkyZwgJgR44cydbU1HCPb9q0ieXz+SyPx2OzsrIarPfJJ5+wANioqCj22rVr3OPXrl3j2vLF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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# http://localhost:9090/api/v1/query_range?query=optical_security_active_services&start=1670203354&end=1670217754&step=57\n", + "# http://localhost:9090/api/v1/query_range?query=optical_security_active_services&start=1670202754&end=1670217754&step=60\n", + "\n", + "query = \"rate(optical_security_loop_seconds_sum[5m]) / rate(optical_security_loop_seconds_count[5m])\"\n", + "\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": query,\n", + " # \"start\": 1675008354,\n", + " # \"end\": 1675025454,\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 16, 9, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 15, 0).timetuple()),\n", + " \"step\": 68,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_services = response.json()\n", + "\n", + "# print(\"results values:\", parsed_services)\n", + "\n", + "initial_timestamp = parsed_services[\"data\"][\"result\"][3][\"values\"][0][0]\n", + "initial_datetime = datetime.datetime.fromtimestamp(initial_timestamp)\n", + "\n", + "x_values = []\n", + "y_values_active_services = []\n", + "\n", + "for value_services in parsed_services[\"data\"][\"result\"][3][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds())\n", + " # x_values.append(time.gmtime(value_services[0]))\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " y_values_active_services.append(float(value_services[1]))\n", + "\n", + " # uncomment to check timestamps\n", + " # print(time.gmtime(float(value_services[0])), float(value_services[1]))\n", + " # print(float(value_services[0]), float(value_services[1]))\n", + "\n", + "plt.figure(figsize=(6.4, 3.6))\n", + "# plt.plot(x_values, y_values_active_services, label=r\"$L=30$\", ls=\"--\")\n", + "\n", + "# x_values = []\n", + "# y_values_active_services = []\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": query,\n", + " # \"start\": 1675008354,\n", + " # \"end\": 1675025454,\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 21, 25, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 59, 0).timetuple()),\n", + " \"step\": 68,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_services = response.json()\n", + "for value_services in parsed_services[\"data\"][\"result\"][0][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds()-550)\n", + " # x_values.append(time.gmtime(value_services[0]))\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " y_values_active_services.append(float(value_services[1]))\n", + "\n", + " # uncomment to check timestamps\n", + " # print(time.gmtime(float(value_services[0])), float(value_services[1]))\n", + " # print(float(value_services[0]), float(value_services[1]))\n", + "\n", + "# print(x_values, y_values_active_services)\n", + "plt.plot(x_values, y_values_active_services, label=r\"$L=60$\", ls=\":\", linewidth=2.5)\n", + "\n", + "plt.text(13800, 10, r\"$p=30$\", rotation=90, verticalalignment=\"center\", horizontalalignment=\"center\")\n", + "plt.text(16200, 10, r\"$p=60$\", rotation=90, verticalalignment=\"center\", horizontalalignment=\"center\")\n", + "\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Loop completion time [s]\")\n", + "# plt.legend(loc=2)\n", + "# plt.tick_params(axis=\"x\", rotation=90)\n", + "# plt.grid()\n", + "# plt.ticklabel_format(style=\"plain\")\n", + "# plt.gca().set_xticklabels(rotation=90)\n", + "plt.grid(axis=\"both\", ls=\":\")\n", + "plt.tight_layout()\n", + "\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"loop_completion_time.pdf\"))\n", + "\n", + "plt.show()\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# http://localhost:9090/api/v1/query_range?query=optical_security_active_services&start=1670203354&end=1670217754&step=57\n", + "# http://localhost:9090/api/v1/query_range?query=optical_security_active_services&start=1670202754&end=1670217754&step=60\n", + "\n", + "query = \"optical_security_number_workers\"\n", + "\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": query,\n", + " # \"start\": 1675008354,\n", + " # \"end\": 1675025454,\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 16, 9, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 15, 0).timetuple()),\n", + " \"step\": 68,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_services = response.json()\n", + "\n", + "# print(\"results values:\", parsed_services)\n", + "\n", + "initial_timestamp = parsed_services[\"data\"][\"result\"][3][\"values\"][0][0]\n", + "initial_datetime = datetime.datetime.fromtimestamp(initial_timestamp)\n", + "\n", + "x_values = []\n", + "y_values_active_services = []\n", + "\n", + "for value_services in parsed_services[\"data\"][\"result\"][3][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds())\n", + " # x_values.append(time.gmtime(value_services[0]))\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " y_values_active_services.append(float(value_services[1]))\n", + "\n", + " # uncomment to check timestamps\n", + " # print(time.gmtime(float(value_services[0])), float(value_services[1]))\n", + " # print(float(value_services[0]), float(value_services[1]))\n", + "\n", + "plt.figure(figsize=(6.4, 3.6))\n", + "# plt.plot(x_values, y_values_active_services, label=r\"$L=30$\", ls=\"--\")\n", + "\n", + "# x_values = []\n", + "# y_values_active_services = []\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": query,\n", + " # \"start\": 1675008354,\n", + " # \"end\": 1675025454,\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 21, 25, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 59, 0).timetuple()),\n", + " \"step\": 68,\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "parsed_services = response.json()\n", + "for value_services in parsed_services[\"data\"][\"result\"][0][\"values\"]:\n", + " parsed_date = datetime.datetime.fromtimestamp(value_services[0])\n", + " x_values.append((parsed_date - initial_datetime).total_seconds()-550)\n", + " # x_values.append(time.gmtime(value_services[0]))\n", + " # x_values.append(float(value_services[0]))\n", + "\n", + " y_values_active_services.append(float(value_services[1]))\n", + "\n", + " # uncomment to check timestamps\n", + " # print(time.gmtime(float(value_services[0])), float(value_services[1]))\n", + " # print(float(value_services[0]), float(value_services[1]))\n", + "\n", + "# print(x_values, y_values_active_services)\n", + "plt.plot(x_values, y_values_active_services, label=r\"$L=60$\", ls=\":\", linewidth=2.5)\n", + "\n", + "plt.text(14100, 6, r\"$p=30$\", rotation=90, verticalalignment=\"center\", horizontalalignment=\"center\")\n", + "plt.text(16200, 6, r\"$p=60$\", rotation=90, verticalalignment=\"center\", horizontalalignment=\"center\")\n", + "\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Number of threads\")\n", + "# plt.legend(loc=2)\n", + "# plt.tick_params(axis=\"x\", rotation=90)\n", + "# plt.grid()\n", + "# plt.ticklabel_format(style=\"plain\")\n", + "# plt.gca().set_xticklabels(rotation=90)\n", + "plt.grid(axis=\"both\", ls=\":\")\n", + "plt.tight_layout()\n", + "\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"number_threads_manager.pdf\"))\n", + "\n", + "plt.show()\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "cur_duration = \"[5m]\"\n", + "loads = [120, 240, 480, 960, 1440, 1920, 1920]\n", + "times_services = (\n", + " (1675009360.0, 1675010788.0), # 120\n", + " (1675011808.0, 1675013168.0), # 240\n", + " (1675014188.0, 1675015548.0), # 480\n", + " (1675016568.0, 1675017996.0), # 960\n", + " (1675019016.0, 1675020376.0), # 1440\n", + " (1675021396.0, 1675022756.0), # 1920\n", + " (1675024076.0, 1675025164.0), # 1921\n", + ")\n", + "\n", + "# response = requests.get(\n", + "# f\"{prometheus_endpoint}/api/v1/query\",\n", + "# params={\n", + "# \"query\": f\"rate(optical_security_loop_seconds_sum{cur_duration}) / rate(optical_security_loop_seconds_count{cur_duration})\",\n", + "# # \"time\": time.mktime(yesterday.timetuple())\n", + "# # \"range_input\": \"1h\",\n", + "# }\n", + "# )\n", + "# print(response.content)\n", + "# parsed = response.json()\n", + "\n", + "# print(\"results values:\", parsed[\"data\"][\"result\"])\n", + "\n", + "# initial_timestamp = parsed[\"data\"][\"result\"][0][\"value\"][0]\n", + "# initial_datetime = datetime.datetime.fromtimestamp(initial_timestamp)\n", + "\n", + "\n", + "# x_values = []\n", + "# y_values = []\n", + "\n", + "# for series in parsed[\"data\"][\"result\"]:\n", + "# for value in series[\"value\"]:\n", + "# parsed_date = datetime.datetime.fromtimestamp(value)\n", + "# x_values.append((parsed_date - initial_datetime).total_seconds())\n", + "\n", + "# y_values.append(value_services[" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "inf", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [24], line 74\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[39m# if i == 0 and prom_metric == \"optical_security_loop_seconds_bucket\":\u001b[39;00m\n\u001b[1;32m 58\u001b[0m \u001b[39m# diff = np.mean(cdf[load][key])\u001b[39;00m\n\u001b[1;32m 59\u001b[0m \u001b[39m# print(i, key)\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[39m# and prom_metric != \"optical_security_loop_seconds_bucket\":\u001b[39;00m\n\u001b[1;32m 70\u001b[0m \u001b[39m# max_x = i - 1\u001b[39;00m\n\u001b[1;32m 72\u001b[0m i \u001b[39m+\u001b[39m\u001b[39m=\u001b[39m \u001b[39m1\u001b[39m\n\u001b[0;32m---> 74\u001b[0m probabilities[i\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m] \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mmean(cdf[load][\u001b[39mfloat\u001b[39;49m(\u001b[39m'\u001b[39;49m\u001b[39mInf\u001b[39;49m\u001b[39m'\u001b[39;49m)])\n\u001b[1;32m 76\u001b[0m probabilities \u001b[39m=\u001b[39m probabilities \u001b[39m/\u001b[39m probabilities\u001b[39m.\u001b[39mmax()\n\u001b[1;32m 78\u001b[0m \u001b[39mif\u001b[39;00m load \u001b[39m==\u001b[39m \u001b[39m480\u001b[39m:\n", + "\u001b[0;31mKeyError\u001b[0m: inf" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABD0AAALqCAYAAAA2Hy/VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA6uUlEQVR4nO3df7TVdZ3v8ddRfp8jCpHQCAqWF8ZgXCKYATkIzowxLTMVbjI10g9LrdB+uDBnuSZ/LGVc1gxqmtM1p7o5ICkUyUiiLYvwByC360wOmWICaQklPz2I+L1/zD1nPJ6Dnp8gHx6PtVzrnP397s/+7LV6dzjPs/d311RVVQUAAACgMAft6w0AAAAAdAXRAwAAACiS6AEAAAAUSfQAAAAAiiR6AAAAAEUSPQAAAIAiiR4AAABAkUQPAAAAoEiiBwAAAFCkdkWPNWvW5MYbb8yMGTMyatSodOvWLTU1Nbn66qs7tJmlS5dmypQpGTBgQHr37p0RI0bk7/7u77Jt27YOrQsAAAAceLq150633HJL5syZ06kb+cd//Md84QtfSE1NTd73vvdl4MCB+dnPfpZrrrkmd911V5YtW5YBAwZ06mMCAAAA5WrXKz1GjhyZL33pS/ne976XJ554Ih/96Ec7tInVq1fni1/8Yg4++ODcc889efDBB3PnnXfmqaeeyuTJk7NmzZqcf/75HXoMAAAA4MDSrld6fPKTn2zy/UEHdezSINdee22qqsrHPvaxvP/972+8vU+fPrntttty9NFH56677sp//ud/ZsSIER16LAAAAODAsM8vZPryyy/nnnvuSZJMnz692fGjjjoq48ePT5IsWLBgr+4NAAAA2H/t8+jxq1/9Kjt27EiSjBkzpsVzGm5fvXr1XtsXAAAAsH9r19tbOtPatWuTJIcddlgOOeSQFs8ZMmRIk3M7av369c1uGzx4cKesDQAAALw17PPosXXr1iRJbW3tHs+pq6tLkmzZsqVTHrMhorzWunXrcsghh6SmpqZTHgMAAABoqqqqbN26NX/yJ3/S4euDtsY+jx5vFS2FEAAAAKDzrVu3bq+842KfR4+Gt7Rs3759j+ds27YtSdK3b99Oecx169Y1+X7Lli1597vfnccffzxvf/vbO+UxYH9WX1+f5cuXJ0nGjRuXXr167eMdwVuD2YDmzAW0zGxAc/X19Vm6dGk++clP7vHyFp1tn0ePoUOHJklefPHFbN26tcUn3hApGs7tqNfXpIa3zbz97W/PwIEDO+UxYH/20ksvpU+fPkmSww8/PL17997HO4K3BrMBzZkLaJnZgOZeOxd769IS+/zTW4YPH974pFeuXNniOQ23jx49eq/tCwAAANi/7fPo0aNHj/z1X/91kuSOO+5odvw3v/lN48vCPvShD+3VvQEAAAD7r70WPW666aaMGDEif/u3f9vs2KWXXpqamprcfvvtuffeextv37FjRz7xiU9k9+7dOeusszJixIi9tV0AAABgP9eua3o89thjufDCCxu/f+qpp5Ikt956a370ox813r5gwYK84x3vSJJs3Lgxa9asyaBBg5qtN3r06Hz1q1/NF77whUyZMiV//ud/nsMPPzw/+9nP8txzz2X48OH5xje+0Z6tAgAAAAeodkWPLVu25JFHHml2+/r167N+/frG73fu3NnqNT//+c9n1KhR+epXv5pHH30027dvz5FHHpkvf/nL+fKXv7zXruwKAAAAlKFd0WPixImpqqpN9/nKV76Sr3zlK294zqmnnppTTz21PVsCAAAAaGKfX8gUAAAAoCuIHgAAAECRRA8AAACgSKIHAAAAUCTRAwAAACiS6AEAAAAUSfQAAAAAiiR6AAAAAEUSPQAAAIAiiR4AAABAkUQPAAAAoEiiBwAAAFAk0QMAAAAokugBAAAAFEn0AAAAAIokegAAAABFEj0AAACAIokeAAAAQJFEDwAAAKBIogcAAABQJNEDAAAAKJLoAQAAABRJ9AAAAACKJHoAAAAARRI9AAAAgCKJHgAAAECRRA8AAACgSKIHAAAAUCTRAwAAACiS6AEAAAAUSfQAAAAAiiR6AAAAAEUSPQAAAIAiiR4AAABAkUQPAAAAoEiiBwAAAFAk0QMAAAAokugBAAAAFEn0AAAAAIokegAAAABFEj0AAACAIokeAAAAQJFEDwAAAKBIogcAAABQJNEDAAAAKJLoAQAAABRJ9AAAAACKJHoAAAAARRI9AAAAgCKJHgAAAECRRA8AAACgSKIHAAAAUCTRAwAAACiS6AEAAAAUSfQAAAAAiiR6AAAAAEUSPQAAAIAiiR4AAABAkUQPAAAAoEiiBwAAAFAk0QMAAAAokugBAAAAFEn0AAAAAIokegAAAABFEj0AAACAIokeAAAAQJFEDwAAAKBI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JNEDAAAAKJLoAQAAABRJ9AAAAACKJHoAAAAARRI9AAAAgCKJHgAAAECRRA8AAACgSKIHAAAAUCTRAwAAACiS6AEAAAAUSfQAAAAAiiR6AAAAAEUSPQAAAIAiiR4AAABAkUQPAAAAoEiiBwAAAFAk0QMAAAAokugBAAAAFEn0AAAAAIokegAAAABFEj0AAACAIokeAAAAQJFEDwAAAKBIogcAAABQJNEDAAAAKJLoAQAAABRJ9AAAAACKJHoAAAAARRI9AAAAgCKJHgAAAECRRA8AAACgSKIHAAAAUCTRAwAAACiS6AEAAAAUSfQAAAAAiiR6AAAAAEUSPQAAAIAiiR4AAABAkUQPAAAAoEgdih7z58/PxIkT069fv9TW1ua4447Lddddl127drVpndWrV+faa6/N5MmTM3DgwHTv3j39+vXL+973vnz9619v83oAAAAA3dp7x4svvjhz5sxJt27dMmnSpNTV1eWBBx7IrFmzsmjRovz4xz9O796933SdV155JaNHj06S1NXVZezYsRk4cGDWr1+fhx56KMuWLct3vvOdLFmyJIcddlh7twsAAAAcYNr1So+FCxdmzpw5qauryyOPPJIlS5bkrrvuypNPPplRo0Zl2bJlufzyy1u93gknnJA777wzGzduzAMPPJB//dd/zc9+9rOsXr0673jHO/Loo4/mC1/4Qnu2CgAAAByg2hU9rrnmmiTJpZde2vgqjSQZMGBAbr755iTJTTfdlM2bN7/pWt26dcvKlSszderU9OzZs8mxUaNG5brrrkuSzJ0719tcAAAAgFZrc/TYsGFDVqxYkSSZPn16s+MTJkzIkCFDsnPnzixevLjDGzz++OOTJC+99FI2btzY4fUAAACAA0Obo8fq1auTJP3798+wYcNaPGfMmDFNzu2IJ598MknSo0eP9O/fv8PrAQAAAAeGNl/IdO3atUmSI488co/nDBkypMm57VVVVePbWz7wgQ80e/tLe61fv77J91u3bk2S1NfX56WXXuqUx4D9WX19fYtfw4HObEBz5gJaZjaguX0xC22OHg2BoLa2do/n1NXVJUm2bNnSzm39lyuuuCIPPfRQ6urqMnv27A6t9VoNUeb1li9fnj59+nTa40AJfvrTn+7rLcBbktmA5swFtMxswL7TrguZ7g3f+c53cuWVV+aggw7Kt771rRxzzDH7eksA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008/PUly9913t2WrAAAAwAGuTdFj9erVSZL+/ftn2LBhLZ4zZsyYJue+ka1btzZer6Phfh1ZDwAAAKBBt7acvHbt2iTJkUceucdzhgwZ0uTcN/LMM880fr2nNduyXmutX7++yfdbt25NktTX17f5IqxQovr6+ha/hgOd2YDmzAW0zGxAc/tiFtoUPRriQG1t7R7PqaurS5Js2bKl1eu90ZptWa+1GkLK6y1dujR9+vTptMeBEtx77737egvwlmQ2oDlzAS0zG/DfduzYkSR77cNK2hQ9SvfJT35yX28BAAAAiverX/0qY8eO7fLHaVP0OOSQQ5Ik27dv3+M527ZtS5L07du31es1rHnooYd2aL3WWrduXePXzz33XE488cQkyX/8x39k8ODBnfY4sL/asGFDjj322CTJL3/5yxxxxBH7eEfw1mA2oDlzAS0zG9Dca+di4MCBe+Ux2xQ9hg4dmqRpNHi9hmMN576Ro446qvHrZ599NqNGjerQeq21p7DRt2/fTo0rsL967dvJDjnkEHMB/5/ZgObMBbTMbEBzr52Lgw5q0+eqtFubHuX4449PkmzatGmPFxZduXJlkmT06NFvul7fvn3zrne9q8n9OrIeAAAAQIM2RY/Bgwc3vufmjjvuaHZ82bJlWbduXXr27JkpU6a0as0PfehDe1xv27ZtWbRoUZLkzDPPbMtWAQAAgANcTdXGS6YuXLgwH/rQh1JXV5cHH3yw8RUYmzZtyimnnJLHH388X/ziF3P99dc33mfBggX58pe/nCOOOCL3339/k/V++9vf5phjjsmOHTvyz//8zznvvPOSJLt3787HPvaxfPe7383YsWPzyCOPpKampqPPFwAAADhAtDl6JMlFF12UG264Id27d8/kyZNTW1ub+++/Py+++GLGjx+f++67L7179248/1/+5V/ysY99LEcddVSeeeaZZuvNnz8/55xzTnbv3p33vOc9GTp0aFasWJGnn346AwcOzLJlyxrfBgMAAADQGu26csicOXMyb968vPe9783y5cuzePHiDB48OLNnz84DDzzQJHi0xtSpU/PII4/kzDPPzNNPP50FCxZk9+7d+cxnPpNf/OIXggcAAADQZu16pQcAAADAW93e+YwYAAAAgL1M9AAAAACKJHoAAAAARRI9AAAAgCKJHgAAAECRRA8AAACgSKIHAAAAUCTR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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "yesterday = datetime.date.today() # - datetime.timedelta(days=1)\n", + "duration = '[' + str(yesterday.day) + 'd]'\n", + "\n", + "metrics = (\n", + " # \"optical_security_loop_seconds_bucket\",\n", + " \"DbscanServing_Detect_histogram_duration_bucket\",\n", + " # \"OpticalAttackDetector_DetectAttack_histogram_duration_bucket\",\n", + " # \"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_histogram_duration_bucket\",\n", + " # \"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_histogram_duration_bucket\",\n", + ")\n", + "\n", + "curves_specific_load = {}\n", + "\n", + "for prom_metric in metrics:\n", + " response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query\",\n", + " params={\n", + " \"query\": f\"{prom_metric}{duration}\",\n", + " \"range_input\": \"4h10m\",\n", + " \"end_input\": \"2022-12-05 05:22:34\",\n", + " }\n", + " )\n", + "\n", + " parsed = response.json()\n", + "\n", + " cdf = {}\n", + " for load in loads:\n", + " cdf[load] = {}\n", + " \n", + " for metric in parsed[\"data\"][\"result\"]:\n", + " for load, _time in zip(loads, times_services):\n", + " if float(metric[\"metric\"][\"le\"]) not in cdf[load]:\n", + " cdf[load][float(metric[\"metric\"][\"le\"])] = []\n", + " # print(metric[\"metric\"])\n", + " for value in metric[\"values\"]:\n", + " # if _time[0] < value[0] and value[0] < _time[1]:\n", + " # print(load, metric[\"metric\"][\"le\"], value)\n", + " cdf[load][float(metric[\"metric\"][\"le\"])].append(float(value[1]))\n", + " # break # stops the loop over values when the first one is found\n", + " # print(\"\\tmetric:\", metric[\"metric\"][\"le\"], type(metric[\"metric\"][\"le\"]))\n", + " # print(\"\\tvalue:\", metric[\"values\"])\n", + " \n", + " # defining the minimum and maximum x\n", + " min_x = 0\n", + " max_x = len(cdf[load].keys()) - 1\n", + "\n", + " plt.figure()\n", + " plt.grid()\n", + " # plt.title(prom_metric)\n", + " for load in loads:\n", + " diff = 0\n", + " probabilities = np.zeros((len(cdf[load].keys()),))\n", + " i = 0\n", + " for key in sorted(cdf[load].keys()):\n", + " if cdf[load][key] == float('Inf'):\n", + " continue\n", + " # if i == 0 and prom_metric == \"optical_security_loop_seconds_bucket\":\n", + " # diff = np.mean(cdf[load][key])\n", + " # print(i, key)\n", + " # probabilities[i] = np.mean(cdf[load][key]) - diff\n", + "\n", + " # find lowest x\n", + " # if i > 1 and probabilities[i-1] == 0 and probabilities[i] > 0:\n", + " # min_x = i - 2\n", + " \n", + " # # find highest x\n", + " # if i > 0 and i - 1 < len(cdf[load].keys()) \\\n", + " # and probabilities[i] > probabilities[i-1] \\\n", + " # and prom_metric != \"optical_security_loop_seconds_bucket\":\n", + " # max_x = i - 1\n", + " \n", + " i += 1\n", + "\n", + " probabilities[i-1] = np.mean(cdf[load][float('Inf')])\n", + "\n", + " probabilities = probabilities / probabilities.max()\n", + "\n", + " if load == 480:\n", + " curves_specific_load[prom_metric] = probabilities.copy()\n", + " \n", + " plt.plot(range(len(cdf[load].keys())), probabilities, label=load)\n", + "\n", + " plt.xticks(range(len(cdf[load].keys())), [x for x in sorted(cdf[load].keys()) if x != float(\"Inf\")] + [\"Inf\"], rotation=90)\n", + " plt.xlabel(\"Completion time [seconds]\")\n", + " plt.ylabel(\"CDF\")\n", + " plt.xlim([min_x - 0.25, max_x + 0.25])\n", + " plt.legend()\n", + " plt.tight_layout()\n", + " plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"cdf_{prom_metric}.pdf\"))\n", + " plt.show()\n", + " plt.close()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmkAAAHKCAYAAABYEdwPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAADdGklEQVR4nOzdeXxU5dn4/8+ZPTPZF0hYwxI22URFRECpAoprRcWtilYrWr+26uOvRXkUtWpt9VFrra3Sgq3iimsFAZVFFgVZlJ2wJKyBhKyT2c7MOb8/JjMQssNMMkOu9+uVV5KzXHPPEJJr7uW6FV3XdYQQQgghREwxtHUDhBBCCCFEXZKkCSGEEELEIEnShBBCCCFikCRpQgghhBAxSJI0IYQQQogYJEmaEEIIIUQMkiRNCCGEECIGSZImhBBCCBGDTG3dgHihaRoHDx4kKSkJRVHaujlCCCGEiAO6rlNVVUWnTp0wGFrWNyZJWjMdPHiQrl27tnUzhBBCCBGH9u3bR5cuXVp0jyRpzZSUlAQEX+Tk5GQAVFVl4cKFjB8/HrPZHJHHiYeY8dDGeIkZD22MRsx4aGO8xIyHNkYjZjy0MV5ixkMboxGztdpYWVlJ165dw3lES0iS1kyhIc7k5ORaSZrdbic5OTmi/8CxHjMe2hgvMeOhjdGIGQ9tjJeY8dDGaMSMhzbGS8x4aGM0YrZ2G09mqpQsHBBCCCGEiEGSpAkhhBBCxCBJ0oQQQgghYpAkaUIIIYQQMUiSNCGEEEKIGCRJmhBCCCFEDJIkTQghhBAiBsVkkvbWW29x9913c/bZZ2O1WlEUhdmzZ7c4jqZpvPLKKwwaNIiEhASysrK48cYb2b17d+QbLYQQQggRQTGZpE2fPp3XX3+dwsJCcnJyTjrO3Xffzf3334+u69x///1ccsklfPTRR5xzzjnk5+dHsMVCCCGEEJEVk0nazJkzKSgooLi4mKlTp55UjMWLFzNz5kzGjBnDunXreO655/jPf/7DJ598QmlpKffdd1+EWy2EEEIIETkxuS3UxRdffMox3njjDQCeeuopLBZL+Pill17KhRdeyMKFC9m7dy/dunU75ccSQgghhIi0mOxJi4QlS5bgcDg4//zz65ybMGECAEuXLm3tZgkhhBBCNEtM9qSdqurqag4dOsTAgQMxGo11zufl5QE0Oi/N6/Xi9XrD31dWVgLBzVNVVQ1/ffznSIiHmPHQxniJGQ9tjEbMeGhjvMSMhzZGI2Y8tDFeYsZDG6MRMxptvOCVL/AEjGz3zuWBn0865fiKrut6pBoXDX/84x+ZNm0as2bNYsqUKc265+DBg3Tu3Jnzzz+f5cuX1zm/aNEixo8fz/3338/LL79cb4wZM2bwxBNP1Dk+Z84c7HZ7i56DEEIIIU5vWiDATatteNQAD/U5wOjs4MJHl8vFTTfdREVFBcnJyS2KeVr2pEXCtGnTePDBB8PfV1ZW0rVrV8aPHx9+kVVVZdGiRYwbNw6z2RyRx42HmPHQxniJGQ9tjEbMeGhjvMSMhzZGI2Y8tDFeYsZDG6MRM9LxPl2xBI/qwaAo3DT2Igb1yAWOjcSdjNMySUtJSQGgoqKi3vOhFyx0XX2sVitWq7XOcbPZXOcfs75jpyoeYsZDG+MlZjy0MRox46GN8RIzHtoYjZjx0MZ4iRkPbYxGzEjFW7SrGEiiY7KRQT1ywzFPJfZpuXDA4XCQk5PDnj17CAQCdc6H5qKF5qYJIYQQQpyKTZXBqVC9kzwRi3laJmkAF1xwAdXV1axYsaLOuQULFgAwZsyY1m6WEEIIIU5DOyuDo289zEcjFjPuk7SSkhK2bdtGSUlJreO/+tWvAPjf//1ffD5f+Pj8+fNZsmQJ48ePp3v37q3aViGEEEKcforLyyiu8gNgC1RFLG5MzkmbOXNmeFXmxo0bw8eWLFkCwKhRo7jzzjsB+Otf/8oTTzzB448/zowZM8Ixxo4dy5133snMmTMZNmwYl112GYcOHeK9994jPT2dV155pVWfkxBCCCFOT+8vX4Wug91qBGt2xOLGZJK2fPly3nzzzVrHVqxYUWvoMpSkNeYf//gHgwYN4vXXX+fll18mMTGRn//85zz99NP06tUr4u0WQgghRPuzeL8bsJCbopGXGLkyXTGZpM2ePZvZs2c369oZM2bU6kE7nsFg4P777+f++++PXOOEEEIIIY6zucIGaOQlVJBjS4xY3LifkyaEEEII0VYCgQCF5QoAmfoREiNYcUSSNCGEEEKIk7Q6Px+3L4CiwEG/EtHYkqQJIYQQQpykTzbsAKBjkglL1pCIxpYkTQghhBDiJH1/JPi5d5KHIVkdIxpbkjQhhBBCiJO0vSw4Ca2X+Qh5WZFbNACSpAkhhBBCnJSyaieHa4rY4jpIXkbkym+AJGlCCCGEECflkx9+QtchwWLkqyobvTIlSRNCCCGEaHNf7QxuSZmbouOy9ibFFsH6G8RoMVshhBBCiFj341EjoNHXXkGK0iXi8aUnTQghhBCihTRNY09NEdsu7KNvZlLEH0OSNCGEEEKIFtqwdy8ub7CI7f7KQ+RlOSL+GJKkCSGEEEK00Mfr8wHISjKx1N+ZvMzIlt8ASdKEEEIIIVps1QEvAH2SvJQFcsjLlJ40IYQQQog2t7XUCEBf02HwOOgtSZoQQgghRNuq8rgpqgwAkOzdSUeHgyRb5AtmSJImhBBCCNECn/24GU3XsZmN/OCqjMpQJ0iSJoQQQgjRIgu3BXdV754K6415kqQJIYQQQsSC9cXBz/0SKnCqmVEpvwGSpAkhhBBCtMiesmAR2zy9EDxJ0pMmhBBCCNHWfjqwH6fHjwJ4qreC3yI9aUIIIYQQbe3jDTsByEwysRwbAL0zJEkTQgghhGhTK/a6AMhL9rHV2JtOyTYc1siX3wBJ0oQQQgghmm1rSXA+2hmmw3i96fTOtEftsSRJE0IIIYRohmqvh4M1RWy7uLeCJzEqe3aGSJImhBBCCNEM8zZvQ9N0rGYju3y7wZcQtUUDIEmaEEIIIUSzfLk1WMS2WwpsTOwKKFErvwGSpAkhhBBCNMu6Ij8A/e2VbKcHgPSkCSGEEEK0tV2lNYsGtEJc1UkA9MqQhQNCCCGEEG1mS9EhqjzBnjR75XpwJ9IlxYbdEp3yGyBJmhBCCCFEkz75MVjENiPRxDpzNXgd9I7ifDSQJE0IIYQQoknfFjgByEtW2ZveG3RDVOejgSRpQgghhBBN2lwcnI822HSEUmtPgKiu7ARJ0oQQQgghGuXy+ThYEZyP1te1BdUdLGArSZoQQgghRBtasG07AU3HYjJQVrWJ0qNWAPKyorfbAED0liQIIYQQQpwGvtxaBEDXFIXVBhuuowkoSnTLb4D0pAkhhBBCNOqHg8GhzgEOJ0c69AHNRNfUBGxmY1QfV5I0IYQQQohG7Dwa/Dw0UIAxuXUWDYAkaUIIIYQQDdpZcoRKd7AnrXPpDzj0NICo10gDSdKEEEIIIRr08Y/5AKQ5TGxTitFcweSsNXrSZOGAEEIIIUQDlu6uAiAv2c860igrtQCqDHcKIYQQQrSlTcXBz4MtJRzM6ElBcQAg6rsNgCRpQgghhBD18vh8HCgPJmVnOjfRqUMvqr0aBgV6Rrn8BkiSJoQQQghRr6/yd+IPaJiNBoyla+lsyQSgW1oCVlN0y2+AJGlCCCGEEPWav+UQAF1SDaxNhCRSgdZZNACSpAkhhBBC1GvNARWAAY5qfkruADV7drZG+Q2QJE0IIYQQol75R3UAzg7sZXdaZ46WBoc4pSdNCCGEEKKN7CktodwVLGLb/8h39Mrqyc6jbiD6G6uHSJImhBBCCHGCTzbuBCDVbuKQtpch6TnsLKkGpCdNCCGEEKLNLNlZAUCvlAA/JNrpae9ItS+AQYEe6dEvvwGSpAkhhBBC1LHxSHA+2hBLKZuTO5JSs7IzN92OxdQ66VPMJmlr1qxh4sSJpKam4nA4GDFiBO+//36LYhw8eJDf/OY3DBgwAIfDQceOHRk1ahT/+c9/CAQCUWq5EEIIIeKZz+9nf1kwTzi3ahP5Sdlo7tbbszMkJvfuXLx4MRMmTMBms3HDDTeQlJTE3LlzmTx5Mvv27eOhhx5qMsbu3bs599xzOXr0KBMmTOCKK66gsrKSTz75hFtvvZVvvvmGWbNmtcKzEUIIIUQ8WbxzF2pAw2Q00OHIKnIHXEnhUS/QuklazPWk+f1+7rrrLgwGA8uWLeP111/nhRde4Mcff6RPnz488sgjFBYWNhnn+eefp6SkhBdffJH58+fz3HPP8dprr7F161a6devG7NmzmxVHCCGEEO3LvC0HAOicYmBzgouh6Z3JL3ECrVcjDWIwSfvmm2/YtWsXN910E0OHDg0fT0lJ4ZFHHsHn8/Hmm282GWf37t0ATJw4sdbx1NRURo0aBUBJSUnkGi6EEEKI08J3+3wA9E9082NSBmdmdCI/tLKzFTZWD4m5JG3JkiUAjB8/vs65CRMmALB06dIm4wwcOBCAefPm1TpeXl7OihUryM7OZsCAAafYWiGEEEKcbvKPBj+fpe9nY1JHhqR1bvXyGxCDc9Ly8/MByMvLq3MuOzubxMTE8DWNefjhh/n888954IEH+PLLLxk8eHB4Tprdbufjjz8mISEh4u0XQgghRPzaW15KWXVwO6jzilbyXF4OHc3puFUNo0Eht5XKb0AMJmkVFcG6JCkpKfWeT05ODl/TmI4dO7Jq1SpuueUW5s+fz5dffglAQkICU6dOZciQIY3e7/V68Xq94e8rKysBUFUVVVXDXx//ORLiIWY8tDFeYsZDG6MRMx7aGC8x46GN0YgZD22Ml5jx0MZoxGwo3ic/bQcgOcGEu2oHnZIGUlQavKZHWgJoAVSt/goR9cU8lfYquq7rJ313FIwfP55FixaRn59P796965zv3LkzTqezyURt586dXHHFFSQmJvLiiy8ydOhQysvLeeutt5g+fTrDhw/n22+/xWg01nv/jBkzeOKJJ+ocnzNnDnZ762XRQgghhGg9/zioMH+nwpk5Bi4pfYyvB0zibOcZ/C3fwLA0nccGtSxtcrlc3HTTTVRUVJCcnNyie2OuJy3Ug9ZQElZZWUlaWlqTcaZMmUJhYSG7d+8mOzsbgMTERH7/+99z+PBhXnrpJd59911uvvnmeu+fNm0aDz74YK3H7dq1K+PHjw+/yKqqsmjRIsaNG4fZbG7R82xIPMSMhzbGS8x4aGM0YsZDG+MlZjy0MRox46GN8RIzHtoYjZgNxXvoha8BlcGWMjYldWR8vzNxHegK+XsY2T+XiRP7tyhmaCTuZMRckhaai5afn89ZZ51V61xRURFOp5Phw4c3GqOqqooVK1YwbNiwcIJ2vLFjx/LSSy+xfv36BpM0q9WK1Wqtc9xsNtf54ajv2KmKh5jx0MZ4iRkPbYxGzHhoY7zEjIc2RiNmPLQxXmLGQxujEfP4eKrfz96aIrYjqrfzp6SO/DKrK7M3BjdW79MhqVmPfXzMU2lrzK3uvOCCCwBYuHBhnXMLFiyodU1DfL7g0tmGSmwUFxcD1JuECSGEEKJ9WrZnD6o/uEBg4IFvKLCnM7SNym9ADCZpF110ET179mTOnDls2LAhfLyiooJnnnkGi8XCrbfeGj5+6NAhtm3bVmt4NCMjg759+7J3715mzpxZK355eTnPP/88EOxRE0IIIYSAY0VsO6UY2WMsI9Vqp0tCKrvaoPwGxGCSZjKZmDlzJpqmMWbMGH71q1/x0EMPMWTIEHbs2MEzzzxDbm5u+Ppp06bRv39/Pv7441pxXnzxRUwmE3fddRcXX3wxDz/8MHfeeSd9+vRh27ZtTJo0iYsvvriVn50QQgghYtWqvR4A+id62JCUyND0Thyo9ODxa5gMCt3TWrd0V8zNSYNgD9fy5ct5/PHHee+991BVlUGDBvHcc88xefLkZsW49NJLWblyJX/+859Zvnw5S5cuxWaz0b9/fx577DHuueeeKD8LIYQQQsSTHTWzpIYpRaxLyubMjM7kFwd70Xpm2DEZW7dvKyaTNIDhw4czf/78Jq+bPXs2s2fPrvfcOeecw/vvvx/hlgkhhBDidHOwooKjzmBNs9GHv+PNrtn8IqMz+YfbZqgTYnC4UwghhBCitX22ZQcASQkmUkvXc8iaxND0Tse2g2rlRQMgSZoQQgghBF/nlwPQM0VjY4IHq8lMv5QOx1Z2Zia2epskSRNCCCFEu/fjoWB9tEG2SjYmZTAoLRuTwRhO0npntv5uQ5KkCSGEEKJdCwQC7C3TABjh2smmpGzOTO9MQNPZVeICpCdNCCGEEKLVfVuwB68awGhQOGfvEjYlB1d27it34wtoWIwGurVy+Q2QJE0IIYQQ7dy8rcEittnJRtzaPo5aHAxN71Sr/IbRoLR6uyRJE0IIIUS7trIwWMS2X5KPDXZQUBiclnPcooHWX9kJkqQJIYQQop3bUawDcJZymE1JHemTkonDbG3T8hsgSZoQQggh2rHDzipKqoJFbM8vWc/G5OCiAUB60oQQQggh2sq8bTvRgUSbiR6HV7IlsSNnZtQkacVOAHpLkiaEEEII0bq+2VUBQI8UncPmMqrMNoamd8If0NhdGiq/IUmaEEIIIUSrChexTXCyzh6shTY0vRN7y92oAR2ryUDX1NYvvwGSpAkhhBCindJ0nYKjwSK2wz0FbEzOppM9mQ4JSeHyG70y7BjaoPwGSJImhBBCiHZqv9+PRw1gUBTO3beUTUkdY2bRAEiSJoQQQoh26idXsIcsO8WI3b2NbYkdji0aCJffaP3toEIkSRNCCCFEu7S53ApA3ySVAwk+PEYzQ9M7ARyrkSY9aUIIIYQQrWtXmQmAYYYS1trTAY4rv9G2hWxBkjQhhBBCtEMlLifFNUVsRx7dyE9JHUk228hNTMMf0NhTU36jd4YkaUIIIYQQrWbetl3oOjisJvKKVrEpqSND0zthUAwUlLnxazo2k4HOKbY2a6OpzR5ZCCGEOE141QAVvgBOT4BKX4BKr58qb4BKl4ufqixU/nQQo9EYkccKBAJsiWDMSMeLVkw14GdjpZldq/Jx+wM4fSpunx+XP4DbF8Ctarj9Gl5Vw+PX8dZ8+AI6Pj/BzwHwB3T8AR2PP1h6IzdFRztSSL7jPMbXs9NAW5XfAEnShBCixfwBjSqfRoXHT5XXT6UvQLVXo8rnx+kN4PQFcKka1T4/1T4Vl0/FrfqDHz4/FZV2/jVnLYpy6r/8dV2nMoLx4iVmtNpYVpHAX2atxhfQ8Pg1vH4t+Ifer6EG9Foffk0nENDwazq6rjcefP1PEWljVGPGQxsBNuyKaLifOcrZn2zDbzCGFw3kt/HG6iGSpAkh2pUKj5/9lV4OVvooqvJy2Omm2OmhxOWl1KVS7lap9ASo9Pip9gbwqDYCa75B1TT8geAfZa2pP8jN4olAjGjGi5eY0Wij95TuNigKRqOCyaBgMiq0YUfMacdoALMx+GExgtWoYzYFP1uNYDPp2IxgNQQ/JxggwaBhVSABnQQdEnSNBE3H7PaTVuEld9ePfO7IBOpZNNCGKztBkjQhxGlA13W2F63jgzIfb7/7NeUehUoPVHrB6QOXV8et6njVAAEtEgnWMYoCJoMBY80fZFPNHxCzQcdiArNRw2rUsRg1rEYNi0FHUXQi+Xdbh4jGi5eY0WijAR2bScdq0LAZgx8Jio7NEPxsN2jYFR27opMA2BVwAA5dwaErJGgGTJoZPRD80PxGykorSUtLC/6wRIKuU1ZWFrmYkY4XtZgaZcWVJFoS0bx+Ai4VvWbI8uRZMHp+Ym2HTMwGI/1TOgCw86gkaUIIccr83h/Zc/A9zn1jFC6vDVCbvEcBLGYjNrOC3aLjsGgkWQMkW/ykWP2kWn1kWHykWbwk6h6STAoJBEjQ/Ni1AAl+Pw5NI0HTsPiNaH4Tut+EpprRVdNx35vQvWY0vwk0WacVfxSg+fOpNKA6/F2g5gMsGKmuqIxoyyIdMx7aGIyp4KuurnNcMRsxWkwYrWYM1uDn2l+bMNQcC32tKxoHXpmA0buDTUlTGJiajcUYTItiofwGSJImhGgD3qNVpO7xse+THzAYTi55MSbuJaHrIswpu7jti1/j8gZwWE0MzIIUk0aySSPV4CcVlXRdJS2gkqX7yfD7SVU1lFAi5Teje4ygH98Oc81H47+gPQr4LMFf+qE/CKbE+v4gHPujoRsV1q5bx1lnDcNkOvVfwX6/n7VrIxcvXmLGQxvjJWY8tDEU84f16xgxeiRWuw2jzRz8f2YxoRhb/nvEuWcdJu8OVHMCe+zp3F4z1KkGNArK3ADkZbbdbgMgSZoQopUFfH4K5qwisSRA2ZHCFt9vzSom/dy1OLrvA+DfW8ewao8ZgEdtOuOL63vnbiTcI2JQoCahMtiDv+ANZlCMOgbFD/hQ8IDmQlerOHx4HzmdsjCawGDUUIwaBoOGYgygGPTGR3L8NR81b/wDgKYFsBftxL9jHZrh1Fe9RTpevMSMhzbGS8x4aGMopuPgTjzr1uGLQEzP/k0A7E3vhq4o4UUDe0pdBDQdu8VITrL1lB/nVEiSJoRoVfs+W4u3pIqAGXLO742xmb9sDdaDmLMWYEraDICuGyg+MpJHF48AfIzqksYIcwHZed0wKD7wV4O/Cl2tBF8ZurcU3VVMwFWC5iolUFJKoLqUQHUZmt7wvJZUwB3ZxWRkAKXbYjdevMSMhzbGS8x4aGO0Yq5xBOehnbhooHeGI2Irh0+WJGlCiKjR/T58R3bjK9qO99A2yndUUlE8CHSNhIN/oOrtrU3GMHWwk3RRDxL6dwzG1HTcG4qo/KaAu5NuoMrjw2Ex8uymq0n3H6Vizcm1VbHYMSamY3TUfCSmo9hS2HvwMN27dz/pYdkTaZpGYWFhxGJGOl68xIyHNsZLzHhoYzRiaprGtv2H+GtWDgCD04KfY6X8BkiSJoQ4RbquE6gqxntoO75DwWTMVxT82le8G7Tg5GnNlI0361kwgKnqI4y+xhM0Y0YCyT/rQcKQjig1NQxcPx2m6us9+ItdLEq/kqXVwXfAD/rnku4/CoAhIblWotXQ14bjj9vTMFjqVhVXVZW18+ZxzsSJmM3miLxeqqryQwRjRjpevMSMhzbGS8x4aGM0Yqqqyj8/fZuyqk30TsokueZ3QKyU3wBJ0oQQzaQEVLwHNuMu2R1MxA5tr+kh247mKm/4PqsDS8f+OA2/BNWGLQO63v4wS3+cxPiJl2M21f5lqwWK8Lrexe/5muB6OTBZzsPiuJmki3rQ8SJw+gI8+edV4HRzTo8sZvzqVVT/S3y5YBETL78iYn8UhBCntz3+YEJ2Zkan8LH8kuBuA5KkCSFinlq6n32vXEuv3WvY+2kDc7cUBXNGNyw5/bBm98WS0xdLdl+sOX0xpXVm33/X4V+Vj8luJe/OCSh2M9qWIgxmG4aahErzH8Fb9RY+15eESheYrOdiS56C0dKn1sP98sONlDrd2Cwm3r95KAaLDYNihAhNUBZCtA+7A8GEbGh65/CxnSXBjdVluFMIEdN0XefgzDvw7P4eBTDYkoKJ2HFJmCW7L5bsPAyWhHpjlG/ZT/GqfAByrzsXS4odVT1Wy0wLHMVb9Q6+6v8SqnFmsp6FNXkKJsuAOvEW5pfx0brgqtBHx/cnN63tNj8WQsS33f5gkhbqSfP5NQrLapI06UkTQsSy8iVvUL15EYrZRsHoZ7joxl9jsViafb+vvJqCuasB6DiqLyl9jw0pmE0ufFVv4Hd/DvgAMFoGY0u+HZN1cL3x1IDGlPc2oOk6Z3TO4JELup38kxNCtGsuv4+DWrAeWqgnbffRajQdEq1GOia1bfkNkCRNCNEAX0khh999CICMnz/FDn/PFi1H1wMau99dRcDtw94lnU7jjyVeAd8GRgx6E7872HNmNPfHlnw7RuuwRh/j7k+2c6jMidlk5L1bhkRs1ZgQov3ZVF6EBnS0JZJjTwaOreyMhfIbIEmaEM2211nG69tWsbF6N4t/+C8GYwSKSAYC7KkuiFi8iMXUdS797DE6e5wU5fTnjdRcdhe27HkP2eJj4F4/PhN82t+Fc90X4XO3ZXxArk3lkC+TbypHstObCxyo+ahfSYWFOd8F56qdd0YC/yz4GgqOnY/Z1zLKMeOhjdGIGQ9tjJeY8dDGaMTcWlYEEC5iC7FVfgMkSROiSU7Vyx9/+oYXNi/FE/AHD25rOJk4KZGOd4oxrz/wI533/4TbYOL2ruexd8d3LYo53JXEjQf6AAqPZe7iq4Ky8LmuNh+Pdz6IpsNFqzpy0LsP2Nd4QB1S948joGmkplhY5v+CZZsbuDbGXstWixkPbYxGzHhoY7zEjIc2RiHmWRldwl/HUvkNkCRNiAYFNI3ZO9cwfd2XFLmrABjdoQdZlSo9e/XCGIGhtoCmsXvXrojFi0TMxIoirljxKgAbz7+dG4de1aKYVo/G+K9dGNDZlWvmrGFDOeu48yMcwTlq2ysyuKn3uGa18bstDpZWVGE0GLhmpEJW6tg618Tia9kaMeOhjdGIGQ9tjJeY8dDGaMQMaBqHdhfwm36jwsfCPWltvGdniCRpQtRj8aGdPLj6MzaUHgSgV1IGfz7nci7L6cv8+fOZeOYlESumOO/QvIjFO9WYuqZR+KeLcake7H1Gc9sdf0cxGJodU9d08mcvocpbja1jCtfePo7rzbV/zVQd/hjND4byITwzvOk2bjpczf99sBSA28/rxRsX94v4825IPMSMhzZGI2Y8tDFeYsZDG6MRMxQvzXpsZfpOGe4UInblVxTz8A//5dO9wbG0FIuN/x1yMff1H4XVaKpVOuJ0VLb477i2Lkax2Ol0579QWvhu9fC3W6naeRjFbKTnDSMxnJCgBdTdaP49gJnist5NxtM0jevf2oDqD9ApLZG/XdWnyXuEEOJkeNQAe8uDqz1luFOIGFLmdfHkhkX8desK/LqGUTEwte8IZpw5gUxbbPxnjTbfkd0cfu//A6Dj9X/E0rHpJOp4zsISDizaCEC3K84ioWNKnWtU19cAGC3n4A80Xd/sD0v2svVgKQZFYfYNQzEbZTWnECI6dh91oeuQbDORldj8UkPRJEmaaNdULcDft61ixoaFlHqDBQwv7dyP54dfzoDU7DZuXevRNY2D/7wD3VuNvd8FpF306xbd73d52fPeStB00gZ3I+OsHnUfQ9fwub8BwGgbC1Q1GnNPmYdnFwX395w0LJdxvdNa1CYhhGiJcPmNzNgovwGSpIl2Std15u3fyv+s+S/bKo4AcEZqR14YfiUTOvdt49a1vrKv/4Zr21IUq4NOv2zZMKeu6xR+tBpfuQtreiLdrz6n3l9wAd8m9MARUOwYrcOBrxuNe/1bP+Lx+clMsjP72v4tfUpCCNEisbayEyRJE+3QxtJDPLjmM746GNyqKMvm4MkzJ3Bnn3MxtcO9H32Hd3H4/d8B0PH657B06Nmi+4u/20n5lgMoRgM9bhyJ0Vb/hN7QUKc5YTSK0ngl75dX7ueHgiMowN+vG4zd0v7+XYQQrSuWNlYPkSRNtBuH3VU8tm4BM/O/R9N1LAYjvxkwmkeHXERKA/tOnu7Cw5w+F/Z+F5L2s3tadL/rYBn7560HoPMlQ3B0Tq//cXQV1R1coWlJuAi9kZhFVV4e/SK4cOOSgV2YdEZWi9okhBAnI9YK2YIkaaId8ARUXtj6Lc/89DVVqheAa3MH89zZl9EzKaONW9e2Sr/6K67ty4LDnC1czRnwqux+dyV6QCOlf2c6jGx45aXfswZdr0IxpGO0DsXv1xq89sZ3NlHt8ZFst/L2DYNa9HyEEOJkyXCnEK1I13WWe4v57WcvUlAdrHh/VkYXXhx+JaOzWzakdzryHd7JkQ9+D0DHyX/GklV3sn9j9n62Fm9JFeaUBHInDW90oq3qDg11jkVRjED9Sdq/1xexZHuwNt2LVw8iLUF+RQkhos+tBthf4QEkSRMi6nwBP5d/M4tF1cF5Z53syTx71kRu6TUMgyJlHHRN48DM29F9buwDfkba2LtbdP/RdXsoXV8AikKP68/DZG94jpmuuVA9qwAw2y9q8LoKj5/ffBws4TEqL4c7zsppUZuEEOJk7aoZ6kxNMJPhiI3yGyBJmjhNvV/wI4sO5WPBwO8Gj+V3g3+Gw9z4ZPX2pHTRX3DvWI7BlkinO/7ZomFOT3Elez9bC0CniwaS1KNDo9ernhWgezGYumA0Nzwk+ov3N1Ne7cFuNfPuTTLMKYRoPcfKb9hjpvwGSJImTlN/2bIcgOsSuvK/gy+O2LYkpwNv0Q6OfPgIAB1veB5LVm6z79XUALvfWYnm85PUswPZFzZdGuPYqs6LGvzl9+nWEv77014Anpx4Bp2TJaEWQrSeY/PRYmPPzhAZ9xGnne+LC1lTsg+Lwcg4a/spSNscuhbg4BvBYU7HGReTeuGvWnT/oQU/4S4qx+Sw0uP685rsgdMCpfi9wV63hoY63WqAu97/CV2HM7tn8dCori1qkxBCnKpjG6vHznw0kJ40cRoK9aJNzh1CannszC2IBaULX8a9cyUGWxI5d8xsUbd+QmmAo/m7Aci9bgTm5KbLlqjuJYCG0dwPo6lzvdf8cu42iiursZpNvH/zkGa3RwghIiUWy29ADPekrVmzhokTJ5KamorD4WDEiBG8//77LY5z5MgRHnjgAfLy8rDZbGRkZHDeeefx2muvRaHVoq0dclXyQcFPAPy678g2bk1s8R7azpEPHwWg440vYMns3ux7fWXVpO32Be8d05+UPs2b1K+6gttANdSLtrSggvd+2APAwxf1o3dG+6xXJ4RoW7FYfgNitCdt8eLFTJgwAZvNxg033EBSUhJz585l8uTJ7Nu3j4ceeqhZcTZs2MD48eMpKyvjsssu49prr8XpdLJ161Y+//xz7rmnZYU7Rez7x/ZVqFqAkR1yGZbRmXn82NZNigm6FuDgzNvRVQ+OgeNJveDO5t8b0Nj74WoMAbB3SafzuOZN6g/4DxBQtwIGzAkX1jmv6jDl/U1ouk7fnDSeuKj5SaMQ8UpVVQKBwCnHMJlMeDyeU44VjXjxEjMUr6yqGjN+uieb6J5sxOPxNHmv0WhslbnOMZek+f1+7rrrLgwGA8uWLWPo0KEAPPbYYwwfPpxHHnmEa6+9lu7dG/+FXllZyVVXXQXA2rVrGTx4cJ3HEacXX8DP37d/B8D9/Ue1cWtiy9EvX8S9cxWGhGQ6tXCYs2zjXlz7S9GM0O3a4SjG5nXAhxYMmKzDMBjr7kTwn0PJHCitwmQ08N7NQzG0YIWpEPGmqqqK8vJyvF7vKcfSdZ3s7Gz27dsXkZWIkY4XLzFD8Q4dOMDfx3XAoCiUFR2grJn3W61WMjMzSU5OPuW2NCTmkrRvvvmGXbt2cfvtt4cTNICUlBQeeeQRpkyZwptvvsljjz3WaJy//e1v7N27l3/+8591EjQAkynmnro4RR8U/MRhdxWd7MlckzsIAg1XtW9PvAe3UfzRdAA63vh/mDNaNjH/6PoCAJzZJixpzRsK0HX9WAHbeoY61x1yMm+PC4Cpo/MYkhNbK6qEiCSr1UpRURFJSUlkZmZiNptPKcnQNA2n00liYmJE3txEOl68xAzF00w21AoPCWYjPZox3KnrOqqqUlFRwYEDBwCilqjFXKayZMkSAMaPH1/n3IQJEwBYunRpk3Hee+89FEVh0qRJbN++nYULF+J2u+nXrx+XXHIJFotMKD/d/GXLtwDc03ckZoMRVZK0mmHOKeiqF8egS0gdc0eL7vdVuKjceRiA6szmb3Kuqflo/v2ABbPt/DrnH56/E39Ao1tGMi9O7N2iNgkRb5KSkkhMTKRLly4R6QHSNA2fz4fNZotYshLJePESMxTPbbCASSMhwYzNZmvWvQkJCSQlJbF//35KSkraT5KWnx+sEJ+Xl1fnXHZ2NomJieFrGuLz+di4cSNZWVm88sorPP7442jasT/YPXv25JNPPmHQoIbn1ni93lrd0pWVlUBwDFtV1fDXx3+OhHiIGYttXF2yl9U1ZTdu73VWvf9OsdDOaMc7MWbp/Jdx7/oeQ0IKWb/4W4uH+YvX7gZdJ6FrOgGbu9nt9DkXAmC0jsAfsEDg2H1eNcCaghIAHr6gO7oWQNUiM7/k+M+REA8x46GN0YgZD20EcLvdWK1WkpOT0XUdXddPOWYohq7rtf62xUq8eIkZiudRg79/rCZDi+MmJSVx8OBB3G43JpOp3p+hU/l5UvRI/MRE0Pjx41m0aBH5+fn07l33HXbnzp1xOp1UVFQ0GKOoqIicnByMRiMGg4Fnn32WX/ziF6iqyj/+8Q/+8Ic/0K1bN7Zt29Zg1jxjxgyeeOKJOsfnzJmD3W4/+ScoouJF5zaW+ooZa+nAbxL7tnVzYoKlch9dv3kQg6ZyeNj/ozK34S2Z6qXrdPzJi9mjU9rDjKtDc9/TaZw3eBZWSzUb8y/naEXtfVKXldv5v588WM1G/nOuH4shpn4FCRFRJpOJ7OxsunbtKiM4MWq/CzwB6GiDpBauBfD5fOzbt4+ioqIG3wS7XC5uuukmKioqWtzjFnM9aZEQyoQDgQD33XdfrdWgTz75JNu3b+f999/nww8/5JZbbqk3xrRp03jwwQfD31dWVtK1a1fGjx8ffpFVVWXRokWMGzcuYqs84iFmrLWxyF3Fyo9XAvDMRddxVkaXmGxna8QLx1zwJXn5s/FpKvZBl3L+Pc+3eJjFdaCUnasXo5gMjJh0Md98u6RZ7Qz41uEtrwYlkeEj70ZRal//0qwfgUP0y0jgsgnnxuy/TbzEjIc2RiNmPLQRwOl0snv3bhwOBwkJkSkxo+s6VVVVJCUlRWwCfSTjxUvMULyArgA6ackO7ObmT+sA8Hg8JCQkMGbMGGw2W70/Q6GRuJMRc0laSkoKQIM9ZZWVlaSlpTUrBsCVV15Z5/yVV17J+++/zw8//NBgkma1WrFa625NYzab6/znre/YqYqHmLHSxn9t+gFVC3BeVndGZPeISMymxPprmZb/Cb7CtRjsKXS+4w3MJ/EOvuKn/QCkDuiCLcne7HaqzmUAWBIuwGKp3eusBjS+rxnqHJWlxcW/TbzEjIc2RiNmrLcxtEhNUZSIzs2KZMxIx4uXmJqmoemgasHefJvZ2OK4BoMBRVHq/Mwc//2p/CzF3Jr30Fy0+uadFRUV4XQ6652vdjyHw0HnzsHq5qmpqXXOh4653e5Ta6xoc8GyG6sA+H8DpOwGgPfAZtK3vgNA9s0vY06vv9J/YzR/gNKfCgHIGFY38W2IrvtQ3cEFHGb7xXXOv7uxGLdXxWIyMjqlusXtEkKISFJrpqCZDAqmGCwDFHM9aRdccAHPPvssCxcu5IYbbqh1bsGCBeFrmvKzn/2M//znP2zZsoVhw4bVOrdlyxYAcnNzI9No0WY+LPiJIncVOQnJTOrevCKrbUEP+FGP7sV3eCe+IzuDnw/vxHc4n54l+9g13wSRGRFA93kwaH7sgyeScv6tJxWjYvshAi4f5iQbyb074m9m4Ui/ZxXo1SjGDhgtA+uc//fa4HL1oV0zsBmKTqptQggRKaEkzWqKvQQNYjBJu+iii+jZsydz5szh/vvvD9dKq6io4JlnnsFisXDrrcf+8Bw6dIiKigpycnJqDXNOnTqV//znP/zxj3/k8ssvD/eeFRUV8fLLL2MwGJg0aVJrPjURBa9sXQHAPf3Ow2Js2x9n3e/DV7ynTiKmHtmJr6QAAvVPKjUCWuQWkwHgt6bQ8da/nfS8jaPrgls1pQ/NDW6i3swkzVezDZQl4WcoSu1fev6AxqrdxQBcNzgbyiRJE6K9eOutt/j2229Zu3YtGzduxOfzMWvWLKZMmVLrOlVV+eyzz/jss89YvXp1uHDtgAEDuPXWW+t03hzv7bff5uWXX2bz5s1YLBbOP/98nnzyyTodNcfz1SRpNlPL5qK1lphL0kwmEzNnzmTChAmMGTOm1rZQhYWFPP/887V6wKZNm8abb75Z5x975MiRPPjgg/zf//0fgwcP5oorrkBVVT799FOOHDnCM888Q58+fVr/CYqIWVO8l++KC7EYjPyq74hWeUzN58ZSuRfn+s/QjhbUSsjUo3tBb3j5tmK2Ycnqibljbywde2Pp0BtDRi4rN+3mggvHYjJFZg6M36/y9Xc/0T+108ndX+2lYvtBoIVDnVoVfs/3AJjtP6tz/qMtR6n2+DAbjdx+ZgeWf3NSzRNCxKHp06dTWFhIZmYmOTk5FBYW1nvdrl27uPbaa0lMTOSiiy7iyiuvpKKigs8//5z77ruPzz//nC+++KLOfU8//TTTp0+ne/fuTJ06laqqKt59911GjhzJ119/zfnn163XCMHt6QCsZulJa7axY8eyfPlyHn/8cd577z1UVWXQoEE899xzTJ48udlxXnjhBQYNGsSrr77K7NmzURSFM888k7///e/8/Oc/j+IzEK0h1Is2ucdQOiYkRfWxfId3UfLfZyhf8R+6B1QOfVX/dYrVEU7Aan3u2BtTaqdgr9RxVFVFLZyHpWNexCYqG1QV3dx4LcHGlP5YCJqOvXMaCR1Tmr6hhupeBqgYTD0wmnvVOT/7h+BChMFd00m2xeSvHiFElMycOZO8vDy6d+/OH//4R6ZNm1bvdUlJSbz66qvcdtttOBzHqv+/8MILXHjhhSxYsIAPP/ywVi6Qn5/PjBkz6NOnD6tXrw6Pqt17772MGDGCu+66i02bNtW7KEAN96RJktYiw4cPZ/78+U1eN3v2bGbPnt3g+SlTptTpThXxr8hVybt7NgDw//rX/w4pEryHtlPy+TNUrHobagquBsx27J37Y+2YF07ALB16Y+nQC2NKx4gtN28rR9cHhzozzmx+LxqAz9XwNlCaprF8V3Co8/ohJ9fDJ4SIXxdfXHchUX06d+7MvffeW+e4w+Hgt7/9LbfccgvLli2rlaTNmjULv9/Po48+Wmva09ChQ7nxxhuZPXs2y5cvZ8yYMXXiypw0IaLg9R3foWoBRmR155ysbhGP79m/mZLPn6by+/fCQ5iOQZeQdtk0Fm8vZeJll0V82X8scB+uwHWgDAwKaYOb/7pqgWICvp+A4Hy0E322rZQqtxeT0cDdwzsBUsBWCNEyod+5J+693dR2krNnz2bp0qV1kjRNh0DNryLpSRMiQnwBP3/f9h0Q+V40z94fKf7sD1T9MBdqNuNIHHoFWVf9Lwk9zwlu77FjXkQfM5aEFgyk9O2EObF5e9gBqK7FgI7RMhCDqWOd8//6Ibiqc2DnDFJspohuuyNEvNJ1HZev5VuiabpGtS+A0efHoESgXlgT8ewWY0yMEMyaNQuAcePG1Tqen59PYmIi2dnZde5prKyX1x987U0GBWMMlt8ASdJEHJpbuJFD7kqyE5K4NndwRGK696yl5LOnqFr3afhY0tnXkHnldBK6nxmRx4h1uqZRuqEAaNmCAQCfOzTUWXdIQ9M0luUfAWDS4Lq/RIVor1y+AImPND2tp605n7kUh7Vt04XXX3+dL7/8kjFjxjBx4sRa5yoqKujQoUO994V2CKqvQL7HHxwlidVeNJAkTZyEVYVl/M86hWnblhOpN1e6Dk5n82LuSV0BZgiUZHPmC9+eUszerq1cW/wfznIGe+Y0FFYlX8hHWTez190T3isHFp9UO5sj0vFOJeYg1cvD1R6cisIF/91B4Itj7zwbi5mbXMycK3bi1wxc+IaBSt/iWuc1g4kKlweDQWHOmgLeWbMnpp53vMeMhzZGI2Y8tBEgO8HA789OZGeJC4Oldhmek+lFawubD1dht7SwRIUOmgYGt7NODciiKg8A+yvcbCpqesukpYu+5Lf33UenLt147MV/sOVw7Zg6wV0D6otVWOwEoNLrr3M+UDPWGavz0UCSNHESXv9uHzudCjidEY6sgKuJmLYqyCoHTaF4XybF/qbaUH/MYeoWprre43x1PQABDHxhHcMbCdex29QVKoCKhmI3o50tEul4JxfzJpMHjDDPb2Tjkfp2A6g/5s97BV/Dr/Z057t9GlD7mqzU4Mrb1EQ7Ww9XnVIbm9ZeY8ZDG6MRM/bbWJ1sIqAn4gtox2apH3sklv16ZMQeK1oUwKM2XF6oUVrd+/w1yZEa0JuMu+Kbhfx/d99KemYWr77zKSlZ2eEesJDEpGSclZX1xiotC/ag2R1JDT6WwxK7qVDstkzErG0170yeGJ/HmF6ZEYnp9/v57vvvGXHuuXUmhR7v2e3/ZeERuLjjAB5tYueJOjF1HXPhShzfPo+lYDkAumLEM/g6XOf/lhEZvWiq2lpz29lckY530jF9fhLfWQYBuOzqM7k0q3bpjYZj6gywzgGgb9crWHzPebXu0zSNa976EYCfD8zhliFZJ9/GJrTXmPHQxmjEjIc2QrC2or36CLlpCVhtzZ/n2RhdB2d1NYkOR+R6JSMYr6mYWY7gXsI5SVb6ZjnquTvoy/nz+N3dt5KZkckXCxfRs2fvemP2yctj9fffkRqoouMJ89I2Hg2W/jlzYL86j6Xr4HJVk+mI3UVgkqSJFtF1ne01vSxXndGRIV0a3+y+uVRVpXo7XNAro8FVk0fcVSxZsRWAp8+9iOFZjSeIoZhjeqbj27GU4k+fxL0jmJxhNJM6agqZl/8eS4eeEW1nS0Q63snGLFmzi8KAhi0rmWEjetaZJNxQTL93M9UlR0CxMaT7BBRD7T9CX+0qo6Lag0FR+MP4nmQnWU+6jU1przHjoY3RiBkPbQSoqqpix44j2C1G7LbIxNQ0Dc0LidaWbwjeGvGaimk1B4dObWYjSQ28Jl988QW/uHEy6enpLFmymLy8vAZj/mzshaz+/jtWLltca0cigGWLg/Nlx1/0szqPFYoXy2J3IFbEpP3lHpy+AEZFp3eGvVUf+/Xt3+PTApyb1Y3hzSi7oes69qIf2P/sGPb+eTzuHctRTBbSLrqXvD/vpNMdr7coQTudHV1fAAQXDLRkFZcaWjBgG1UnQQN4/fvgqs6+OWnhBE0IIRozf/58Jk2aRFpaGosXLw6v0GzI7bffjslk4umnn661QGDDhg2888479O/fn1GjRkW72VHRop60Bx98kEsuuaTeWiSifdh6JDinKMcGllacbKlqAV7bvhKA/9e/6f9sul/l4EuX03nzIjwEt2RKG3s3GZc+jDm9c5RbG1+8pU6cBcWgQPrQ7s2+T9f9qO4lQP0FbAEW7zgMwNWDZFWnEO3ZzJkzWb48OJKxcePG8LFQjbNRo0Zx5513sm3bNn7+85/j9Xq58MILeeedd8IxdF3H6/XSp08f7rjjjvDxPn36MGPGDKZPn86QIUOYNGlSeFsogDfeeCNiPYStrUVJ2ksvvURqamqtJO25557jT3/6E0ePHo1440Ts2Xo4OB+tS+t2ovFRwUYOuoJlN65rRtmN6m1LcG1ehGawkD7uPjpMfBhTqiQK9QnVRkvq1RFLSvP/Yf3etehaBYohFZP1rDrnl+4pp6TKhaIo3HNul4i1VwgRf5YvX86bb75Z69iKFStYsWJF+Ps777yToqIivN7gGGQoyTrRBRdcUCtJA3j00UfJzc3lpZde4rXXXsNisTB69GieeuqpRjdYj3WnPCfN4/FQXl4egaaIeLD1SNskaX/ZGnwHdnffEViMTf/YVm9aCEBV19H0ve6PmE7D3QEiQdf0WkOdLaGGtoFKGIui1F2e/4+aoc68jql0TZGhTiHas6a2cAy58MIL0fX6dyTRNI3Kyspw7bMT3Xzzzdx8882n0syYE5/9f6LNbKkpodDF3nrb+qwt2c/KIwWYDUbu7nte0zcAzo0LAHB1bB+FaE+Ws7AYX1k1BquJtAHN7+3SNTeqJ/gO2Gyvuw0UwNc1Q51XnCE9mEIIcTIkSRMt0hbDna/U9KJdlzuYHHv976COp5Yfwrt/IygKrqzI7Ehwugr1oqUN7IqhBbWCVM9K0D0YjJ0wmvvXOf/dvgqOVFSjKPDr82SoUwghToYkaaLZSpxeSqp9QOslaUfcVbyzO1gs9f4BzVudU71pEQDW7sPQrE0nde2V5vNTtnEvcApDnfaf1bsa9LWaoc6eHVLpkRaZ2lBCCNHetHhO2v79+1m9enWt7wHWrFnT4Djy8OHDT7J5IpaE5qN1S7VhM7pa5THf2BEsu3FOZlfOzWreysPQfDT7GeOauLJ9K9+yH83rx5LmILF7VrPv0wLl+L1rADAn1L+qc9G24FDnZQNkqFMIIU5Wi5O0f/7zn/zzn/+sdUzXdUaMaLhWeyAQH/uTicaFhjr7d0gEop+kqVqAv20Llt1obi+armk4a5I0xxnjYGdVE3e0X+EFA2fmohhaUhttKaBhMOdhNNetV7fuoJNDZU4U4NcjZKhTCCFOVouStNtuuy1a7RBxIFQjrV+HhrfxiKSPC4NlNzrYErkud0iz7vHs+5FAVTEGWyK2nufCzq+i3Mr45KtwUbkz2NuVcWZui+4NFbC1NNCL9rfvgr3r3TKT6ZOZcPKNFEKIdq5FSdqsWbOi1Q4RB0I9af06JEJJ9B/vL1uCCwam9jsPazPKbsBxQ539xqKYLFFrW7wr/bEQdJ3E7plYM5KafZ8WKCLg2wwomO1j671mwdYiACbKUKcQQpwSWTggmi00J61fh8SoP9a6kv2sOFKASTEwtZllN4DwUGfioAnRalrc03U9XMC2pQsGAp7FABitQzEY6+6durHIyf7SYI+rrOoUQohTc0rFbKuqqli7di0lJcFulaysLIYNG0ZSUvPfmYv44PT62VvmBqBfloPvo/x44bIbPYY0q+wGgOatDm+g7hgoW5c1xHWgDM+RShSTkbRBXVtwp46/JklraKjz1e+Cqzq7ZiRzRisNiwshxOnqpJK0TZs28fvf/54FCxagaVqtc0ajkYkTJ/LMM88wYMCAiDRStL1tNb1oWYkWMhzRHUYs9jh5Z88GAO5vxj6dIdXblqL7fZgzc7F07I3f749SC+NbqBctdUBnjLbm/1smJpSgB/YCZswJo+u95suaoc5L+nc85XYKIUR71+IkbenSpVxxxRU4nU7sdjtnnXUWnTp1AuDgwYOsXbuWzz77jCVLlvDFF19w/vnnR7zRovVtrdlpoH8rDHW+sf17vAE/Z2d24dysuqsHGxKaj+YYOL7e2l0CNH+A0p8KgZYPdXbI2A6AyTYCxVD352B7sYvCkkoA7pVVnUIIccpalKS5XC5+8Ytf4HK5mDFjBg899BAOR+0hjerqap5//nmeeuopbrnlFrZu3YrNJsUs411oPlr/jtEdyq5VdqP/6BYlWzIfrWmVOw4RcPkwJ9lI7t383i5d1+iYHkzSLPb6hzr/WrOqs1NaIkNzop/MCyHE6a5FCwfef/999u/fz7PPPstjjz1WJ0EDcDgcPP744zzzzDPs3buXDz74IGKNFW0ntLJzQMfo/vH9dN8WDrgq6GBL5PoezSu7AaAe3Yfv4FZQDDj617+XpDg21Jk+NBfF0Pz//pq6EaulGhQHJtu59V7zxZbgUOe4fjLUKYQQkdCiJG3evHlkZWXx29/+tslrf/vb35KRkcF///vfk22biCHHhjuj25P2ak0v2t19RzS77AYc60VL6HUuRkdqNJoW9/zVXiq2HwJaXhvNH17VOQpFqTuPbfdRNwVHKgC4d0RLFiMIIYRoSIuStB9//JHRo0djNpubvNZisTBmzBg2bNhwsm0TMcLn19h5NLjDQP8o9qTt9jtZUVxTdqNf88tuQO35aKJ+pT8Wogc07J3SSMhObfZ9uu4j4A2umjXZ6q+N9tfvD6ADHVMcDO8iq7uFEMccOHCAl156ifHjx9OtWzcsFgvZ2dlMmjSJ779vulbA7t27SUxMxGg08sADDzR43dtvv83w4cNxOBykpaVx+eWXs27dukg+lVbXoiTtyJEj5ObmNvv6Hj16cOTIkZa2ScSYnSXVBDSdJKuJzinRm1/4hecgANfmDqaTPaXZ9+lagOrNwZ0FZD5aw8LbQLV0M3X3ctCdeH0ODOZB9V7z+aZgD93FMtQphDjBK6+8wgMPPMDu3bsZP348Dz30EKNGjeLTTz9l5MiRvPfeew3eq2kaU6ZMafIxnn76aW655RaOHDnC1KlTue6661i2bBkjR45kxYoVEXw2ratFCweqqqpITm5ezSqAxMREnE5nixslYsuWw6HtoBKjtmqyxFPNMl8wof9/LSi7AeDZs5ZAdSkGewoJPc6JRvPinvtwBa4DpWBQSBvc/BWzuq7jc34IwKGSM0jrYqxzzd5yD7tqhjrvHi6rOoUQtQ0fPpwlS5ZwwQUX1Dr+7bffctFFF3HPPfdw9dVXY7Va69z74osvsmrVKv785z832IuWn5/PjBkz6NOnD6tXryYlJfgm/95772XEiBHcddddbNq0CUML5uHGiha1+MSaaNG6R8SWYys7IzvUWa162VFRzOJDO/nfDQtQ0RmW3pnzOnRvUZzwhuoDLkJpwTy29uTo+uCCgZS+nTAnNr83NODbSEDdDpg5cGRwvdf87bsD6LpOVrKd0bnN7wEVQrQP11xzTZ0EDWD06NGMHTuWsrIyNm7cWOf8tm3bmD59OtOmTWPo0KENxp81axZ+v59HH300nKABDB06lBtvvJGtW7eyfPnyiDyX1tbiv2ibNm3i/fffb/a1Iv6FVnY2t0aaruuU+dzsry7ngKuC/dUV9X4u87nr3PvrfiNb3FsXmo+WKPPR6qVrGqUbamqjtXDBgNcZXJ1tsl2M6rfXe82nm4OrOn/WV4Y6hRAtE5rjbjLVTkcCgQC33XYbeXl5TJ8+nZUrVzYYY8mSJQCMH1/3b8CECROYPXs2S5cuZcyYMZFreCtpcZI2d+5c5s6d26xrdV2XoqKngfDKzpoaabqus9vv5JO9mynyOutNwNwBtVmxHSYLXRwpdEpIJrncww25zS+7ARBwV+LatSoYS5K0elXuPIxa6caYYCGlX6dm3xdQ9+H3BF9bk/0aoO473UNVXnYcKgPgV+d0jkh7hWgvdF3H5fe1+D5N06n2+zCqPgyGU/8b21Q8u8kSlb/le/fu5auvviInJ4dBg2rPd3322WdZt24d3333HRZL4zuj5Ofnk5iYSHZ2dp1zeXl54WviUYuStMcffzxa7RAxStN0thfXHu58ZdsK/qdyPSxb3+i9mVYHnR0pdLGn0NmeQhdH3c/JZhuKoqCqKvPmzcNsqDvnqTGurYsh4MfSMQ9LVssmxLcXpTULBtKHdMdgav7r66ueC+iYbCMwmLpSX5L2t+8Oouk66YkJ/KxXWmQaLEQ74fL7SHzr0bZuRpOctzyNw1x3vtipUFWVX/ziF3i9Xp577jmMxmO/m3788UeefPJJHn74Yc4666wmY1VUVNChQ4d6z4Xm0VdUVESm4a1MkjTRqMIyN25Vw2I00DM9ONy19HBwflNeUiaD03Po4kilsz251udOCcnYTE2XajlVTim90aiAR6VsS3AngIxhuc2+TwuU46teAIA18Tr0Bq77eGNwVefYPvX/ghRCiBOFVmwuW7aMu+66i1/84hfhcz6fj9tuu43evXtLzsFJDHc+/fTTVFdX88QTTzRYL83n8/HEE0+QlJTE73//+1NupGg7W48Ehzr7ZDkwGYPrTLZXFgPwl+FXcUm3/m3WNpD5aE0p27QXXQ1gy0rG3jm92ff5qj8DfBjMeRgtQ+rdrP5ItY+th0oBuFNWdQrRYnaTBectT7f4Pk3TqayqJDkpOWLDnY3Fs5saH25s2WNp3HHHHcyZM4dbbrmFv//977XOP/vss2zcuJGVK1fWu9qzPikpKQ32lFVWVoaviUctWt351Vdf8dhjj5GRkdFoQVuLxUJGRgaPPvooixcvPuVGirYTXjRQM9SpagF2Vx0FoG9yVpu1C8B3ZDe+wzvBaMLev/4iq+3d0XUFQLAXrblzSnTdh6/6UyDYi9bQfX///iCappPqsDG+V2okmitEu6IoCg6z9SQ+LDhMluDnk7q/ZfEiNR9N0zRuv/123nzzTW688UZmz55dpyzG+vXr0TSNESNGoChK+GPs2ODv+NmzZ2M0Grn66qvD9+Tl5eF0OikqKqrzmKG5aKG5afGmRT1p//73v0lLS+O+++5r8tpf//rXPPvss8yaNSv84or4c2xlZ3DRwM7KEvy6hg0jne3Nr5kXDaGhTnvvkRgTpMr9ibylTpwFxaAE9+psLtW1CF0rRzF2wJxQd9l8yNyfgkOdY/I6xGX9ISFE6wklaP/+97+ZPHky//nPf2rNQwsZN24cmZmZdY4fOnSIefPm0adPH0aNGsWwYcPC5y644AJWrVrFwoULufXWW2vdt2DBgvA18ahFSdrKlSu5+OKLm9UFabVaufjii+O60q84Vsg21JO2rSJYcLaLMaHNV+7KVlCNK/9xLwBJvTpiSam/fMaJdF3DW1O81ur4OYpS/6+Ioy6VzQeCQ52/lFWdQohGhIY4//3vf3Pdddfx1ltv1ZugQbCDpz5Llixh3rx5jBw5kjfeeKPWG8Pbb7+d559/nqeffpqrrroqPLS5YcMG3nnnHfr378+oUS0rkh4rWpSkHTx4kJ49ezb7+h49evDpp5+2uFEiNui6XqeQ7dbyYJLW2di8P/rRogf8VG/5GpD5aPXSdcpqkrSWbAPl965B8+8FxY7FMbHB615fc5CAppGUYOXyPs2f6yaEaH+efPJJ3nzzTRITE+nTpw9/+MMf6lxz9dVXN1qwtjF9+vRhxowZTJ8+nSFDhjBp0iSqqqp49913AeokdfGkRUmawWBAVZtX/wqCS2zj9YURcLjKS7lbRVGgT1bdnrS25N69Gs1diTExA1vusKZvaGcsVRq+Mg8Gi4m0Ac2f1B8qXmtxTEQxNFy8+IMfg0Odo3vLUKcQonEFBQUAOJ1Onn66/oUSubm5J52kATz66KPk5uby0ksv8dprr2GxWBg9ejRPPfVUraHReNOiJK1Tp04t2kVg06ZNdO4sQyHxKtSL1iPdToI52DV9LElr254058bgPAPHGRejtLC2WnvgKAkAkDaoKwZL8/6bB3z5BLzrAQNWxzUNXlfh8bNxf3DxyO1ny/9vIUTjZs+ezezZs08pxoUXXkggEAiv1qzPzTffzM0333xKjxNrWvQWePTo0XzzzTfhrLgxBQUFfPPNN3G5DYMICi0aGHDcTgOx0pMm89EapqkBEo4Gk7SMM5s/1BnqRTMnXIjB1PAWT2+sOYQ/oJFos3DNgIxTa6wQQogGtShJ+/Wvf42qqlx77bWUlJQ0eN3Ro0e57rrr8Pv93HPPPafcSNE2wttB1ezZedBVSZXqxagYyDa0XZIWqC7DvXs1IPPR6lOx7SAGDcypdhJzm1cmRQsUo7qXAMGyG415/8eDAIzsJUOdQggRTS0a7hw2bBi//e1veemllxgwYABTp05l7NixdOkSnPNy4MABvv76a15//XWKi4t58MEH43osuL07cdFAqBetZ2I6ZqXt/jhXb/kGdA1rpwGY09tHEVVd19F8fjSvn4BXJeD1o3nVE74OngvtMJA2pDtKMwtdep0fAQGMliEYLX0avM7pC7BhX3Co87azmr8PqBBCiJZr8Y4DL7zwAjabjT//+c88/fTTdSYB6rqO0Whk2rRp9a7gEPHjWCHb4HDn1vLDAPRNyQJXmzXr2Hy0OO1F03Udf7UXT3El1UVlJO9TOfDFenRVq5Vs1UrIfCoN7s1U32MAaUO6Ne9arRpf9RcAWBOvbfTaN9cfQfUHsFvNXD+wbYsZCyHE6a7FSZqiKDzzzDP88pe/ZNasWaxcuTJc5Tc7O5vzzz+fKVOm0KtXr4g3VrSeCrfKwUoPcGy4M9ST1i+lA7i0NmmXrutUb46P+Wh6QMNb5sRTXIWnuPK4jyoCbl/4umTg6MHdzQuqKBitJgxWE0aLGaPNfNzXJgwWM5gNbD28B2tGw6szj+dzzQe9GoOpKybbiEavfe+n4P/1ET2ywtuECSGEiI4WJ2khvXr1kp6y01hoqDMn2UpKQnALsG0VwT07+yVnwaHDbdIu3+F81JJCFJMFR7/YWJTid/vwltRNxDxHq0BroPtLAUuqA2tmIocqS+jZNw+z3YrRWpN0Wc01yZi51tcGs7HJIsKqqrJ+3t5mtV3XAzVDnWBJnITSyDC2T1NYVxici3rLWbKqUwghou2kkzRxeju2aODYdktbK4KJWb+ULEpomyStemPNVlB9RmOwOlr1sTV/gKpdh0ks8rP/83X4jlbjKanEX+Vp8B6D2YgtKxlbVjLWzKTw17bMRAxmE6qqsnXePLIvOqPR/XCjRXUvQw8cRjGkYLE33jP5bYUdn9+NzWLiliEdWqmFQgjRfkmSJup14sbqlT4PB13B+jR9krNoeG1vdDk3te58NF3Xqd53lNL1BZRu3EvA5SMVKC3cU+s6c3ICtuOTsKxkbFlJmJPtzZ6839p0XccXLl57FYrS+HZv35YE69ENz83CLEOdQggRdZKkiXqFhjtDNdJC89GyE5JItbRN+Q3d76N662Ig+qU3vKVOjq4voHRDId6jVeHjpkQblWYfuQPzsGen1vSKJWO0tX4v2KkK+DYSULcDZiyOKxu91qsG2FoS7DG8eZgMdQohRGuQJE3Ua2sDG6v3T2m7YS7XzlXo3mqMyR2wdh0c8fh+t4+yjXspXV+As/BYX6HBbCT1jC5knJmLrVsG87+cz4iLB7bJ8GQkhYvX2sdjMKY1eu27m0rwqn6sZhO/GCpDnUII0RpiNklbs2YNjz/+OCtXrkRVVQYNGsSDDz7I9ddff1LxysrKGDhwIAcPHmTChAl8+eWXEW7x6cOjBthTGqyxUWdlZ2rb/YEO7TKQOHA8SoSKqGr+AJU7DnF0fQEV2w6iB2pWrSqQ1KsjGWfmkjqgC0ZrMCFryd61sSyg7sPvWQU0XXYD4O0NwVWdZ3XPCG8RJoQQIrpiMklbvHgxEyZMwGazccMNN5CUlMTcuXOZPHky+/bt46GHHmpxzPvuu4+KioootPb0s6O4Gk2H1AQzHZOC85S2lh9XfqONRKo+Wn3zzEISslNIH5pL+pDuWFLadn/SaPJVzwV0TLYRGM2N11NTAxrfFwR7FicPyWmF1gkhhIAYTNL8fj933XUXBoOBZcuWMXToUAAee+wxhg8fziOPPMK1115L9+7dmx1z7ty5zJkzh7/+9a/cd999UWr56WPLcdtBhco9HBvubHhPx2jyVxbjKVwHBDdVPxneUielGwo4ur72PDNzko30Id1JPzMXe07jw36nAy1Qga86mPA2tQUUwBs/HMLtVTGbjNw2RArYCiFEa4m5JVrffPMNu3bt4qabbgonaAApKSk88sgj+Hw+3nzzzWbHKy4u5p577uEXv/gFl112WRRafPo5cWWnqgXYWRnsSWmrnrTqLV+DrmPtOhhzavN7cxS/ztEfdrP9H1+x6fn/cvCrTXiPVmEwG0kf2p282y9g0O+upMvEM9tFggbgq/4M8GEw52G0DGn0Wk3T+MOiHQAM7ZiA3SJDnUII0VpiLklbsmQJAOPH1x3SmjBhAgBLly5tdrypU6diNBp5+eWXI9K+9mDrkdo10nZVHsWvazhMFro4UtqkTeH5aIMmNOt6XdM48MUGOq3zcODz9cGFAAok9e5I7rXnMviRq+lx/Xkk5+VEbH5bPNB1H77qT4BgL1pThXH/9O0+DpU5MRkN3NG1DfcCE0KcVp577jkURUFRFL777rs65/Pz87n99tvJy8sjISGBzp07M378eObNm9dgzLfffpvhw4fjcDhIS0vj8ssvZ926ddF8GlEXc8Od+fn5AOTl5dU5l52dTWJiYviaprz11lt89NFHfPLJJ6SlpcmctGY6sSft+O2gmvqjHg26rrd4PlplfhFHV+9CAWwdk8k4s8dpP8+sOVTXV+haOYoxC3PCBY1e61UD/Omb4P+1KwZ3IcdS0AotFEKc7jZt2sTjjz+Ow+Ggurq6zvnvv/+esWPHoqoqV155JZMmTeLIkSN89NFHfP311+zYsYMZM2bUuufpp59m+vTpdO/enalTp1JVVcW7777LyJEj+frrrzn//PNb6dlFVswlaaFEKiWl/h6b5OTkZiVbBw8e5P777+fGG2/kqquuanE7vF4vXq83/H1lZbCQq6qq4RV+J36OhLaO6Q9o7CgOJml5GTZUVWVz6SEA+iRl1vv8o91G74HN+MsPophtmHuc26zHLV4b3AvT2cFI/7suDJfLONU2R/q5t+Zrqesanqpg2Q1TwlX4/TrQ8OM+uqiAMqcbq9nE8+Nz2biqIC6f9+keMx7aGI2Y8dBGCM6zhuCbTU2LzJ7Huq5HNGak4zUWU1VVbrvtNoYOHUrv3r15++230TSt1jUzZszA7Xbz0Ucf1fr7PX36dIYOHcqf/vQnfve732G1Bhe25efnM2PGDPr06cN3330Xzh+mTp3KyJEjueuuu/jpp58wnDBqEonnrWkauq6jqipGo7Hen6FT+XlS9FArY8T48eNZtGgR+fn59O7du875zp0743Q6m0zUJk6cyNq1a9m8eTOZmZkAFBQU0KNHj2aV4JgxYwZPPPFEneNz5szBbj99e2MOuuHeNQYsBp13z9cxKPCyczuLfUe4KaE71yc0vhIwGlLzPyNr47+o7nAmB0c93uT1il+n0zoPig6HB1pRHe1nOLMx6SkFDM77DH/AzKqf7iAQaHiHAbemcOcaC9VelYk9E/lVl8pWbKkQpw+TyUR2djZdu3bFYrG0dXPa3B//+EdeeukllixZwl/+8hfeeecdFi5cyDnnnBO+Zvjw4ezcuZOioqI6r9mECRNYvXo1u3btIj09HYAnn3ySF198kddee40bbrih1vW//vWvmTNnDv/973+j0pvm8/nYt28fRUVF4YT8RC6Xi5tuuomKigqSk5NbFD/metJCGXBDSVhlZSVpaY1P8H7zzTeZP38+H3zwQThBa6lp06bx4IMP1nrcrl27Mn78+PCLrKoqixYtYty4cRErbNrWMT/fcgTWrKN/x2Quvyz4A/30/D1wFK48ZxQTuw1s9TYeeOk1XED3C29k6PiJTcY6+sNuDqxdjzUrCdWuxvS/T2u+lp6y36OpYEu8ggkTft5ojKmf5VPt3YXDZuHNW0dgN+px+7xP95jx0MZoxIyHNgI4nU52796Nw+EgISEyu7Xouk5VVRVJSUkRmYIS6XgNxVy3bh0vvPACTzzxBMOHDw+/xg6Ho1byMmjQIPLz81mxYkWtnrTCwkK2bt3KkCFDyM3NDR8PzWm78sor6yRBl112GXPmzGHt2rVceumlEX/eHo+HhIQExowZg81mq/dnKDQSdzJiLkkLzUXLz8/nrLPOqnWuqKgIp9PJ8OHDG42xfv16AK67rv7yAgsWLEBRFIYMGcKGDRvqvcZqtYa7Uo9nNpvr/Oet79ipaquY+UfdAAzITsZsNqPrOttrVnYOTM+pdX9rtFHzeXDvWAZA8pCJzXq88p/2AZA2tDtU7oqLf59otzHg24mmbgAMJCRfi8HU8GMVVXl5e00hAFPP70VmUkK4uz7ennd7ihkPbYxGzFhvo8kU/DOrKEq9w226r+ULcnRNQ/NWo1uNEVn41FQ8xWJvcRITGj4MPW+v18uUKVMYOnQov/vd7zAYDOGYBoOh1mvz9NNPs3LlSq6//nquvPJK+vTpE56Tlpuby7vvvlvr+vz8fBITE+nUqVOddvTt2xeAnTt31nn9T2zjyQg9jxN/Zo7//lR+lmIuSbvgggt49tlnWbhwYZ1uywULFoSvacx5552H0+msc9zpdPLee+/RpUsXJkyYQLdurT90F+tO3A7qkLuSStWDUTHQO/nkeiVPhSt/ObrPjSm1E9bOA5q83nO0iurCElAU0oZ0g293tUIrY194C6iECzCYGq91d99nO/CqftIcCTw9rkdrNE+Idkn3udj2q8STvr8ogm1pLF6/150oVscpxX7sscfIz89n7dq1GI2Nl/Lp168f3333Hddddx0fffRR+HhGRgY333wzvXr1qnV9RUUFHTrUXx4q1LMWrwsHYy5Ju+iii+jZsydz5szh/vvvD9dKq6io4JlnnsFisXDrrbeGrz906BAVFRXk5OSEh0onT57M5MmT68QuKCjgvffe44wzzmDmzJmt8nzizZbQys7QdlA1Ow30TErHamz9H5dQ6Q3HwPHNeidXuq4AgOS8bMxJbbMRfKzRAsWo7uDG9JYmitfuPOrm0x/3AvA/P8vDKltACSFO0apVq3j++eeZMWMGAwcObPL61atXc/XVVzNo0CDWrl1Lv379KCoq4pVXXuH3v/89P/zwAx988EErtLztxVySZjKZmDlzJhMmTGDMmDG1toUqLCzk+eefrzUWPW3aNN58801mzZrFlClT2qzdpwNd19l2JFR+I1gjbWtF224H5Txuv86m6JrO0fV7AMg4MzeazYorXudHQACjZQgmS99Gr733k634AxrZqQ5+P6Zr6zRQiHZKsdjp93rdUZ+maJpGZWUlycnJJz1M15J4iuXkF8v5/X5uu+02Bg8ezO9///smr1dVlRtuuAGDwcDHH38cXqjXs2dPXnjhBfLz8/nwww9ZsWJFeCFASkpKo/PYQ9fEo5hL0gDGjh3L8uXLefzxx3nvvffCG6w/99xz9faQicg4UOGhyuvHaFDIywx2bR/bDqr1kzR/eRHevT+CouAYOK7J650FxfjKXRisZlIHdCZATC1cbhO65sJX/QXQ9EbqPxyo4uutBwF44pL+EfnlL4RomKIoJzeMqGkYrAEMVkdk/p9GOt5xnE5nuLZpQ6tbzzvvPAA+/vhjevXqxZ49e7jmmmvqraQwevRovvjiC9avXx9O0vLy8li1ahVFRUVkZ2fXur6x2qvxICaTNAguwZ0/f36T182ePZvZs2c3K2Zubi4xVnEkpoSK2PbKsGMxBf+jhgvZprZ+kubcvAgAW/dhmJKang8X6kVLH9QVg9lEIIK1juKVzzUf9GoMpq6YbCMavfa+T7ei6To9O6Twq3NkI3UhxKmzWq388pe/rPfcsmXLyM/P58orryQrK4vc3Fx8Ph8Q3NKxPiUlJeG4IRdccAGrVq1i4cKFtaZDQfPnsseqmE3SROsLbQc1oGaoE2BredsNdx4/H60pAZ+fso3BVZ0Zw2SyO4CuB/A65wJgSZyEojT8DvmrXWV8v+swAH+6vH+rtE8IcfpLSEhocA74lClTyM/PZ9q0aYwYEXwT6fV6SU5OZsWKFSxcuLDWFpH79u1j9uzZKIpSK+m6/fbbef7553n66ae56qqrwkObGzZs4J133qF///6MGjUqis8yeiRJE2EnbgdVpXo44AqO87d2kqZrWrgnrTnz0cq37Efz+bGkO3B0b/1VqLEo4F2BHjiMYkjBYm/8NfztZ1sBGNQ1k0lnZLVG84QQog6r1cqf//xn7r77bi699FIuv/zy8MKBjz76CKfTyYMPPkifPn3C9/Tp04cZM2Ywffp0hgwZwqRJk8LbQgG88cYbcTt9Q5I0Ebb1SO2Vndsrgt3NHROSSLO27i4L3n0/Eag4jGJ1YM8b2eT1R9eFFgz0aJP9RWOPjt/1IQAWx5UoSsO7C7y/sZjN+4+iAC9fKb1oQoi29atf/YoePXrw8ssvs3LlSr744gsSExMZNmwYN998M3feeWedex599FFyc3N56aWXeO2117BYLIwePZqnnnqKYcOGtcGziAxJ0kTYsRppNSs7w0Odrd+zElrV6eg/FsXU+FYqvgoXVTVDdbKqMygl8SCafwdgxuJoeO9aTdP4//67BYDzemcztmdq6zRQCNHuNTanfNy4cYwbV3vBWGgVakNuvvlmbr755kg2sc3FZ/+fiLij1T6OOIMTNvuFaqSFV3Y2Xvw0GqpbUHqjdEMB6JCYm4U1/eQLQ55OunYM7rphto/HYGx4G7W/rzlEYUklBoPCq1dLL5oQQsQSSdIEcKwXrWuqjURrsIN1WxvVSNO8Llw7vgWaXjSg6zpHawrYZgzLjXLL4oPmP0BG6m6g8bIb/oDGEwu2AzCuf2eG5kiCK4QQsUSGOwVw/Hy041d2BocQ+7dy+Y3qbUvR/T7Mmd2xZPdp9FrXgVI8xZUoZiNpA9vnNl+67kUPlKNrFWhaOWr1f1EUMFiGYzQ3/Jr8cdlejlRUYzYa+dtV/VqxxUIIIZpDkjQB1F3ZqWoBdlYdBVq/Jy1ceuOMpreCCvWipQ3ogtEW2U2W24Ku66B70LVyNK0CXSuvlYAFv6+odR7dU28ss31Sg4/jVgO8sDhY5PHnZ3ajZ4ZsoSWEELFGkjQB1K2RtqeqFFULYDeZ6eJo3e00wvPRBjU+1Kn5A5T+WAhAehwsGND1ALpWiuYvQgsUoQWO4PcdZFDeVtyl83DrleiBcsB3EtFNKIYUFGMqkMyuAgsDsgY3ePUjC3dTXu3BZjHxypWN91YKIYRoG5KkCaBuT1poqLNfSgcMjRRBjTS1dD/eg1tAMeAYcFGj11ZsP0TA7cOcnEBy79Zf3HAiXQ+gB0pqErDDNcnYYbTAYXR/MCmDQJ37MlJA95941IJiTEUxpGAwBD+HkjCDIQXFkBr8MAbPozjCvY6qqlK4ah5nnFl/L2SFx8/rK3YBcOu5PejgaHz1rBBCiLYhSZqg2uunsMwNHKuR1laLBlxbvgIgoedwjI6GVyXCsdpo6UO7o7RCoUJd19ECh0lN2offvZCAu7gmETuCFihCDxQDWhNRjCjGDhiMHTGYOoKSxcZNhxgydAwmS2Y4AUOxRa3e22/+uwOXVyUxwcILl/aOymMIIYQ4dZKkCbYXB3vRMh0WMhODRU+3tlWSVrPLQFOrOlWnh4rtwc3AM86M3jZQuu7F792A37Mav+d7tMAhhvYFX1VDd5gxGDtgMHVEMXbEYMzGYOoYTMqM2SjGDBTFeOx5qCpFR+cxzHouJnP059QdqPTyzpoCAO4b3Tu8klcIIUTskd/Qgi0nDHXCcTXSWnNlpx7AteVroOn6aGU/7QVNx945jYSOkZ0zp/kPotYkZX7vBmrPETNR7U4iKaUnJlMOiqkmEavpGVMM6Y3ukdnW7vt0Oz5/gIykBJ68WPY4FUKIWCZJmji200DNUKeu620y3Gkt34NWXYohIZmEnsMbvfbo+mPbQJ0qXffh9/4U7C3zrkbz76t1XjF2wGwdjsl2LrphIEu+XMzEiRMxt0LPVyRtPVLN5z8Fn9vvL+qL2Ri7yaQQQghJ0gTH1UirWdlZ5K6iwufBoCjkJbfellD2w8Eq+Y4BF6GYGk6A3IcrcB0oA4NC+pDuJ/VYmv8wqnd1TWK27oQyFkaMloGYbedisp2LwdS91qT8ePXrT7cR0DQ6pyfx4Pmd27o5QgghmiBJmji2svOERQM9EzOwGlvvR8R+ZAPQ9Hy0UC9aSt9OmBwNbxx+PF1XCfg21QxjrkbzF9Q6rxgyMNmGY7YNx2QdhmI4varvr95fxZLthwB46tJ+GFphoYUQQohTI0laO6cGNHaWVAPHaqSFhzpTW68XTfNUkXB0G9D4fDRd0yjdEKyNljGs8aFOXSsnO3Mz3oq1uHzrQXcdd9aA0TIgmJhZz8Vg7hW11ZSx4Ncfb0HXdfKy07h9WHZbN0cIIUQzyNvpdm5nSTV+TSfRaqRLqg2AreWtPx/NtW0pih7AnNULS4eeDV5XufMwaqUbY4KFlL45DV6nBYpxH51Kv9yvCXhXgO5CMaRiThhHQtp0knLmkpj1MrakmzFaep/WCdq8HUf5oSD4b/r8FbL9kxCi9Wmaxl//+leGDRuG3W4nOTmZMWPG8NlnnzV4z549e7jrrrvo3r07VquVnJwcrrjiCj744IN6r3/77bcZPnw4DoeDtLQ0Lr/8ctatWxetp9QqpCetnQsNdfbrkBhOVMIrO1OiUyBW13U0dyWB6lICzlIC1aVUrngTAPvAcY3eG66NNqQ7BpOxweu8zrmgl+PxJpGUfjUW+wiM5j4xvfIyWh76PNhDObRbFlf2y2zj1ggh2htd17n++uuZO3cuvXr14pe//CVer5dPP/2Uq666ildeeYX77ruv1j2LFi3i6quvBuCKK66gZ8+elJaWsn79er7++msmT55c6/qnn36a6dOn0717d6ZOnUpVVRXvvvsuI0eO5Ouvv+b8889vracbUZKktXOh7aCO31i9uSs79YAfv6eiVrIV/lxdihb63lVW63igugy0upX3AewDLm7w8QIelfItBwDIGJbbcLu0KnzV/wVgx96xjOh6c6vUIItFb/94mG0HS1EU+MtV/du6OUKIdmju3LnMnTuX888/n0WLFpGQENwr+JlnnuHss8/mf/7nf7j88svJzc0FYO/evVx77bV07tyZr776im7dugHB3rjKykrsdnut+Pn5+cyYMYM+ffqwevVqUlKCZZnuvfdeRowYwV133cWmTZvici6uJGnt3Jai2jXSnKqXfdXlAPRroEZa9U/z6fHFbez8qOKUHlux2DEmpmN0pGOwp3FIddB70KUNXl+2aS+6P4AtKxl75/QGr/NWfwa6G8WYS2nFya3+PB1omsa0L4K9aKPychid27p7sAohBMCnn34KwCOPPBJO0AAyMzN54IEH+O1vf8usWbN44okngGDyVllZyccffxxO0I5nMtVOXWbNmoXf7+fRRx8NJ2gAQ4cO5cYbb2T27NksX76cMWPGROPpRZUkae3csZ60YJK2vaIYgA62RNKt9nrvqVj6OibvsQTNYE/B6Eg/9pEY+jqt1jHD8eftaRgstnAMVVX5ad68RktvHF1XAAQXDDQ0h0zXvficHwFg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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "yesterday = datetime.date.today() # - datetime.timedelta(days=1)\n", + "duration = '[' + str(yesterday.day) + 'd]'\n", + "\n", + "metrics = (\n", + " \"optical_security_loop_seconds_bucket\",\n", + " # \"DbscanServing_Detect_histogram_duration_bucket\",\n", + " # \"OpticalAttackDetector_DetectAttack_histogram_duration_bucket\",\n", + " # \"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_histogram_duration_bucket\",\n", + " # \"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_histogram_duration_bucket\",\n", + ")\n", + "\n", + "for prom_metric in metrics:\n", + " response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": f\"{prom_metric}\",\n", + " \"start\": time.mktime(datetime.datetime(2023, 1, 29, 16, 9, 0).timetuple()),\n", + " \"end\": time.mktime(datetime.datetime(2023, 1, 29, 21, 15, 0).timetuple()),\n", + " # \"start\": 1670202754,\n", + " # \"end\": 1670217754,\n", + " \"step\" :60,\n", + " }\n", + " )\n", + "\n", + " parsed = response.json()\n", + " # print(parsed)\n", + "\n", + " cdf = {}\n", + " for load in loads:\n", + " cdf[load] = {}\n", + " \n", + " for metric in parsed[\"data\"][\"result\"]:\n", + " for load, _time in zip(loads, times_services):\n", + " if float(metric[\"metric\"][\"le\"]) not in cdf[load]:\n", + " cdf[load][float(metric[\"metric\"][\"le\"])] = []\n", + " # print(metric[\"metric\"])\n", + " for value in metric[\"values\"]:\n", + " if _time[0] < value[0] and value[0] < _time[1]:\n", + " # print(load, metric[\"metric\"][\"le\"], value)\n", + " cdf[load][float(metric[\"metric\"][\"le\"])].append(float(value[1]))\n", + " # break # stops the loop over values when the first one is found\n", + " # print(\"\\tmetric:\", metric[\"metric\"][\"le\"], type(metric[\"metric\"][\"le\"]))\n", + " # print(\"\\tvalue:\", metric[\"values\"])\n", + " \n", + " # defining the minimum and maximum x\n", + " min_x = 0\n", + " max_x = len(cdf[load].keys()) - 1\n", + "\n", + " plt.figure()\n", + " plt.grid()\n", + " # plt.title(prom_metric)\n", + " for load in loads:\n", + " diff = 0\n", + " probabilities = np.zeros((len(cdf[load].keys()),))\n", + " i = 0\n", + " for key in sorted(cdf[load].keys()):\n", + " if cdf[load][key] == float('Inf'):\n", + " continue\n", + " if i == 0 and prom_metric == \"optical_security_loop_seconds_bucket\":\n", + " diff = np.mean(cdf[load][key])\n", + " # print(i, key)\n", + " probabilities[i] = np.mean(cdf[load][key]) - diff\n", + "\n", + " # find lowest x\n", + " if i > 1 and probabilities[i-1] == 0 and probabilities[i] > 0:\n", + " min_x = i - 2\n", + " \n", + " # find highest x\n", + " if i > 0 and i - 1 < len(cdf[load].keys()) \\\n", + " and probabilities[i] > probabilities[i-1] \\\n", + " and prom_metric != \"optical_security_loop_seconds_bucket\":\n", + " max_x = i - 1\n", + " \n", + " i += 1\n", + "\n", + " probabilities[i-1] = np.mean(cdf[load][float('Inf')])\n", + "\n", + " probabilities = probabilities / probabilities.max()\n", + "\n", + " if load == 480:\n", + " curves_specific_load[prom_metric] = probabilities\n", + " \n", + " plt.plot(range(len(cdf[load].keys())), probabilities, label=load)\n", + "\n", + " plt.xticks(range(len(cdf[load].keys())), [x for x in sorted(cdf[load].keys()) if x != float(\"Inf\")] + [\"Inf\"], rotation=90)\n", + " plt.xlabel(\"Completion time [milliseconds]\")\n", + " plt.ylabel(\"CDF\")\n", + " plt.xlim([min_x - 0.25, max_x + 0.25])\n", + " plt.legend()\n", + " plt.tight_layout()\n", + " plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"cdf_{prom_metric}.pdf\"))\n", + " plt.show()\n", + " plt.close()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "'data'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [17], line 30\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[39mfor\u001b[39;00m load \u001b[39min\u001b[39;00m loads:\n\u001b[1;32m 28\u001b[0m cdf[prom_metric][load] \u001b[39m=\u001b[39m {}\n\u001b[0;32m---> 30\u001b[0m \u001b[39mfor\u001b[39;00m metric \u001b[39min\u001b[39;00m parsed[\u001b[39m\"\u001b[39;49m\u001b[39mdata\u001b[39;49m\u001b[39m\"\u001b[39;49m][\u001b[39m\"\u001b[39m\u001b[39mresult\u001b[39m\u001b[39m\"\u001b[39m]:\n\u001b[1;32m 31\u001b[0m \u001b[39mfor\u001b[39;00m load, _time \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(loads, times_services):\n\u001b[1;32m 32\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mfloat\u001b[39m(metric[\u001b[39m\"\u001b[39m\u001b[39mmetric\u001b[39m\u001b[39m\"\u001b[39m][\u001b[39m\"\u001b[39m\u001b[39mle\u001b[39m\u001b[39m\"\u001b[39m]) \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m cdf[prom_metric][load]:\n", + "\u001b[0;31mKeyError\u001b[0m: 'data'" + ] + } + ], + "source": [ + "yesterday = datetime.date.today() - datetime.timedelta(days=1)\n", + "duration = '[' + str(yesterday.day) + 'd]'\n", + "\n", + "metrics = (\n", + " # \"optical_security_loop_seconds_bucket\",\n", + " \"DbscanServing_Detect_histogram_duration_bucket\",\n", + " \"OpticalAttackDetector_DetectAttack_histogram_duration_bucket\",\n", + " # \"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_histogram_duration_bucket\",\n", + " \"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket\",\n", + " # \"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_histogram_duration_bucket\",\n", + " \"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket\",\n", + ")\n", + "cdf = {}\n", + "\n", + "for prom_metric in metrics:\n", + " response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query_range\",\n", + " params={\n", + " \"query\": f\"{prom_metric}{duration}\",\n", + " \n", + " }\n", + " )\n", + "\n", + " parsed = response.json()\n", + "\n", + " cdf[prom_metric] = {}\n", + " for load in loads:\n", + " cdf[prom_metric][load] = {}\n", + " \n", + " for metric in parsed[\"data\"][\"result\"]:\n", + " for load, _time in zip(loads, times_services):\n", + " if float(metric[\"metric\"][\"le\"]) not in cdf[prom_metric][load]:\n", + " cdf[prom_metric][load][float(metric[\"metric\"][\"le\"])] = []\n", + " # print(metric[\"metric\"])\n", + " for value in metric[\"values\"]:\n", + " if _time[0] < value[0] and value[0] < _time[1]:\n", + " # print(load, metric[\"metric\"][\"le\"], value)\n", + " cdf[prom_metric][load][float(metric[\"metric\"][\"le\"])].append(float(value[1]))\n", + " break # stops the loop over values when the first one is found\n", + " # print(\"\\tmetric:\", metric[\"metric\"][\"le\"], type(metric[\"metric\"][\"le\"]))\n", + " # print(\"\\tvalue:\", metric[\"values\"])\n", + " \n", + " # defining the minimum and maximum x\n", + " min_x = 0\n", + " max_x = len(cdf[prom_metric][load].keys()) - 1\n", + "\n", + " plt.figure()\n", + " plt.grid()\n", + " # plt.title(prom_metric)\n", + " for load in loads:\n", + " diff = 0\n", + " probabilities = np.zeros((len(cdf[prom_metric][load].keys()),))\n", + " i = 0\n", + " for key in sorted(cdf[prom_metric][load].keys()):\n", + " if cdf[prom_metric][load][key] == float('Inf'):\n", + " continue\n", + " if i == 0 and prom_metric == \"optical_security_loop_seconds_bucket\":\n", + " diff = np.mean(cdf[prom_metric][load][key])\n", + " # print(i, key)\n", + " probabilities[i] = np.mean(cdf[prom_metric][load][key]) - diff\n", + "\n", + " # find lowest x\n", + " if i > 1 and probabilities[i-1] == 0 and probabilities[i] > 0:\n", + " min_x = i - 2\n", + " \n", + " # find highest x\n", + " if i > 0 and i - 1 < len(cdf[prom_metric][load].keys()) \\\n", + " and probabilities[i] > probabilities[i-1] \\\n", + " and prom_metric != \"optical_security_loop_seconds_bucket\":\n", + " max_x = i - 1\n", + " \n", + " i += 1\n", + "\n", + " print(prom_metric, load, cdf[prom_metric][load].keys())\n", + " probabilities[i-1] = np.mean(cdf[prom_metric][load][float('Inf')])\n", + "\n", + " probabilities = probabilities / probabilities.max()\n", + " \n", + " plt.plot(range(len(cdf[prom_metric][load].keys())), probabilities, label=load, marker=\"*\")\n", + "\n", + " plt.xticks(range(len(cdf[prom_metric][load].keys())), [x * 1_000 for x in sorted(cdf[prom_metric][load].keys()) if x != float(\"Inf\")] + [\"Inf\"], rotation=90)\n", + " plt.xlabel(\"Completion time [milliseconds]\")\n", + " plt.ylabel(\"CDF\")\n", + " plt.title(prom_metric)\n", + " plt.xlim([min_x - 0.25, max_x + 0.25])\n", + " plt.legend()\n", + " plt.tight_layout()\n", + " plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"cdf_{prom_metric}.pdf\"))\n", + " plt.show()\n", + " plt.close()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cdf[\"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket\"][480]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "'OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [24], line 17\u001b[0m\n\u001b[1;32m 15\u001b[0m x_values \u001b[39m=\u001b[39m []\n\u001b[1;32m 16\u001b[0m y_values \u001b[39m=\u001b[39m []\n\u001b[0;32m---> 17\u001b[0m \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m \u001b[39msorted\u001b[39m(cdf[key][load]\u001b[39m.\u001b[39mkeys()):\n\u001b[1;32m 18\u001b[0m \u001b[39mif\u001b[39;00m v \u001b[39m!=\u001b[39m \u001b[39mfloat\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mInf\u001b[39m\u001b[39m\"\u001b[39m):\n\u001b[1;32m 19\u001b[0m x_values\u001b[39m.\u001b[39mappend(v)\n", + "\u001b[0;31mKeyError\u001b[0m: 'OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket'" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjwAAAGpCAYAAACJTOz3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAABFZElEQVR4nO3dfXRU9Z3H8c+9MyGJISThSTTyIAiIhoe2hkK1UEpNKK7rth6LsC2yq6J0Xa3S1sq2S2u7UK0edan1iS1ytJ5iRWV7TEhoIwQISmijmJZACCFEDA15mElgmWTuvb/9A2fKmAecYXLvd+58XudwejsTJr/rO5Af9zuZ0ZRSCkREREQupju9ACIiIqKBxg0PERERuR43PEREROR63PAQERGR63HDQ0RERK7HDQ8RERG5Hjc8RERE5Hrc8BAREZHrccNDRERErscNDxEREble1Buel19+GXfddReuueYapKamQtM0vPjii1F/YsuysG7dOkydOhXp6ekYMWIEFi9ejCNHjkT9WERERET9iXrD88Mf/hDPP/88GhoacMkll8T8ie+66y7ce++9UErh3nvvxYIFC/D6668jPz8ftbW1MT8uERER0SdFveFZv349jh49ipMnT+Luu++O6ZO+/fbbWL9+PebMmYM///nPeOSRR/DSSy/hzTffRFtbG+65556YHpeIiIioN95of8NXvvKVC/6kL7zwAgDgpz/9KQYNGhS+/atf/Sq+9KUvobS0FMeOHcOYMWMu+HMREREROfKk5e3btyMjIwPXXnttj/sKCwsBADt27LB7WURERORSUV/huVCnT59GU1MT8vLy4PF4etw/ceJEADjv83i6urrQ1dUV/v+WZaGtrQ3Dhg2DpmnxXTQRERENCKUUOjs7cemll0LXB+46jO0bHr/fDwDIysrq9f4hQ4ZEfFxf1q5di5/85CfxXRwRERE5orGxEZdddtmAPb7tG554eeihh/DAAw+E/7/f78eYMWNw5MgRDBs2DKZpAgA8Hk/EsWEY0DQtfKzrOnRd7/M4GAzC4/GEj71eLzRNCx8DgGEYEccpKSlQSoWPLcuCaZrhY8uy4PV6+zw2TRNKqfBxb+ch+ZyCwSA+/PBDjBkzBpqmueKcErVTMBjE0aNHMX78eGia5opzStROmqahoaEBubm5SEtLc8U5JWqnQCCA48ePY9y4ceHP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A7Rq97qQHkopFBcXY8WKFZg2bRqysrJw0UUXYfr06VizZg0CgcAAr95d4vFn41zt7e3Izc2FpmlYsGBBHFfqfvFq0dzcjPvvvz/8d9WwYcMwe/ZsPPPMMwOwaneKR4uPPvoI9913H6666ipkZGTg4osvxnXXXYeXXnop/IaY1L+XX34Zd911F6655hqkpqZC0zS8+OKLUT+OZVlYt24dpk6divT0dIwYMQKLFy/GkSNHYl+cEqisrEylpKSozMxMdeedd6oHHnhAjR07VgFQjz322Kd6DNM0VWFhoQKgZs2apR588EH19a9/XWmapsaPH6+am5sH+Czc40J7nDlzRgFQqampqrCwUH33u99V99xzj5o4caICoPLz89Xp06dtOJPEF48/G5+0ZMkSlZGRoQCowsLCOK/YveLVoqqqSo0YMUJ5vV510003qR/84AfqnnvuUfPnz1df/epXB/AM3CMeLerq6tTw4cOVpmlqwYIF6vvf/766++671ahRoxQAtWzZsgE+C3cI/XcfPnx4+HjDhg1RP84dd9yhAKirr75aff/731ff/OY31aBBg9TQoUPVoUOHYlqbuA1PMBhUEyZMUKmpqaqqqip8u8/nU5MmTVKDBg1SR48ePe/j/PrXv1YA1OLFi5VlWeHbn3nmGQVALV++fCCW7zrx6NHd3a1+9rOfqba2th6333jjjQqAevTRRwdi+a4Srz8b53rttdcUAPXLX/6SG54oxKuF3+9XY8aMUSNGjFDvv/9+r5+H+hevFitWrFAA1JNPPhlxe3t7uxozZowCEPWfr2S0bdu28H+ntWvXxrThKSsrUwDUnDlzVFdXV/j2oqIiBUAVFBTEtDZxG56SkhIFQP3Lv/xLj/tefPFFBUD95Cc/Oe/jzJ49u9cvUMuy1Pjx41VGRob6v//7v7it263i1aMvFRUVCoC64YYbLmSZSSHeLZqbm9WIESPUt771LVVfX88NTxTi1SL0DeF//ud/BmKZSSFeLUITgd6uHixZskQBUPv27YvLmpNFrBuexYsXKwBqx44dPe770pe+pACohoaGqNcj7jk827dvBwAUFBT0uK+wsBAAsGPHjn4fIxAI4N1338XkyZMxduzYiPs0TcP111+P06dPY9++ffFZtIvFo0d/UlJSAABerzfmx0gW8W5x9913w+Px4KmnnorL+pJJvFps2rQJmqbh5ptvxsGDB7Fu3To8+uij+N///V90d3fHdc1uFa8WeXl5AICioqKI230+H3bv3o1Ro0bhqquuusDV0qexfft2ZGRk4Nprr+1x34V83xH3Xaa/Nw8dNWoUBg8e3Ocbj4bU1dXBsqw+34D03DdB/eIXv3iBK3a3ePToz69//WsAvf9lRZHi2eLll1/G66+/jjfffBM5OTnw+/1xXavbxaNFd3c3PvjgA4wYMQLr1q3D6tWrYVlW+P7x48fjzTffxNSpU+O7eJeJ15+L733ve/j973+P+++/H1u3bsW0adPQ0dGBN998ExdddBHeeOMNpKenx339FOn06dNoampCXl4ePB5Pj/v7exPz8xF3hSf0F++57711riFDhpz3L+dP8xjnfhz1LR49+lJcXIznnnsOU6ZMwe233x7zGpNFvFp89NFHuPfee7F48WLcdNNNcV1jsohHi7a2NpimidbWVjz88MN49NFH8be//Q0ffvghfvSjH6G+vh433ngjf4rxPOL15+Liiy/Gnj17sGDBAmzduhWPPvoonn32Wfj9fixduhTTp0+P67qpdwP5/VvchoeSQ2VlJRYtWoSsrCz87ne/47sW2+iOO+5ASkoK/vu//9vppSS10NUc0zTx7W9/GytXrsTIkSORm5uLhx9+GLfccgsaGhrw2muvObzS5HD48GFce+21OHnyJHbu3InOzk40NjbiP//zP/HTn/4U8+fP54+mJzhxG57Qrq6v3VtHR0efO79oHuPcj6O+xaPHJ+3btw8FBQXQdR0lJSW4+uqrL3idySAeLTZu3Iji4mI8/fTTGD58eNzXmCzi+fcUAPzjP/5jj/tDt/G5hv2L199Ry5YtQ0NDA37/+9/juuuuw+DBg3HZZZfhBz/4Af793/8de/bswW9/+9u4rp16Gsjv3+I2PP3N506cOIFTp071+dyckPHjx0PX9T5nfP3NfClSPHqca9++fbj++uthWRZKSkqQn58ft7W6XTxaVFVVAQBuueUWaJoW/nX55ZcDAEpKSqBpGmbMmBHfxbtMPFpkZGQgNzcXAJCdnd3j/tBtZ86cubDFulw8WnR2dmL37t2YMmUKRo0a1eP+efPmAfj7nx8aOBkZGbjkkktQX1/f6xW1C/n+LW7DM3fuXABAaWlpj/tKSkoiPqYv6enpmDlzJg4ePIiGhoaI+5RS2LZtGzIyMnDNNdfEadXuFY8eIaHNjmma2Lp1Kz7/+c/Hb6FJIB4tZs+ejdtvv73Hr0WLFgEALrvsMtx+++34+te/HufVu0u8/lx8+ctfBgD89a9/7XFf6LZx48bFusykEI8WoZ+Ia2lp6fX+kydPAgBH7zaZO3cuTp8+jd27d/e4L9R0zpw50T9w1D/IPsCCwaAaP358vy8iVV9fH779o48+UgcOHFA+ny/icfjCg/ERrx779u1T2dnZavDgwWrXrl02rd5d4tWiN3wdnujEq8Xu3bvDrybb3t4evr2pqUnl5uYqXdfVwYMHB/hsElu8WkyePFkBUC+88ELE7e3t7erKK69UANS2bdsG8lRc53yvw3Py5El14MABdfLkyYjbk+aFB5WK7mXCb7vttl7/g/b21hI333yz0jRNXX755XxriShcaI/W1laVk5OjAKgFCxao1atX9/j1xBNP2HtSCSoefzZ6ww1P9OLV4oEHHlAA1OjRo9W3v/1tdeedd6qRI0cqAGrNmjU2nU1ii0eLoqIi5fV6FQA1f/589d3vflfdfvvtasSIEQqAuvnmm208o8T1wgsvqNtuu03ddttt6rOf/awCoK699trwbeduKFevXq0AqNWrV/d4nE++tcS3vvWt8FtLxPqPAJEbHqWUevfdd9WCBQvUkCFDVHp6upo5c6b67W9/2+Pj+vuLJBAIqB//+MdqwoQJatCgQWrUqFHqjjvuUCdOnLDhDNzlQnqEvpn292vs2LH2nUyCi8efjU/ihic28WqxYcMGdc0116iLLrpIZWRkqOuuu069/vrrA7x6d4lHi71796pbbrlFXXLJJcrr9arBgwer/Px8tW7dOmUYhg1nkfhC/337+nXbbbeFP7a/DY9pmuqpp55SV199tUpNTVXDhg1TixYtUocPH455bZpSSkU/CCMiIiJKHOKetExEREQUb9zwEBERketxw0NERESuxw0PERERuR43PEREROR63PAQERGR63HDQ0RERK7HDQ8RERG5Hjc8RERE5Hrc8BAREZHrccNDRERErscNDxEREbne/wPb4fWwsNqe+QAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# summary of response time\n", + "\n", + "labels = collections.OrderedDict({\n", + " \"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket\": \"Cache\",\n", + " \"DbscanServing_Detect_histogram_duration_bucket\": \"Inference\",\n", + " \"OpticalAttackDetector_DetectAttack_histogram_duration_bucket\": \"Worker\",\n", + "})\n", + "\n", + "\n", + "plt.figure() # figsize=(6.4, 3.2)\n", + "plt.grid(axis=\"both\", ls=\":\")\n", + "lss = [\"--\", \":\", \"-\"]\n", + "for i, (key, label) in enumerate(labels.items()):\n", + " \n", + " x_values = []\n", + " y_values = []\n", + " for v in sorted(cdf[key][load].keys()):\n", + " if v != float(\"Inf\"):\n", + " x_values.append(v)\n", + " y_values.append(np.mean(cdf[key][load][v]))\n", + " \n", + " x_values.append(float(\"Inf\"))\n", + " y_values.append(np.mean(cdf[key][load][float(\"Inf\")]))\n", + "\n", + " # x_values = np.array(x_values)\n", + " y_values = np.array(y_values)\n", + "\n", + " # x_values = x_values / x_values.sum()\n", + " y_values = y_values / y_values.sum()\n", + " # y_values = y_values.cumsum()\n", + " print(key, y_values)\n", + "\n", + " plt.plot(x_values, y_values, label=label, ls=lss[i])\n", + "\n", + "plt.xticks(range(len(x_values)), [x * 1_000 for x in sorted(x_values) if x != float(\"Inf\")] + [\"Inf\"], rotation=90)\n", + "plt.xlabel(\"Response time [milliseconds]\")\n", + "plt.xlim([-1, 12.25])\n", + "plt.ylabel(\"CDF of number of requests\")\n", + "plt.legend()\n", + "plt.tight_layout()\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"cdf_summary_response_time.pdf\"))\n", + "plt.show()\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '+Inf'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '+Inf'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '+Inf'}\n", + "480 +Inf [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '+Inf'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '+Inf'}\n", + "1440 +Inf [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '+Inf'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.001'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.001'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.001'}\n", + "480 0.001 [1675014193.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.001'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.001'}\n", + "1440 0.001 [1675019023.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.001'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0025'}\n", + "480 0.0025 [1675014193.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0025'}\n", + "1440 0.0025 [1675019023.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.005'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.005'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.005'}\n", + "480 0.005 [1675014193.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.005'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.005'}\n", + "1440 0.005 [1675019023.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.005'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0075'}\n", + "480 0.0075 [1675014193.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0075'}\n", + "1440 0.0075 [1675019023.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.0075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.01'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.01'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.01'}\n", + "480 0.01 [1675014193.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.01'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.01'}\n", + "1440 0.01 [1675019023.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.01'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.025'}\n", + "480 0.025 [1675014193.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.025'}\n", + "1440 0.025 [1675019023.164, '0']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.025'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.05'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.05'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.05'}\n", + "480 0.05 [1675014193.164, '143']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.05'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.05'}\n", + "1440 0.05 [1675019023.164, '682']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.05'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.075'}\n", + "480 0.075 [1675014193.164, '242']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.075'}\n", + "1440 0.075 [1675019023.164, '1138']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.075'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.1'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.1'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.1'}\n", + "480 0.1 [1675014193.164, '283']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.1'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.1'}\n", + "1440 0.1 [1675019023.164, '1337']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.1'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.25'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.25'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.25'}\n", + "480 0.25 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.25'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.25'}\n", + "1440 0.25 [1675019023.164, '1475']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.25'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.5'}\n", + "480 0.5 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.5'}\n", + "1440 0.5 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.75'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.75'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.75'}\n", + "480 0.75 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.75'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.75'}\n", + "1440 0.75 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '0.75'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '1.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '1.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '1.0'}\n", + "480 1.0 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '1.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '1.0'}\n", + "1440 1.0 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '1.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '10.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '10.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '10.0'}\n", + "480 10.0 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '10.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '10.0'}\n", + "1440 10.0 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '10.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '2.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '2.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '2.5'}\n", + "480 2.5 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '2.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '2.5'}\n", + "1440 2.5 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '2.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '5.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '5.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '5.0'}\n", + "480 5.0 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '5.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '5.0'}\n", + "1440 5.0 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '5.0'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '7.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '7.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '7.5'}\n", + "480 7.5 [1675014193.164, '291']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '7.5'}\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '7.5'}\n", + "1440 7.5 [1675019023.164, '1476']\n", + "{'__name__': 'DbscanServing_Detect_histogram_duration_bucket', 'instance': '10.1.19.194:9192', 'job': 'dbscanservingservice', 'le': '7.5'}\n", + "960 +Inf [1675016612.783, '182']\n", + "1440 +Inf [1675019042.783, '182']\n", + "960 0.001 [1675016612.783, '0']\n", + "1440 0.001 [1675019042.783, '0']\n", + "960 0.0025 [1675016612.783, '0']\n", + "1440 0.0025 [1675019042.783, '0']\n", + "960 0.005 [1675016612.783, '0']\n", + "1440 0.005 [1675019042.783, '0']\n", + "960 0.0075 [1675016612.783, '0']\n", + "1440 0.0075 [1675019042.783, '0']\n", + "960 0.01 [1675016612.783, '0']\n", + "1440 0.01 [1675019042.783, '0']\n", + "960 0.025 [1675016612.783, '0']\n", + "1440 0.025 [1675019042.783, '0']\n", + "960 0.05 [1675016612.783, '73']\n", + "1440 0.05 [1675019042.783, '80']\n", + "960 0.075 [1675016612.783, '133']\n", + "1440 0.075 [1675019042.783, '135']\n", + "960 0.1 [1675016612.783, '161']\n", + "1440 0.1 [1675019042.783, '151']\n", + "960 0.25 [1675016612.783, '182']\n", + "1440 0.25 [1675019042.783, '180']\n", + "960 0.5 [1675016612.783, '182']\n", + "1440 0.5 [1675019042.783, '182']\n", + "960 0.75 [1675016612.783, '182']\n", + "1440 0.75 [1675019042.783, '182']\n", + "960 1.0 [1675016612.783, '182']\n", + "1440 1.0 [1675019042.783, '182']\n", + "960 10.0 [1675016612.783, '182']\n", + "1440 10.0 [1675019042.783, '182']\n", + "960 2.5 [1675016612.783, '182']\n", + "1440 2.5 [1675019042.783, '182']\n", + "960 5.0 [1675016612.783, '182']\n", + "1440 5.0 [1675019042.783, '182']\n", + "960 7.5 [1675016612.783, '182']\n", + "1440 7.5 [1675019042.783, '182']\n", + "480 +Inf [1675014389.018, '102']\n", + "1440 +Inf [1675019024.018, '1759']\n", + "1920 +Inf [1675021409.018, '1415']\n", + "480 0.001 [1675014389.018, '0']\n", + "1440 0.001 [1675019024.018, '0']\n", + "1920 0.001 [1675021409.018, '0']\n", + "480 0.0025 [1675014389.018, '0']\n", + "1440 0.0025 [1675019024.018, '0']\n", + "1920 0.0025 [1675021409.018, '0']\n", + "480 0.005 [1675014389.018, '0']\n", + "1440 0.005 [1675019024.018, '0']\n", + "1920 0.005 [1675021409.018, '0']\n", + "480 0.0075 [1675014389.018, '0']\n", + "1440 0.0075 [1675019024.018, '0']\n", + "1920 0.0075 [1675021409.018, '0']\n", + "480 0.01 [1675014389.018, '0']\n", + "1440 0.01 [1675019024.018, '0']\n", + "1920 0.01 [1675021409.018, '0']\n", + "480 0.025 [1675014389.018, '0']\n", + "1440 0.025 [1675019024.018, '0']\n", + "1920 0.025 [1675021409.018, '0']\n", + "480 0.05 [1675014389.018, '44']\n", + "1440 0.05 [1675019024.018, '858']\n", + "1920 0.05 [1675021409.018, '627']\n", + "480 0.075 [1675014389.018, '98']\n", + "1440 0.075 [1675019024.018, '1357']\n", + "1920 0.075 [1675021409.018, '1001']\n", + "480 0.1 [1675014389.018, '99']\n", + "1440 0.1 [1675019024.018, '1607']\n", + "1920 0.1 [1675021409.018, '1196']\n", + "480 0.25 [1675014389.018, '101']\n", + "1440 0.25 [1675019024.018, '1752']\n", + "1920 0.25 [1675021409.018, '1407']\n", + "480 0.5 [1675014389.018, '102']\n", + "1440 0.5 [1675019024.018, '1756']\n", + "1920 0.5 [1675021409.018, '1412']\n", + "480 0.75 [1675014389.018, '102']\n", + "1440 0.75 [1675019024.018, '1759']\n", + "1920 0.75 [1675021409.018, '1415']\n", + "480 1.0 [1675014389.018, '102']\n", + "1440 1.0 [1675019024.018, '1759']\n", + "1920 1.0 [1675021409.018, '1415']\n", + "480 10.0 [1675014389.018, '102']\n", + "1440 10.0 [1675019024.018, '1759']\n", + "1920 10.0 [1675021409.018, '1415']\n", + "480 2.5 [1675014389.018, '102']\n", + "1440 2.5 [1675019024.018, '1759']\n", + "1920 2.5 [1675021409.018, '1415']\n", + "480 5.0 [1675014389.018, '102']\n", + "1440 5.0 [1675019024.018, '1759']\n", + "1920 5.0 [1675021409.018, '1415']\n", + "480 7.5 [1675014389.018, '102']\n", + "1440 7.5 [1675019024.018, '1759']\n", + "1920 7.5 [1675021409.018, '1415']\n", + "120 +Inf [1675009362.662, '489']\n", + "240 +Inf [1675011822.662, '4186']\n", + "480 +Inf [1675014192.662, '9113']\n", + "960 +Inf [1675016577.662, '16276']\n", + "1440 +Inf [1675019022.661, '24049']\n", + "1920 +Inf [1675021407.662, '32855']\n", + "1920 +Inf [1675024077.662, '43594']\n", + "120 0.001 [1675009362.662, '0']\n", + "240 0.001 [1675011822.662, '0']\n", + "480 0.001 [1675014192.662, '0']\n", + "960 0.001 [1675016577.662, '0']\n", + "1440 0.001 [1675019022.661, '0']\n", + "1920 0.001 [1675021407.662, '0']\n", + "1920 0.001 [1675024077.662, '0']\n", + "120 0.0025 [1675009362.662, '0']\n", + "240 0.0025 [1675011822.662, '0']\n", + "480 0.0025 [1675014192.662, '0']\n", + "960 0.0025 [1675016577.662, '0']\n", + "1440 0.0025 [1675019022.661, '0']\n", + "1920 0.0025 [1675021407.662, '0']\n", + "1920 0.0025 [1675024077.662, '0']\n", + "120 0.005 [1675009362.662, '0']\n", + "240 0.005 [1675011822.662, '0']\n", + "480 0.005 [1675014192.662, '0']\n", + "960 0.005 [1675016577.662, '0']\n", + "1440 0.005 [1675019022.661, '0']\n", + "1920 0.005 [1675021407.662, '0']\n", + "1920 0.005 [1675024077.662, '0']\n", + "120 0.0075 [1675009362.662, '0']\n", + "240 0.0075 [1675011822.662, '0']\n", + "480 0.0075 [1675014192.662, '0']\n", + "960 0.0075 [1675016577.662, '0']\n", + "1440 0.0075 [1675019022.661, '0']\n", + "1920 0.0075 [1675021407.662, '0']\n", + "1920 0.0075 [1675024077.662, '0']\n", + "120 0.01 [1675009362.662, '0']\n", + "240 0.01 [1675011822.662, '0']\n", + "480 0.01 [1675014192.662, '0']\n", + "960 0.01 [1675016577.662, '0']\n", + "1440 0.01 [1675019022.661, '0']\n", + "1920 0.01 [1675021407.662, '0']\n", + "1920 0.01 [1675024077.662, '0']\n", + "120 0.025 [1675009362.662, '0']\n", + "240 0.025 [1675011822.662, '0']\n", + "480 0.025 [1675014192.662, '0']\n", + "960 0.025 [1675016577.662, '0']\n", + "1440 0.025 [1675019022.661, '0']\n", + "1920 0.025 [1675021407.662, '0']\n", + "1920 0.025 [1675024077.662, '0']\n", + "120 0.05 [1675009362.662, '211']\n", + "240 0.05 [1675011822.662, '1791']\n", + "480 0.05 [1675014192.662, '3858']\n", + "960 0.05 [1675016577.662, '7538']\n", + "1440 0.05 [1675019022.661, '11269']\n", + "1920 0.05 [1675021407.662, '14924']\n", + "1920 0.05 [1675024077.662, '18397']\n", + "120 0.075 [1675009362.662, '375']\n", + "240 0.075 [1675011822.662, '3151']\n", + "480 0.075 [1675014192.662, '6883']\n", + "960 0.075 [1675016577.662, '12939']\n", + "1440 0.075 [1675019022.661, '19089']\n", + "1920 0.075 [1675021407.662, '25554']\n", + "1920 0.075 [1675024077.662, '32483']\n", + "120 0.1 [1675009362.662, '462']\n", + "240 0.1 [1675011822.662, '4051']\n", + "480 0.1 [1675014192.662, '8792']\n", + "960 0.1 [1675016577.662, '15732']\n", + "1440 0.1 [1675019022.661, '22862']\n", + "1920 0.1 [1675021407.662, '30549']\n", + "1920 0.1 [1675024077.662, '38949']\n", + "120 0.25 [1675009362.662, '487']\n", + "240 0.25 [1675011822.662, '4184']\n", + "480 0.25 [1675014192.662, '9111']\n", + "960 0.25 [1675016577.662, '16274']\n", + "1440 0.25 [1675019022.661, '24047']\n", + "1920 0.25 [1675021407.662, '32852']\n", + "1920 0.25 [1675024077.662, '43558']\n", + "120 0.5 [1675009362.662, '488']\n", + "240 0.5 [1675011822.662, '4185']\n", + "480 0.5 [1675014192.662, '9112']\n", + "960 0.5 [1675016577.662, '16275']\n", + "1440 0.5 [1675019022.661, '24048']\n", + "1920 0.5 [1675021407.662, '32854']\n", + "1920 0.5 [1675024077.662, '43593']\n", + "120 0.75 [1675009362.662, '489']\n", + "240 0.75 [1675011822.662, '4186']\n", + "480 0.75 [1675014192.662, '9113']\n", + "960 0.75 [1675016577.662, '16276']\n", + "1440 0.75 [1675019022.661, '24049']\n", + "1920 0.75 [1675021407.662, '32855']\n", + "1920 0.75 [1675024077.662, '43594']\n", + "120 1.0 [1675009362.662, '489']\n", + "240 1.0 [1675011822.662, '4186']\n", + "480 1.0 [1675014192.662, '9113']\n", + "960 1.0 [1675016577.662, '16276']\n", + "1440 1.0 [1675019022.661, '24049']\n", + "1920 1.0 [1675021407.662, '32855']\n", + "1920 1.0 [1675024077.662, '43594']\n", + "120 10.0 [1675009362.662, '489']\n", + "240 10.0 [1675011822.662, '4186']\n", + "480 10.0 [1675014192.662, '9113']\n", + "960 10.0 [1675016577.662, '16276']\n", + "1440 10.0 [1675019022.661, '24049']\n", + "1920 10.0 [1675021407.662, '32855']\n", + "1920 10.0 [1675024077.662, '43594']\n", + "120 2.5 [1675009362.662, '489']\n", + "240 2.5 [1675011822.662, '4186']\n", + "480 2.5 [1675014192.662, '9113']\n", + "960 2.5 [1675016577.662, '16276']\n", + "1440 2.5 [1675019022.661, '24049']\n", + "1920 2.5 [1675021407.662, '32855']\n", + "1920 2.5 [1675024077.662, '43594']\n", + "120 5.0 [1675009362.662, '489']\n", + "240 5.0 [1675011822.662, '4186']\n", + "480 5.0 [1675014192.662, '9113']\n", + "960 5.0 [1675016577.662, '16276']\n", + "1440 5.0 [1675019022.661, '24049']\n", + "1920 5.0 [1675021407.662, '32855']\n", + "1920 5.0 [1675024077.662, '43594']\n", + "120 7.5 [1675009362.662, '489']\n", + "240 7.5 [1675011822.662, '4186']\n", + "480 7.5 [1675014192.662, '9113']\n", + "960 7.5 [1675016577.662, '16276']\n", + "1440 7.5 [1675019022.661, '24049']\n", + "1920 7.5 [1675021407.662, '32855']\n", + "1920 7.5 [1675024077.662, '43594']\n", + "120 +Inf [1675009372.05, '571']\n", + "240 +Inf [1675011817.049, '4490']\n", + "480 +Inf [1675014202.049, '9925']\n", + "960 +Inf [1675016572.05, '17255']\n", + "1440 +Inf [1675019017.05, '25096']\n", + "1920 +Inf [1675021402.049, '33917']\n", + "1920 +Inf [1675024087.05, '45031']\n", + "120 0.001 [1675009372.05, '0']\n", + "240 0.001 [1675011817.049, '0']\n", + "480 0.001 [1675014202.049, '0']\n", + "960 0.001 [1675016572.05, '0']\n", + "1440 0.001 [1675019017.05, '0']\n", + "1920 0.001 [1675021402.049, '0']\n", + "1920 0.001 [1675024087.05, '0']\n", + "120 0.0025 [1675009372.05, '0']\n", + "240 0.0025 [1675011817.049, '0']\n", + "480 0.0025 [1675014202.049, '0']\n", + "960 0.0025 [1675016572.05, '0']\n", + "1440 0.0025 [1675019017.05, '0']\n", + "1920 0.0025 [1675021402.049, '0']\n", + "1920 0.0025 [1675024087.05, '0']\n", + "120 0.005 [1675009372.05, '0']\n", + "240 0.005 [1675011817.049, '0']\n", + "480 0.005 [1675014202.049, '0']\n", + "960 0.005 [1675016572.05, '0']\n", + "1440 0.005 [1675019017.05, '0']\n", + "1920 0.005 [1675021402.049, '0']\n", + "1920 0.005 [1675024087.05, '0']\n", + "120 0.0075 [1675009372.05, '0']\n", + "240 0.0075 [1675011817.049, '0']\n", + "480 0.0075 [1675014202.049, '0']\n", + "960 0.0075 [1675016572.05, '0']\n", + "1440 0.0075 [1675019017.05, '0']\n", + "1920 0.0075 [1675021402.049, '0']\n", + "1920 0.0075 [1675024087.05, '0']\n", + "120 0.01 [1675009372.05, '0']\n", + "240 0.01 [1675011817.049, '0']\n", + "480 0.01 [1675014202.049, '0']\n", + "960 0.01 [1675016572.05, '0']\n", + "1440 0.01 [1675019017.05, '0']\n", + "1920 0.01 [1675021402.049, '0']\n", + "1920 0.01 [1675024087.05, '0']\n", + "120 0.025 [1675009372.05, '0']\n", + "240 0.025 [1675011817.049, '0']\n", + "480 0.025 [1675014202.049, '0']\n", + "960 0.025 [1675016572.05, '0']\n", + "1440 0.025 [1675019017.05, '0']\n", + "1920 0.025 [1675021402.049, '0']\n", + "1920 0.025 [1675024087.05, '0']\n", + "120 0.05 [1675009372.05, '245']\n", + "240 0.05 [1675011817.049, '1896']\n", + "480 0.05 [1675014202.049, '4331']\n", + "960 0.05 [1675016572.05, '8182']\n", + "1440 0.05 [1675019017.05, '12217']\n", + "1920 0.05 [1675021402.049, '16235']\n", + "1920 0.05 [1675024087.05, '20038']\n", + "120 0.075 [1675009372.05, '427']\n", + "240 0.075 [1675011817.049, '3299']\n", + "480 0.075 [1675014202.049, '7426']\n", + "960 0.075 [1675016572.05, '13550']\n", + "1440 0.075 [1675019017.05, '19785']\n", + "1920 0.075 [1675021402.049, '26299']\n", + "1920 0.075 [1675024087.05, '33400']\n", + "120 0.1 [1675009372.05, '552']\n", + "240 0.1 [1675011817.049, '4372']\n", + "480 0.1 [1675014202.049, '9665']\n", + "960 0.1 [1675016572.05, '16810']\n", + "1440 0.1 [1675019017.05, '24090']\n", + "1920 0.1 [1675021402.049, '31814']\n", + "1920 0.1 [1675024087.05, '40600']\n", + "120 0.25 [1675009372.05, '569']\n", + "240 0.25 [1675011817.049, '4488']\n", + "480 0.25 [1675014202.049, '9923']\n", + "960 0.25 [1675016572.05, '17253']\n", + "1440 0.25 [1675019017.05, '25093']\n", + "1920 0.25 [1675021402.049, '33912']\n", + "1920 0.25 [1675024087.05, '45004']\n", + "120 0.5 [1675009372.05, '569']\n", + "240 0.5 [1675011817.049, '4488']\n", + "480 0.5 [1675014202.049, '9923']\n", + "960 0.5 [1675016572.05, '17253']\n", + "1440 0.5 [1675019017.05, '25094']\n", + "1920 0.5 [1675021402.049, '33915']\n", + "1920 0.5 [1675024087.05, '45029']\n", + "120 0.75 [1675009372.05, '571']\n", + "240 0.75 [1675011817.049, '4490']\n", + "480 0.75 [1675014202.049, '9925']\n", + "960 0.75 [1675016572.05, '17255']\n", + "1440 0.75 [1675019017.05, '25096']\n", + "1920 0.75 [1675021402.049, '33917']\n", + "1920 0.75 [1675024087.05, '45031']\n", + "120 1.0 [1675009372.05, '571']\n", + "240 1.0 [1675011817.049, '4490']\n", + "480 1.0 [1675014202.049, '9925']\n", + "960 1.0 [1675016572.05, '17255']\n", + "1440 1.0 [1675019017.05, '25096']\n", + "1920 1.0 [1675021402.049, '33917']\n", + "1920 1.0 [1675024087.05, '45031']\n", + "120 10.0 [1675009372.05, '571']\n", + "240 10.0 [1675011817.049, '4490']\n", + "480 10.0 [1675014202.049, '9925']\n", + "960 10.0 [1675016572.05, '17255']\n", + "1440 10.0 [1675019017.05, '25096']\n", + "1920 10.0 [1675021402.049, '33917']\n", + "1920 10.0 [1675024087.05, '45031']\n", + "120 2.5 [1675009372.05, '571']\n", + "240 2.5 [1675011817.049, '4490']\n", + "480 2.5 [1675014202.049, '9925']\n", + "960 2.5 [1675016572.05, '17255']\n", + "1440 2.5 [1675019017.05, '25096']\n", + "1920 2.5 [1675021402.049, '33917']\n", + "1920 2.5 [1675024087.05, '45031']\n", + "120 5.0 [1675009372.05, '571']\n", + "240 5.0 [1675011817.049, '4490']\n", + "480 5.0 [1675014202.049, '9925']\n", + "960 5.0 [1675016572.05, '17255']\n", + "1440 5.0 [1675019017.05, '25096']\n", + "1920 5.0 [1675021402.049, '33917']\n", + "1920 5.0 [1675024087.05, '45031']\n", + "120 7.5 [1675009372.05, '571']\n", + "240 7.5 [1675011817.049, '4490']\n", + "480 7.5 [1675014202.049, '9925']\n", + "960 7.5 [1675016572.05, '17255']\n", + "1440 7.5 [1675019017.05, '25096']\n", + "1920 7.5 [1675021402.049, '33917']\n", + "1920 7.5 [1675024087.05, '45031']\n", + "960 +Inf [1675016640.504, '114']\n", + "1920 +Inf [1675021410.505, '1481']\n", + "960 0.001 [1675016640.504, '0']\n", + "1920 0.001 [1675021410.505, '0']\n", + "960 0.0025 [1675016640.504, '0']\n", + "1920 0.0025 [1675021410.505, '0']\n", + "960 0.005 [1675016640.504, '0']\n", + "1920 0.005 [1675021410.505, '0']\n", + "960 0.0075 [1675016640.504, '0']\n", + "1920 0.0075 [1675021410.505, '0']\n", + "960 0.01 [1675016640.504, '0']\n", + "1920 0.01 [1675021410.505, '0']\n", + "960 0.025 [1675016640.504, '0']\n", + "1920 0.025 [1675021410.505, '0']\n", + "960 0.05 [1675016640.504, '60']\n", + "1920 0.05 [1675021410.505, '594']\n", + "960 0.075 [1675016640.504, '91']\n", + "1920 0.075 [1675021410.505, '1074']\n", + "960 0.1 [1675016640.504, '105']\n", + "1920 0.1 [1675021410.505, '1250']\n", + "960 0.25 [1675016640.504, '113']\n", + "1920 0.25 [1675021410.505, '1471']\n", + "960 0.5 [1675016640.504, '113']\n", + "1920 0.5 [1675021410.505, '1481']\n", + "960 0.75 [1675016640.504, '114']\n", + "1920 0.75 [1675021410.505, '1481']\n", + "960 1.0 [1675016640.504, '114']\n", + "1920 1.0 [1675021410.505, '1481']\n", + "960 10.0 [1675016640.504, '114']\n", + "1920 10.0 [1675021410.505, '1481']\n", + "960 2.5 [1675016640.504, '114']\n", + "1920 2.5 [1675021410.505, '1481']\n", + "960 5.0 [1675016640.504, '114']\n", + "1920 5.0 [1675021410.505, '1481']\n", + "960 7.5 [1675016640.504, '114']\n", + "1920 7.5 [1675021410.505, '1481']\n", + "960 +Inf [1675016639.206, '93']\n", + "1440 +Inf [1675019024.206, '171']\n", + "1920 +Inf [1675024169.206, '54']\n", + "960 0.001 [1675016639.206, '0']\n", + "1440 0.001 [1675019024.206, '0']\n", + "1920 0.001 [1675024169.206, '0']\n", + "960 0.0025 [1675016639.206, '0']\n", + "1440 0.0025 [1675019024.206, '0']\n", + "1920 0.0025 [1675024169.206, '0']\n", + "960 0.005 [1675016639.206, '0']\n", + "1440 0.005 [1675019024.206, '0']\n", + "1920 0.005 [1675024169.206, '0']\n", + "960 0.0075 [1675016639.206, '0']\n", + "1440 0.0075 [1675019024.206, '0']\n", + "1920 0.0075 [1675024169.206, '0']\n", + "960 0.01 [1675016639.206, '0']\n", + "1440 0.01 [1675019024.206, '0']\n", + "1920 0.01 [1675024169.206, '0']\n", + "960 0.025 [1675016639.206, '0']\n", + "1440 0.025 [1675019024.206, '0']\n", + "1920 0.025 [1675024169.206, '0']\n", + "960 0.05 [1675016639.206, '52']\n", + "1440 0.05 [1675019024.206, '76']\n", + "1920 0.05 [1675024169.206, '26']\n", + "960 0.075 [1675016639.206, '77']\n", + "1440 0.075 [1675019024.206, '122']\n", + "1920 0.075 [1675024169.206, '42']\n", + "960 0.1 [1675016639.206, '83']\n", + "1440 0.1 [1675019024.206, '147']\n", + "1920 0.1 [1675024169.206, '45']\n", + "960 0.25 [1675016639.206, '90']\n", + "1440 0.25 [1675019024.206, '169']\n", + "1920 0.25 [1675024169.206, '52']\n", + "960 0.5 [1675016639.206, '91']\n", + "1440 0.5 [1675019024.206, '171']\n", + "1920 0.5 [1675024169.206, '54']\n", + "960 0.75 [1675016639.206, '92']\n", + "1440 0.75 [1675019024.206, '171']\n", + "1920 0.75 [1675024169.206, '54']\n", + "960 1.0 [1675016639.206, '93']\n", + "1440 1.0 [1675019024.206, '171']\n", + "1920 1.0 [1675024169.206, '54']\n", + "960 10.0 [1675016639.206, '93']\n", + "1440 10.0 [1675019024.206, '171']\n", + "1920 10.0 [1675024169.206, '54']\n", + "960 2.5 [1675016639.206, '93']\n", + "1440 2.5 [1675019024.206, '171']\n", + "1920 2.5 [1675024169.206, '54']\n", + "960 5.0 [1675016639.206, '93']\n", + "1440 5.0 [1675019024.206, '171']\n", + "1920 5.0 [1675024169.206, '54']\n", + "960 7.5 [1675016639.206, '93']\n", + "1440 7.5 [1675019024.206, '171']\n", + "1920 7.5 [1675024169.206, '54']\n", + "240 +Inf [1675012414.993, '110']\n", + "1440 +Inf [1675019029.992, '137']\n", + "240 0.001 [1675012414.993, '0']\n", + "1440 0.001 [1675019029.992, '0']\n", + "240 0.0025 [1675012414.993, '0']\n", + "1440 0.0025 [1675019029.992, '0']\n", + "240 0.005 [1675012414.993, '0']\n", + "1440 0.005 [1675019029.992, '0']\n", + "240 0.0075 [1675012414.993, '0']\n", + "1440 0.0075 [1675019029.992, '0']\n", + "240 0.01 [1675012414.993, '0']\n", + "1440 0.01 [1675019029.992, '0']\n", + "240 0.025 [1675012414.993, '0']\n", + "1440 0.025 [1675019029.992, '0']\n", + "240 0.05 [1675012414.993, '56']\n", + "1440 0.05 [1675019029.992, '60']\n", + "240 0.075 [1675012414.993, '93']\n", + "1440 0.075 [1675019029.992, '109']\n", + "240 0.1 [1675012414.993, '106']\n", + "1440 0.1 [1675019029.992, '120']\n", + "240 0.25 [1675012414.993, '109']\n", + "1440 0.25 [1675019029.992, '134']\n", + "240 0.5 [1675012414.993, '110']\n", + "1440 0.5 [1675019029.992, '135']\n", + "240 0.75 [1675012414.993, '110']\n", + "1440 0.75 [1675019029.992, '135']\n", + "240 1.0 [1675012414.993, '110']\n", + "1440 1.0 [1675019029.992, '135']\n", + "240 10.0 [1675012414.993, '110']\n", + "1440 10.0 [1675019029.992, '137']\n", + "240 2.5 [1675012414.993, '110']\n", + "1440 2.5 [1675019029.992, '137']\n", + "240 5.0 [1675012414.993, '110']\n", + "1440 5.0 [1675019029.992, '137']\n", + "240 7.5 [1675012414.993, '110']\n", + "1440 7.5 [1675019029.992, '137']\n", + "240 +Inf [1675011818.616, '212']\n", + "960 +Inf [1675016573.616, '1522']\n", + "1920 +Inf [1675021403.616, '1415']\n", + "1920 +Inf [1675024088.616, '235']\n", + "240 0.001 [1675011818.616, '0']\n", + "960 0.001 [1675016573.616, '0']\n", + "1920 0.001 [1675021403.616, '0']\n", + "1920 0.001 [1675024088.616, '0']\n", + "240 0.0025 [1675011818.616, '0']\n", + "960 0.0025 [1675016573.616, '0']\n", + "1920 0.0025 [1675021403.616, '0']\n", + "1920 0.0025 [1675024088.616, '0']\n", + "240 0.005 [1675011818.616, '0']\n", + "960 0.005 [1675016573.616, '0']\n", + "1920 0.005 [1675021403.616, '0']\n", + "1920 0.005 [1675024088.616, '0']\n", + "240 0.0075 [1675011818.616, '0']\n", + "960 0.0075 [1675016573.616, '0']\n", + "1920 0.0075 [1675021403.616, '0']\n", + "1920 0.0075 [1675024088.616, '0']\n", + "240 0.01 [1675011818.616, '0']\n", + "960 0.01 [1675016573.616, '0']\n", + "1920 0.01 [1675021403.616, '0']\n", + "1920 0.01 [1675024088.616, '0']\n", + "240 0.025 [1675011818.616, '0']\n", + "960 0.025 [1675016573.616, '0']\n", + "1920 0.025 [1675021403.616, '0']\n", + "1920 0.025 [1675024088.616, '0']\n", + "240 0.05 [1675011818.616, '104']\n", + "960 0.05 [1675016573.616, '773']\n", + "1920 0.05 [1675021403.616, '614']\n", + "1920 0.05 [1675024088.616, '134']\n", + "240 0.075 [1675011818.616, '175']\n", + "960 0.075 [1675016573.616, '1211']\n", + "1920 0.075 [1675021403.616, '1035']\n", + "1920 0.075 [1675024088.616, '204']\n", + "240 0.1 [1675011818.616, '205']\n", + "960 0.1 [1675016573.616, '1450']\n", + "1920 0.1 [1675021403.616, '1252']\n", + "1920 0.1 [1675024088.616, '231']\n", + "240 0.25 [1675011818.616, '211']\n", + "960 0.25 [1675016573.616, '1520']\n", + "1920 0.25 [1675021403.616, '1412']\n", + "1920 0.25 [1675024088.616, '233']\n", + "240 0.5 [1675011818.616, '211']\n", + "960 0.5 [1675016573.616, '1522']\n", + "1920 0.5 [1675021403.616, '1415']\n", + "1920 0.5 [1675024088.616, '234']\n", + "240 0.75 [1675011818.616, '212']\n", + "960 0.75 [1675016573.616, '1522']\n", + "1920 0.75 [1675021403.616, '1415']\n", + "1920 0.75 [1675024088.616, '235']\n", + "240 1.0 [1675011818.616, '212']\n", + "960 1.0 [1675016573.616, '1522']\n", + "1920 1.0 [1675021403.616, '1415']\n", + "1920 1.0 [1675024088.616, '235']\n", + "240 10.0 [1675011818.616, '212']\n", + "960 10.0 [1675016573.616, '1522']\n", + "1920 10.0 [1675021403.616, '1415']\n", + "1920 10.0 [1675024088.616, '235']\n", + "240 2.5 [1675011818.616, '212']\n", + "960 2.5 [1675016573.616, '1522']\n", + "1920 2.5 [1675021403.616, '1415']\n", + "1920 2.5 [1675024088.616, '235']\n", + "240 5.0 [1675011818.616, '212']\n", + "960 5.0 [1675016573.616, '1522']\n", + "1920 5.0 [1675021403.616, '1415']\n", + "1920 5.0 [1675024088.616, '235']\n", + "240 7.5 [1675011818.616, '212']\n", + "960 7.5 [1675016573.616, '1522']\n", + "1920 7.5 [1675021403.616, '1415']\n", + "1920 7.5 [1675024088.616, '235']\n", + "480 +Inf [1675014202.702, '161']\n", + "480 0.001 [1675014202.702, '0']\n", + "480 0.0025 [1675014202.702, '0']\n", + "480 0.005 [1675014202.702, '0']\n", + "480 0.0075 [1675014202.702, '0']\n", + "480 0.01 [1675014202.702, '0']\n", + "480 0.025 [1675014202.702, '0']\n", + "480 0.05 [1675014202.702, '77']\n", + "480 0.075 [1675014202.702, '134']\n", + "480 0.1 [1675014202.702, '155']\n", + "480 0.25 [1675014202.702, '159']\n", + "480 0.5 [1675014202.702, '159']\n", + "480 0.75 [1675014202.702, '160']\n", + "480 1.0 [1675014202.702, '161']\n", + "480 10.0 [1675014202.702, '161']\n", + "480 2.5 [1675014202.702, '161']\n", + "480 5.0 [1675014202.702, '161']\n", + "480 7.5 [1675014202.702, '161']\n", + "1920 +Inf [1675021410.1, '85']\n", + "1920 0.001 [1675021410.1, '0']\n", + "1920 0.0025 [1675021410.1, '0']\n", + "1920 0.005 [1675021410.1, '0']\n", + "1920 0.0075 [1675021410.1, '0']\n", + "1920 0.01 [1675021410.1, '0']\n", + "1920 0.025 [1675021410.1, '0']\n", + "1920 0.05 [1675021410.1, '30']\n", + "1920 0.075 [1675021410.1, '53']\n", + "1920 0.1 [1675021410.1, '59']\n", + "1920 0.25 [1675021410.1, '75']\n", + "1920 0.5 [1675021410.1, '76']\n", + "1920 0.75 [1675021410.1, '78']\n", + "1920 1.0 [1675021410.1, '79']\n", + "1920 10.0 [1675021410.1, '85']\n", + "1920 2.5 [1675021410.1, '85']\n", + "1920 5.0 [1675021410.1, '85']\n", + "1920 7.5 [1675021410.1, '85']\n", + "240 +Inf [1675011822.887, '192']\n", + "1920 +Inf [1675024167.887, '33']\n", + "240 0.001 [1675011822.887, '0']\n", + "1920 0.001 [1675024167.887, '0']\n", + "240 0.0025 [1675011822.887, '0']\n", + "1920 0.0025 [1675024167.887, '0']\n", + "240 0.005 [1675011822.887, '0']\n", + "1920 0.005 [1675024167.887, '0']\n", + "240 0.0075 [1675011822.887, '0']\n", + "1920 0.0075 [1675024167.887, '0']\n", + "240 0.01 [1675011822.887, '0']\n", + "1920 0.01 [1675024167.887, '0']\n", + "240 0.025 [1675011822.887, '0']\n", + "1920 0.025 [1675024167.887, '0']\n", + "240 0.05 [1675011822.887, '98']\n", + "1920 0.05 [1675024167.887, '18']\n", + "240 0.075 [1675011822.887, '156']\n", + "1920 0.075 [1675024167.887, '25']\n", + "240 0.1 [1675011822.887, '185']\n", + "1920 0.1 [1675024167.887, '26']\n", + "240 0.25 [1675011822.887, '190']\n", + "1920 0.25 [1675024167.887, '31']\n", + "240 0.5 [1675011822.887, '190']\n", + "1920 0.5 [1675024167.887, '32']\n", + "240 0.75 [1675011822.887, '191']\n", + "1920 0.75 [1675024167.887, '33']\n", + "240 1.0 [1675011822.887, '191']\n", + "1920 1.0 [1675024167.887, '33']\n", + "240 10.0 [1675011822.887, '192']\n", + "1920 10.0 [1675024167.887, '33']\n", + "240 2.5 [1675011822.887, '192']\n", + "1920 2.5 [1675024167.887, '33']\n", + "240 5.0 [1675011822.887, '192']\n", + "1920 5.0 [1675024167.887, '33']\n", + "240 7.5 [1675011822.887, '192']\n", + "1920 7.5 [1675024167.887, '33']\n", + "240 +Inf [1675012823.301, '2']\n", + "960 +Inf [1675016603.301, '106']\n", + "1920 +Inf [1675024178.301, '101']\n", + "240 0.001 [1675012823.301, '0']\n", + "960 0.001 [1675016603.301, '0']\n", + "1920 0.001 [1675024178.301, '0']\n", + "240 0.0025 [1675012823.301, '0']\n", + "960 0.0025 [1675016603.301, '0']\n", + "1920 0.0025 [1675024178.301, '0']\n", + "240 0.005 [1675012823.301, '0']\n", + "960 0.005 [1675016603.301, '0']\n", + "1920 0.005 [1675024178.301, '0']\n", + "240 0.0075 [1675012823.301, '0']\n", + "960 0.0075 [1675016603.301, '0']\n", + "1920 0.0075 [1675024178.301, '0']\n", + "240 0.01 [1675012823.301, '0']\n", + "960 0.01 [1675016603.301, '0']\n", + "1920 0.01 [1675024178.301, '0']\n", + "240 0.025 [1675012823.301, '0']\n", + "960 0.025 [1675016603.301, '0']\n", + "1920 0.025 [1675024178.301, '0']\n", + "240 0.05 [1675012823.301, '0']\n", + "960 0.05 [1675016603.301, '48']\n", + "1920 0.05 [1675024178.301, '43']\n", + "240 0.075 [1675012823.301, '0']\n", + "960 0.075 [1675016603.301, '84']\n", + "1920 0.075 [1675024178.301, '77']\n", + "240 0.1 [1675012823.301, '0']\n", + "960 0.1 [1675016603.301, '92']\n", + "1920 0.1 [1675024178.301, '93']\n", + "240 0.25 [1675012823.301, '0']\n", + "960 0.25 [1675016603.301, '104']\n", + "1920 0.25 [1675024178.301, '99']\n", + "240 0.5 [1675012823.301, '2']\n", + "960 0.5 [1675016603.301, '104']\n", + "1920 0.5 [1675024178.301, '100']\n", + "240 0.75 [1675012823.301, '2']\n", + "960 0.75 [1675016603.301, '106']\n", + "1920 0.75 [1675024178.301, '100']\n", + "240 1.0 [1675012823.301, '2']\n", + "960 1.0 [1675016603.301, '106']\n", + "1920 1.0 [1675024178.301, '101']\n", + "240 10.0 [1675012823.301, '2']\n", + "960 10.0 [1675016603.301, '106']\n", + "1920 10.0 [1675024178.301, '101']\n", + "240 2.5 [1675012823.301, '2']\n", + "960 2.5 [1675016603.301, '106']\n", + "1920 2.5 [1675024178.301, '101']\n", + "240 5.0 [1675012823.301, '2']\n", + "960 5.0 [1675016603.301, '106']\n", + "1920 5.0 [1675024178.301, '101']\n", + "240 7.5 [1675012823.301, '2']\n", + "960 7.5 [1675016603.301, '106']\n", + "1920 7.5 [1675024178.301, '101']\n", + "1920 +Inf [1675021401.463, '1820']\n", + "1920 0.001 [1675021401.463, '0']\n", + "1920 0.0025 [1675021401.463, '0']\n", + "1920 0.005 [1675021401.463, '0']\n", + "1920 0.0075 [1675021401.463, '0']\n", + "1920 0.01 [1675021401.463, '0']\n", + "1920 0.025 [1675021401.463, '0']\n", + "1920 0.05 [1675021401.463, '769']\n", + "1920 0.075 [1675021401.463, '1300']\n", + "1920 0.1 [1675021401.463, '1574']\n", + "1920 0.25 [1675021401.463, '1814']\n", + "1920 0.5 [1675021401.463, '1819']\n", + "1920 0.75 [1675021401.463, '1820']\n", + "1920 1.0 [1675021401.463, '1820']\n", + "1920 10.0 [1675021401.463, '1820']\n", + "1920 2.5 [1675021401.463, '1820']\n", + "1920 5.0 [1675021401.463, '1820']\n", + "1920 7.5 [1675021401.463, '1820']\n", + "1920 +Inf [1675021416.904, '195']\n", + "1920 +Inf [1675024236.904, '24']\n", + "1920 0.001 [1675021416.904, '0']\n", + "1920 0.001 [1675024236.904, '0']\n", + "1920 0.0025 [1675021416.904, '0']\n", + "1920 0.0025 [1675024236.904, '0']\n", + "1920 0.005 [1675021416.904, '0']\n", + "1920 0.005 [1675024236.904, '0']\n", + "1920 0.0075 [1675021416.904, '0']\n", + "1920 0.0075 [1675024236.904, '0']\n", + "1920 0.01 [1675021416.904, '0']\n", + "1920 0.01 [1675024236.904, '0']\n", + "1920 0.025 [1675021416.904, '0']\n", + "1920 0.025 [1675024236.904, '0']\n", + "1920 0.05 [1675021416.904, '61']\n", + "1920 0.05 [1675024236.904, '13']\n", + "1920 0.075 [1675021416.904, '122']\n", + "1920 0.075 [1675024236.904, '18']\n", + "1920 0.1 [1675021416.904, '152']\n", + "1920 0.1 [1675024236.904, '22']\n", + "1920 0.25 [1675021416.904, '190']\n", + "1920 0.25 [1675024236.904, '24']\n", + "1920 0.5 [1675021416.904, '191']\n", + "1920 0.5 [1675024236.904, '24']\n", + "1920 0.75 [1675021416.904, '191']\n", + "1920 0.75 [1675024236.904, '24']\n", + "1920 1.0 [1675021416.904, '195']\n", + "1920 1.0 [1675024236.904, '24']\n", + "1920 10.0 [1675021416.904, '195']\n", + "1920 10.0 [1675024236.904, '24']\n", + "1920 2.5 [1675021416.904, '195']\n", + "1920 2.5 [1675024236.904, '24']\n", + "1920 5.0 [1675021416.904, '195']\n", + "1920 5.0 [1675024236.904, '24']\n", + "1920 7.5 [1675021416.904, '195']\n", + "1920 7.5 [1675024236.904, '24']\n", + "480 +Inf [1675014199.946, '338']\n", + "1440 +Inf [1675019029.946, '1851']\n", + "480 0.001 [1675014199.946, '0']\n", + "1440 0.001 [1675019029.946, '0']\n", + "480 0.0025 [1675014199.946, '0']\n", + "1440 0.0025 [1675019029.946, '0']\n", + "480 0.005 [1675014199.946, '0']\n", + "1440 0.005 [1675019029.946, '0']\n", + "480 0.0075 [1675014199.946, '0']\n", + "1440 0.0075 [1675019029.946, '0']\n", + "480 0.01 [1675014199.946, '0']\n", + "1440 0.01 [1675019029.946, '0']\n", + "480 0.025 [1675014199.946, '0']\n", + "1440 0.025 [1675019029.946, '0']\n", + "480 0.05 [1675014199.946, '202']\n", + "1440 0.05 [1675019029.946, '819']\n", + "480 0.075 [1675014199.946, '305']\n", + "1440 0.075 [1675019029.946, '1391']\n", + "480 0.1 [1675014199.946, '330']\n", + "1440 0.1 [1675019029.946, '1650']\n", + "480 0.25 [1675014199.946, '337']\n", + "1440 0.25 [1675019029.946, '1849']\n", + "480 0.5 [1675014199.946, '338']\n", + "1440 0.5 [1675019029.946, '1851']\n", + "480 0.75 [1675014199.946, '338']\n", + "1440 0.75 [1675019029.946, '1851']\n", + "480 1.0 [1675014199.946, '338']\n", + "1440 1.0 [1675019029.946, '1851']\n", + "480 10.0 [1675014199.946, '338']\n", + "1440 10.0 [1675019029.946, '1851']\n", + "480 2.5 [1675014199.946, '338']\n", + "1440 2.5 [1675019029.946, '1851']\n", + "480 5.0 [1675014199.946, '338']\n", + "1440 5.0 [1675019029.946, '1851']\n", + "480 7.5 [1675014199.946, '338']\n", + "1440 7.5 [1675019029.946, '1851']\n", + "1440 +Inf [1675019017.016, '1449']\n", + "1440 0.001 [1675019017.016, '0']\n", + "1440 0.0025 [1675019017.016, '0']\n", + "1440 0.005 [1675019017.016, '0']\n", + "1440 0.0075 [1675019017.016, '0']\n", + "1440 0.01 [1675019017.016, '0']\n", + "1440 0.025 [1675019017.016, '0']\n", + "1440 0.05 [1675019017.016, '657']\n", + "1440 0.075 [1675019017.016, '1142']\n", + "1440 0.1 [1675019017.016, '1331']\n", + "1440 0.25 [1675019017.016, '1448']\n", + "1440 0.5 [1675019017.016, '1449']\n", + "1440 0.75 [1675019017.016, '1449']\n", + "1440 1.0 [1675019017.016, '1449']\n", + "1440 10.0 [1675019017.016, '1449']\n", + "1440 2.5 [1675019017.016, '1449']\n", + "1440 5.0 [1675019017.016, '1449']\n", + "1440 7.5 [1675019017.016, '1449']\n", + "960 +Inf [1675016568.249, '1491']\n", + "1440 +Inf [1675019043.249, '170']\n", + "1920 +Inf [1675021398.25, '1300']\n", + "1920 +Inf [1675024083.249, '209']\n", + "960 0.001 [1675016568.249, '0']\n", + "1440 0.001 [1675019043.249, '0']\n", + "1920 0.001 [1675021398.25, '0']\n", + "1920 0.001 [1675024083.249, '0']\n", + "960 0.0025 [1675016568.249, '0']\n", + "1440 0.0025 [1675019043.249, '0']\n", + "1920 0.0025 [1675021398.25, '0']\n", + "1920 0.0025 [1675024083.249, '0']\n", + "960 0.005 [1675016568.249, '0']\n", + "1440 0.005 [1675019043.249, '0']\n", + "1920 0.005 [1675021398.25, '0']\n", + "1920 0.005 [1675024083.249, '0']\n", + "960 0.0075 [1675016568.249, '0']\n", + "1440 0.0075 [1675019043.249, '0']\n", + "1920 0.0075 [1675021398.25, '0']\n", + "1920 0.0075 [1675024083.249, '0']\n", + "960 0.01 [1675016568.249, '0']\n", + "1440 0.01 [1675019043.249, '0']\n", + "1920 0.01 [1675021398.25, '0']\n", + "1920 0.01 [1675024083.249, '0']\n", + "960 0.025 [1675016568.249, '0']\n", + "1440 0.025 [1675019043.249, '0']\n", + "1920 0.025 [1675021398.25, '0']\n", + "1920 0.025 [1675024083.249, '0']\n", + "960 0.05 [1675016568.249, '780']\n", + "1440 0.05 [1675019043.249, '67']\n", + "1920 0.05 [1675021398.25, '567']\n", + "1920 0.05 [1675024083.249, '104']\n", + "960 0.075 [1675016568.249, '1202']\n", + "1440 0.075 [1675019043.249, '120']\n", + "1920 0.075 [1675021398.25, '931']\n", + "1920 0.075 [1675024083.249, '179']\n", + "960 0.1 [1675016568.249, '1428']\n", + "1440 0.1 [1675019043.249, '147']\n", + "1920 0.1 [1675021398.25, '1109']\n", + "1920 0.1 [1675024083.249, '202']\n", + "960 0.25 [1675016568.249, '1491']\n", + "1440 0.25 [1675019043.249, '166']\n", + "1920 0.25 [1675021398.25, '1297']\n", + "1920 0.25 [1675024083.249, '208']\n", + "960 0.5 [1675016568.249, '1491']\n", + "1440 0.5 [1675019043.249, '166']\n", + "1920 0.5 [1675021398.25, '1299']\n", + "1920 0.5 [1675024083.249, '209']\n", + "960 0.75 [1675016568.249, '1491']\n", + "1440 0.75 [1675019043.249, '167']\n", + "1920 0.75 [1675021398.25, '1300']\n", + "1920 0.75 [1675024083.249, '209']\n", + "960 1.0 [1675016568.249, '1491']\n", + "1440 1.0 [1675019043.249, '170']\n", + "1920 1.0 [1675021398.25, '1300']\n", + "1920 1.0 [1675024083.249, '209']\n", + "960 10.0 [1675016568.249, '1491']\n", + "1440 10.0 [1675019043.249, '170']\n", + "1920 10.0 [1675021398.25, '1300']\n", + "1920 10.0 [1675024083.249, '209']\n", + "960 2.5 [1675016568.249, '1491']\n", + "1440 2.5 [1675019043.249, '170']\n", + "1920 2.5 [1675021398.25, '1300']\n", + "1920 2.5 [1675024083.249, '209']\n", + "960 5.0 [1675016568.249, '1491']\n", + "1440 5.0 [1675019043.249, '170']\n", + "1920 5.0 [1675021398.25, '1300']\n", + "1920 5.0 [1675024083.249, '209']\n", + "960 7.5 [1675016568.249, '1491']\n", + "1440 7.5 [1675019043.249, '170']\n", + "1920 7.5 [1675021398.25, '1300']\n", + "1920 7.5 [1675024083.249, '209']\n", + "1920 +Inf [1675024229.99, '2']\n", + "1920 0.001 [1675024229.99, '0']\n", + "1920 0.0025 [1675024229.99, '0']\n", + "1920 0.005 [1675024229.99, '0']\n", + "1920 0.0075 [1675024229.99, '0']\n", + "1920 0.01 [1675024229.99, '0']\n", + "1920 0.025 [1675024229.99, '0']\n", + "1920 0.05 [1675024229.99, '0']\n", + "1920 0.075 [1675024229.99, '0']\n", + "1920 0.1 [1675024229.99, '0']\n", + "1920 0.25 [1675024229.99, '2']\n", + "1920 0.5 [1675024229.99, '2']\n", + "1920 0.75 [1675024229.99, '2']\n", + "1920 1.0 [1675024229.99, '2']\n", + "1920 10.0 [1675024229.99, '2']\n", + "1920 2.5 [1675024229.99, '2']\n", + "1920 5.0 [1675024229.99, '2']\n", + "1920 7.5 [1675024229.99, '2']\n", + "240 +Inf [1675012193.42, '2']\n", + "1920 +Inf [1675021403.42, '1768']\n", + "240 0.001 [1675012193.42, '0']\n", + "1920 0.001 [1675021403.42, '0']\n", + "240 0.0025 [1675012193.42, '0']\n", + "1920 0.0025 [1675021403.42, '0']\n", + "240 0.005 [1675012193.42, '0']\n", + "1920 0.005 [1675021403.42, '0']\n", + "240 0.0075 [1675012193.42, '0']\n", + "1920 0.0075 [1675021403.42, '0']\n", + "240 0.01 [1675012193.42, '0']\n", + "1920 0.01 [1675021403.42, '0']\n", + "240 0.025 [1675012193.42, '0']\n", + "1920 0.025 [1675021403.42, '0']\n", + "240 0.05 [1675012193.42, '0']\n", + "1920 0.05 [1675021403.42, '811']\n", + "240 0.075 [1675012193.42, '0']\n", + "1920 0.075 [1675021403.42, '1292']\n", + "240 0.1 [1675012193.42, '0']\n", + "1920 0.1 [1675021403.42, '1526']\n", + "240 0.25 [1675012193.42, '0']\n", + "1920 0.25 [1675021403.42, '1766']\n", + "240 0.5 [1675012193.42, '2']\n", + "1920 0.5 [1675021403.42, '1767']\n", + "240 0.75 [1675012193.42, '2']\n", + "1920 0.75 [1675021403.42, '1768']\n", + "240 1.0 [1675012193.42, '2']\n", + "1920 1.0 [1675021403.42, '1768']\n", + "240 10.0 [1675012193.42, '2']\n", + "1920 10.0 [1675021403.42, '1768']\n", + "240 2.5 [1675012193.42, '2']\n", + "1920 2.5 [1675021403.42, '1768']\n", + "240 5.0 [1675012193.42, '2']\n", + "1920 5.0 [1675021403.42, '1768']\n", + "240 7.5 [1675012193.42, '2']\n", + "1920 7.5 [1675021403.42, '1768']\n", + "480 +Inf [1675015296.566, '72']\n", + "1920 +Inf [1675024176.566, '80']\n", + "480 0.001 [1675015296.566, '0']\n", + "1920 0.001 [1675024176.566, '0']\n", + "480 0.0025 [1675015296.566, '0']\n", + "1920 0.0025 [1675024176.566, '0']\n", + "480 0.005 [1675015296.566, '0']\n", + "1920 0.005 [1675024176.566, '0']\n", + "480 0.0075 [1675015296.566, '0']\n", + "1920 0.0075 [1675024176.566, '0']\n", + "480 0.01 [1675015296.566, '0']\n", + "1920 0.01 [1675024176.566, '0']\n", + "480 0.025 [1675015296.566, '0']\n", + "1920 0.025 [1675024176.566, '0']\n", + "480 0.05 [1675015296.566, '47']\n", + "1920 0.05 [1675024176.566, '29']\n", + "480 0.075 [1675015296.566, '66']\n", + "1920 0.075 [1675024176.566, '62']\n", + "480 0.1 [1675015296.566, '68']\n", + "1920 0.1 [1675024176.566, '74']\n", + "480 0.25 [1675015296.566, '70']\n", + "1920 0.25 [1675024176.566, '77']\n", + "480 0.5 [1675015296.566, '70']\n", + "1920 0.5 [1675024176.566, '80']\n", + "480 0.75 [1675015296.566, '71']\n", + "1920 0.75 [1675024176.566, '80']\n", + "480 1.0 [1675015296.566, '72']\n", + "1920 1.0 [1675024176.566, '80']\n", + "480 10.0 [1675015296.566, '72']\n", + "1920 10.0 [1675024176.566, '80']\n", + "480 2.5 [1675015296.566, '72']\n", + "1920 2.5 [1675024176.566, '80']\n", + "480 5.0 [1675015296.566, '72']\n", + "1920 5.0 [1675024176.566, '80']\n", + "480 7.5 [1675015296.566, '72']\n", + "1920 7.5 [1675024176.566, '80']\n", + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0. 0. 228. 401. 507. 528. 528.5 530.\n", + " 530. 530. 530. 530. 530. 530. ]\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0.\n", + " 0. 563.57142857 982. 1274.14285714 1311.71428571\n", + " 1312.57142857 1313.28571429 1313.28571429 1313.42857143 1313.42857143\n", + " 1313.42857143 1313.42857143 1313.42857143]\n" + ] + }, + { + "data": { + "image/png": "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IqJak3MlgyXavXu3CAkJ0a1Q1PeSJEmEhISImJgYk8Z25swZXVyGsIQxykHJ76uxWMIYiYhqgzNqMigrK1NkDbzLly/jzTffhCRJWLlypUHXsoQxykGp76sxWcIYiYhqiokaERERkUJxMQERERGRQnF7DgthCfUTLWGMRERkWXjr0wIsWbIEs2bNQlFREQDA2dkZrq6uAMpXQebl5QEo339s4cKFePnll+UKtc4sYYxERGR5eOvTzG3YsAEREREIDAzEqlWrkJGRAbVajbS0NKSlpUGtViMjIwMrV65Es2bNEBERgR9//FHusGvFEsZIRESWiTNqZs4S6idawhiJiMgycUbNzJ04cQIjR46sVf3EmuwMrySWMEYiIrJMTNTMnCXUT7SEMRIRkWViombmLKF+oiWMkYiILBOfUTNzllA/0RLGSERElomJmgWIiYnB888/jwsXLkCSJL1thBBo3rw5li9fjgEDBpg2QCOwhDESEZHlYaJmISyhfqIljJGIiCwLEzUiIiIiheJiAiIiIiKFYqJGREREpFBM1IiIiIgUiokaERERkUIxUSMisgADBgyocusaIlIuJmpEVCdJSUmQJKnCy8bGBk2aNMGTTz6Jw4cPyx2iRZk7dy4kSUJsbKzcoRCREVnLHQARNWwhISF49tlnAQD5+fk4cuQINmzYgE2bNuH3339H//79ZY6QAGD16tW4efOm3GEQUS0xUSMig7Ro0QJz586tcOz999/HzJkz8fbbbyMuLk6ewKiCZs2ayR0CEdUBb30SkdFNnDgRAHDkyJFK54qLi/Hxxx+jS5cucHJygouLC/r164dffvmlUtucnBzMmTMH7dq1g7OzM1xdXdGiRQuMGzcOycnJuna33/ZbsWIFQkNDYW9vjyZNmuCVV15Bbm6u3ji3bNmCgQMHws3NDQ4ODujUqRM+/vhjlJaWVminvc07fvx4nD9/HiNGjICHhwecnJxw//334/jx45WunZCQgAkTJiA4OBh2dnbw9PREp06d8PLLL+POfcZzc3MRGRmJ9u3bw8HBAe7u7ggPD8fevXvv/maj/PmzefPmAQAGDhyouxUdFBRUoc2dz6itWrUKkiRh1apV2LJlC3r06AFHR0c0adIEb7/9NjQaDQAgKioKnTp1goODA5o1a4YPP/xQbxxCCHzzzTfo06cPXF1d4ejoiK5du+Kb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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0.\n", + " 0. 1243.14285714 2164.85714286 2770.28571429 2856.\n", + " 2856.42857143 2857.14285714 2857.42857143 2857.42857143 2857.42857143\n", + " 2857.42857143 2857.42857143 2857.42857143]\n" + ] + }, + { + "data": { + "image/png": "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448oKSlBREQEAgICdK47b948ANAprxEUFIT33ntP55hmmPfw4cN65Q3FXrduXe3/p6enY82aNXj44YcxZswYnXI+Pj547733cPPmTfzxxx961zGll156CR07dtT+7OrqikcffRR37tzBhAkT0KRJE+25gIAA9OjRA2fPntUZIv7yyy/h7OyM//u//9PpubS3t8fs2bMBAD/99FONtoPIEnHok4iMcvnyZe3zURp+fn7Yu3cvmjZtqj124cIF3L59G/7+/nrlAeDmzZsAgPPnzwMAWrZsiQceeAA//fQTkpOT8eSTT6J3795o164dVCrDv2P27NlT71jjxo0REBCAM2fOoKioCPb29jh27BiAsue27tW1a1c4Ojri+PHjeucM1d2wYUMAQGZmpvbYY489hsmTJ+P111/Hrl27MHDgQISFhekkPEBZcldaWorCwkK9CRlA2XNumnvy6KOPGmyzKbRr107vWP369Ss8V1pairS0NDRo0AB37tzBqVOn4O/vr01071ZcXAzg38+WiCqPiRoRGSU8PBzbtm0DUJZsRUVF4YMPPsDjjz+Ov/76S9vzlZGRAQA4c+YMzpw5U+718vLyAJQ937Z7927MnDkT69evR0REBADA29sbb7zxBqZOnQobGxud92qeEbuXr68v4uPjkZOTAy8vL2RnZ5dbXpIk+Pr64tq1a3rn3Nzc9I5pnjUrLS3VHgsMDMTBgwcxc+ZMbNmyBWvXrgUAtGjRAh9++CGeffZZnXsSGxuL2NjY+96TmlJRuyo6p0nAbt++DSEErl27ZjAJ16jpdhBZIg59EpHJeHt7491338WUKVNw7tw5TJs2TXtO8w/+kCFDIIQo97V8+XLte7y8vLB48WJcu3YNZ8+exZdffom6desiMjIS8+fP16s/LS3NYFxpaWmQJAmurq46sRgqL4RAWlqawQSlKtq0aYOff/4ZGRkZOHDgAGbMmIHU1FQMHTpUm5Rp6oiIiKjwnkRGRhoVS03TtKNDhw4VtmPPnj0yR0pU+zBRIyKTmzJlCvz9/fG///0P8fHxAMqGMt3c3HDkyBFtT0xlSZKEli1b4vXXX8fOnTsBwOByHnv37tU7lpCQgKSkJLRu3Rr29vYAgAcffBAADK7if+jQIRQUFBgc8qsOOzs7dOnSBbNmzcJ///tfCCHw22+/AQA6duwISZJw4MABo+vR9C7e3bNnLq6urmjZsiXOnTunMwRMRMZjokZEJufk5IQPPvgAxcXF+OijjwCUDZdNmDABCQkJePfddw0ma6dPn8aNGzcAlC2FoUny7qbpBXN0dNQ7t3LlSpw8eVL7sxACU6ZMQWlpqXYJCwAYNmwYbG1t8fnnn+P69eva40VFRfjggw8AQKd8VR09elQ7vFpR7H5+fnjuueewf/9+fPrpp3rrqwFliWNldhTQTFJISkqqdtzGmDhxIu7cuYNXX33V4BDn1atXDX6eRFQxPqNGRDVi7NixmDdvHlauXIkpU6ZoZ3v+/fff+O9//4vff/8dvXr1go+PD65du4ZTp07hxIkTOHDgAHx8fHD8+HE8/fTT6NSpE1q1agU/Pz9cu3YNGzduhEqlwttvv61XZ3h4OLp27Yrnn38e3t7e2LVrF44cOYIuXbrgzTff1JYLDg7GvHnzEBERgQceeADPPfccnJ2dsXnzZly4cAFPPPGEdlus6li1ahW++eYb9OrVC8HBwXBzc8PZs2exZcsW1K1bF6NHj9aW/d///ocLFy7g/fffx6pVq9C1a1d4eHggKSkJR44cQVxcHFJSUlCnTp0K69QsdDtlyhScOXMG7u7u8PDw0K5LV9PGjRuHgwcPIioqCrGxsejXrx/8/f2RlpaG8+fP49ChQ/jxxx91FuElokow1zogRGRZKlpHTWPx4sUCgBg+fLj2WElJifjmm29E9+7dhZubm3BwcBCNGjUSAwcOFF999ZXIzc0VQgiRlJQkJk2aJLp06SJ8fHyEvb29aNSokXj66afFgQMHdOq5ew2xJUuWiNatWwsHBwdRv3598Z///EdkZ2cbjG/Tpk0iLCxMuLq6CgcHBxEaGioWLFggiouLDbZ15MiRBq8DQISFhWl/PnjwoBg3bpxo06aN8PDwEE5OTiIkJES88cYbIiEhQe/9d+7cEfPnzxcdOnQQzs7OwsnJSQQFBYknn3xSrFy5Ui+e8qxYsUKEhoYKBwcHAUA0btxYe66iddSWL1+ud62K1mUbOXKkACCuXr2qd27NmjWiX79+wtPTU9jZ2YkGDRqI3r17iwULFoibN29Wqh1E9C9JCAN97UREtcjMmTMxa9Ys7Nmzx+CSG0REtRWfUSMiIiJSKCZqRERERArFRI2IiIhIofiMGhEREZFCsUeNiIiISKGYqBEREREpFBM1IiIiIoViokZERESkUEzUiIiIiBSKiRoRERGRQjFRIyIiIlIoJmpERERECsVEjYiIiEih/h8eWDcRzP26+AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0. 0. 2188.25 3660.875\n", + " 4482.625 4628.375 4628.875 4629.75 4629.875 4629.875 4629.875 4629.875\n", + " 4629.875 4629.875]\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0. 0. 2678.5 4438.8 5344.2 5631.3\n", + " 5632.8 5633.5 5633.8 5634. 5634. 5634. 5634. 5634. ]\n" + ] + }, + { + "data": { + "image/png": "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R48yibUQArGxsZg+fTrOnTuHzz//3KA6te0DStoGlPzC2LJlyzJlU1JSULdu3WrX9dZbb2HkyJHo0qULPvzwQwwcOLDMPbtx4wZ27NiBOXPmICkpCXPnzq12fVqmbCNQ8ndy48aN+OCDD9CwYcNKy6ampmLjxo0V9vLrSwiBGTNmYMmSJcjKyqq0bEUJXE1homZCvXv3xvbt2xEXF1elRM0Y6+GEh4eXe7y8BCMuLg6HDx/G66+/Xu36GjduDEmSdP+g2draonHjxvjrr7/KJGq5ubn4888/MXTo0GrXB5i+jR06dMB3332Ho0ePon///g8sX7duXTRu3Lja9QElv8GV16Nz6dKlMknMnTt38Ndff+H55583qM4TJ06UWWdoy5Yt5SZq+/fvR1BQkEH1mbqNo0aNgr+/f5WThEWLFiEiIqLa9WklJCSUWVgzKiqqTBJTVFSEvXv3Gvw9sGXLFvz0008A/u192L59O1577bUyZU+dOmWUniZTt/GNN97AqVOnsHLlSvTp0wdOTk7w9/fX9QRnZmbi77//Rk5ODoQQGDduHN544w2D6oyOji6VyAAlazeWl8QcOXIEzZs3r3ZdL730EhISEhAREaFbj9HZ2blU+7RDuVZWVpg1axZefPHFatenZco2AkBYWBiGDBmC9u3b46233sLAgQMRGBhYqp1xcXHYsWMHlixZglu3biEsLMygOrVmzZqFOXPmwN3dHaNGjYKPj88De2dNRRLG7jekWis7Oxu3b99GnTp1anQBU62LFy9iw4YN6Nevn8m6ko3RxtzcXNy4cQP16tWrcBhATgkJCYiJiUGHDh2qnTwlJiaWe9zR0RGenp6ljp04cQLvvPMORo4ciVdeeaVa9enLGG1UujNnzmDRokV46qmn8OSTT1brGhU9v+Pv71/m79yxY8fQqVMnvPfee/j444+rVZ++jNHGe+3ZswfLly9HTExMmedCGzZsiODgYEyYMKHc3n19xMTElHvc09MTrVq1KnXs2LFjGDZsGF577TW8//77BtV7+fJlfPPNN5UueDt27FgEBgYaVA8gXxvXrVuHt956CxkZGRU+biCEgJubG7744gujLXzdpEkTSJKEI0eOGNwzaGxM1IiIyOzcvXu3VCJjjGdhyTQyMjKwadOmShPS559/3qiPntjb22Py5Mn47LPPjHZNY2GiRkRERBat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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0. 0. 3701.7 6257.55 7536.15\n", + " 8274.2 8279.3 8280.1 8280.4 8280.7 8280.7 8280.7 8280.7 8280.7 ]\n" + ] + }, + { + "data": { + "image/png": "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3boVLi4u6Ny5s4miJiIiIjI9xSVqDz30EJo3b44ff/wRR44c0R3PycnBnDlzYG9vj1GjRumOZ2Zm4syZM3rDnOPHjwdwZwjz7jV9v/32W1y4cAHPPfccnJycarcxREREREZQ3M4EQPlbSKWkpOCTTz4ps4XUmDFjEBMTg6VLl2LMmDG64xqNBoMHD9ZtIRUWFobz58/jl19+QUBAAPbu3VutLaS4MwERERGZQp3emQAA+vXrh507d6JXr15YvXo1vvnmGzRq1AirVq2q0j6fAKBSqbB+/XrMnDkTV65cwWeffYaEhAS8+OKL2L17N/f5JCIiIsVTZI+aErFHjYiIiEyhzveoERERERETNSIiIiLFYqJGREREpFBM1IiIiIgUiokaERERkUIpbq9PpdJOjtXuE0pERERUE9pcoioLbzBRq6Lc3FwAqNWN2YmIiMh65ObmwsPDo8IyXEetijQaDS5dugQ3NzdIkmTy66vVavj5+SEtLc1s67SZu0620TLqZBsto0620TLqZBvrZp1CCOTm5sLX1xcqVcVPobFHrYpUKhWaNm1a6/W4u7ubfUFdc9fJNlpGnWyjZdTJNlpGnWxj3auzsp40LU4mICIiIlIoJmpERERECsVETSEcHBwQFRUFBwcHi62TbbSMOtlGy6iTbbSMOtlGy6mzPJxMQERERKRQ7FEjIiIiUigmakREREQKxUSNiIiISKGYqBEREREpFBM1IiIisirHjh3D5cuX5Q6jSpioERERkVW57777sHDhQt3PDz74IJYvXy5jROVjombl8vLycPnyZWg0GrlDqTXW0EaqfdevX0dqaqrcYRCRCdjY2KC0tFT3c1xcHJKTk+ULqALc61PBlixZgoSEBHz//fc1vkZqaio8PT319ir7448/MG3aNBw/fhwA4OLigmHDhuGjjz6Cl5eXUXEbkp+fj0WLFiEhIQH5+fkICAjAiBEj0Lt3b6OvrZQ2lmfXrl04f/48Ro0aZfJrp6en45NPPilzX5977jk899xzJq9L68iRI2XqGzRoENzc3GqtPjnaaEhERARWrFiBkpISk19bCIH169eXaePTTz+NwMBAk9elpdFocPr0aeTn58Pf3x+NGjWqtboA87UxPT0d8fHxSExMRE5ODoA7eyoGBwejT58+8PPzM2l997p69Sr27t2ra2OXLl0gSZLJrr9z585y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xlTps2zatCmGDRtmdJ1aS5cuNcl1agMTNTMKDQ1Famoq3n333SqVP3PmjEkSteTkZPz9998AgMLCQgBAZmYm/P399cpmZWUZPSPy7tk/2r9weXl5cHR01Cubn58PZ2dno+oDzNvGli1borCwEJs2bapS+bFjx5pkfZ6776s2eblx44bBhPTGjRtwdXU1uk4tDw8PAHf+MTfExsam3HPVYc423n///di0aRMKCwvh4OBQrdhMpUGDBgDu/EPs4uKid764uBj29vYmq8/W9s5Xfr169Qyer1evnsn/gTdHG1u0aIENGzZg1qxZujaWp7i4GBs2bECLFi2MqvNuTk5OAGCwfdrjxiwP1LZtW8TGxiIqKqrSP/NqtRqxsbFo27ZtjeszpLbbCNyZGWyO91SkpKQEZ8+exc2bN8ss33G3Pn36mLTOyjBRM6P7778fhw4dQlpaWq1PEb9bTEyM7rcOIQQkSUJcXBxGjx6tV/b06dPl9mBU1Weffab77USbNJ04cQJ9+/bVK5uSkmKSZQHM2cZOnTph1apVuHnzJjw9PWt8neqaOXMmZs6cWebY4cOHMWjQIL2yFy9erFYPgyHr1q3TrSt06dIlAEBSUhI6duyoVzY9PV33D7IxzNnG++67D7///juOHj2Krl27Vlpe3HlUpMb1aS1btgxxcXEAgJs3bwIAzp07h27duumVTUtLQ8OGDY2q78iRI7pfFLTrwKWnpyMoKEivbEZGRrlJXHWYu40vvfQSXn/9dQwYMACzZs1Cz5499RJrIQQSEhIwffp0nDp1Cp9//rlRdWrbB9xpG3DnF8aQkBC9sunp6ahfv36N65o8eTJGjhyJrl274r333kP//v317tnly5exZcsWzJ49G6mpqZgzZ06N69MyZxuBO38nV69ejSlTpqBx48YVls3IyMDq1avL7eWvLiEEZsyYgS+//BK5ubkVli0vgastTNTM6IEHHsDmzZuRmJhYpUTNFOvhREVFGTxuKMFITEzE/v378corr9S4vmbNmkGSJN0/aPb29mjWrBn++ecfvUStoKAAf//9NwYPHlzj+gDzt7FTp0746aefcPDgQTz00EOVlq9fvz6aNWtW4/qAO7/BGerROXfunF4Sc+PGDfzzzz945plnjKrzyJEjeusMrVu3zmCitnv3boSGhhpVn7nbOGrUKAQGBlY5SZg/fz6i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sMz+/fuFp6encHd3F4MHDzZ66PPTTz8Vjo6Ouhm7bm5uokmTJqJJkya64UhJkoSjo6P47LPPjKpLiOp9jsXFxeLnn38WgwcPNrre6hgzZozR99Wcs+n79eunNxs3KSlJBAYG6s2uV6lUYtq0aTWuS0uO2fT3Sk9PFzt27BDr1q0T69atEzt27BDp6ekmu355qxJU9JLjUQQmamb2wQcfCDs7O91fbnd3d+Hn5yf8/Px0SZL2WZzZs2cbXd9nn30mJEkSf//9d4XlNBqNGD16tEn+IJq7jTVJ1IxRWFgowsPDdfcqJCREPP7442LkyJFi5MiR4vHHHxchISG6L9CBAwcaPZFh2rRpQqVSiaSkpArLXbt2TXTs2NHoz1GONpr7c+zevbsIDAwUarW60rI3b94UAQEBlSbLlZk4caJwcnISN2/erLDc/v37hZeXl+7vSk3JkYya+3OsCWMTtb179wobGxthb28vwsPDxaOPPiocHR2FSqUSEydO1CtvbKJm6J527dpVSJIkRo0aJRISEsTZs2dFTEyM8PHxESqVSvz11181rk9bZ7t27USDBg103wPNmjUTUVFRIjk52ahrV6SwsFB8+OGHokWLFro///e+goKCxLx588Tt27eNqis5OblGL3NjoiaDxMREMXXqVNGzZ0/h7e0t7O3thb29vfD29hY9e/YUU6dOLXd9rOrKyMgQU6ZMEb/++mulZTUajYiKijLJrBZztnHZsmXiyJEjJrlWVWk0GvH999+LHj166GaY3v2ysbERPXr0EEuXLjXJb6FHjhwR3bt3F1999VWlZa9fvy7CwsJEQECAUXWau41jxowR69evN/o6VeXi4iLefvvtKpePiIgQLi4uRtW5ceNGIUmSmDNnTqVlDxw4oEvWakqOZDQgIEB8/vnnRl2jurTrv1X11bt3b6Puq7ln09+bqO3du1dIkiRGjx6tV/b06dPC3t5ePPnkkzWu7+46zTWbXggh8vLyRLdu3XQ9vwMHDhSvvfaaeO+998R7770nXnvtNTFw4EDd2o7du3cXeXl5JqtfqZioERnp9u3b4uTJk2LXrl1i165d4uTJk6KgoEDusEzKEtvo6elZrRnK48ePF56enkbXe/v2bVFcXFylstevXzfqN3g5klE53L0Ic1VexvY4m3s2/b2J2ldffSVUKlW5yyANGTLE5LOwhajd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zs42GFd2djYkSYKbm1uZWAyVF0IgOzvbYIJSHe3atcPPP/+M69evY/fu3ZgxYwaysrIwbNgwXVKmrSMiIqLCexIVFWVULLVN247777+/wnbs2LFD5kiJ6h4makRkcpGRkfD19cX//d//ITk5GcCdoUx3d3ccOHBA1xNTVZIkISQkBK+88gq2bt0KAAaX8/jnn3/0jqWkpCAtLQ1t27aFvb09AOC+++4DAIOr+O/duxe3b982OORXE3Z2dujevTuio6PxxRdfQAiBP/74AwDQpUsXSJKE3bt3G12Ptnfx7p49c3Fzc0NISAhOnz5dZgiYiIzHRI2ITM7JyQnvvvsuiouLMWvWLAB3hssmTZqElJQUvP322waTtRMnTuDy5csA7iyFoU3y7qbtBXN0dNQ7t3z5chw7dkz3sxACkZGRKC0t1S1hAQAjRoyAra0tPv30U1y6dEl3vKioCO+++y4AlClfXQcPHtQNr1YUu4+PD5555hns2rULH3/8sd76asCdxLEqOwpoJymkpaXVOG5jTJ48Gbdu3cJLL71kcIjz4sWLBj9PIqoYn1Ejoloxfvx4zJs3D8uXL0dkZKRutuehQ4fwxRdfYMOGDejTpw8aNmyIjIwMHD9+HEePHsXu3bvRsGFDHDlyBE8++SS6du2KNm3awMfHBxkZGVi3bh1UKhXefPNNvTrDw8PRo0cPDB8+HN7e3ti2bRsOHDiA7t2747XXXtOVCwoKwrx58xAREYH27dvjmWeegYuLC37//XecPXsWTzzxhG5brJpYsWIFvv32W/Tp0wdBQUFwd3fHqVOnsHHjRtSrVw9jx47Vlf2///s/nD17Fv/973+xYsUK9OjRA56enkhLS8OBAweQmJiIzMxMODs7V1indqHbyMhInDx5Eh4eHvD09NStS1fbJkyYgD179iAmJgYJCQl4+OGH4evri+zsbJw5cwZ79+7Fjz/+WGYRXiKqAnOtA0JElqWiddS0vvzySwFAjBw5UnespKREfPvtt6JXr17C3d1dODg4iGbNmomBAweKb775RuTl5QkhhEhLSxNTpkwR3bt3Fw0bNhT29vaiWbNm4sknnxS7d+8uU8/da4gtWrRItG3bVjg4OIjGjRuL119/XajVaoPxrV+/XoSFhQk3Nzfh4OAgQkNDxfz580VxcbHBto4ePdrgdQCIsLAw3c979uwREyZMEO3atROenp7CyclJBAcHi1dffVWkpKTovf/WrVvio48+Evfff79wcXERTk5OIjAwUAwZMkQsX75cL57yLFu2TISGhgoHBwcBQPj7++vOVbSO2tKlS/WuVdG6bKNHjxYAxMWLF/XOrV69Wjz88MPCy8tL2NnZiSZNmoi+ffuK+fPniytXrlSpHUT0L0kIA33tRER1yMyZMxEdHY0dO3YYXHKDiKiu4jNqRERERArFRI2IiIhIoZioERERESkUn1EjIiIiUij2qBEREREpFBM1IiIiIoViokZERESkUEzUiIiIiBSKiRoRERGRQjFRIyIiIlIoJmpERERECsVEjYiIiEihmKgRERERKdT/A/xQjQvGghK3AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0.001\n", + "1 0.0025\n", + "2 0.005\n", + "3 0.0075\n", + "4 0.01\n", + "5 0.025\n", + "6 0.05\n", + "7 0.075\n", + "8 0.1\n", + "9 0.25\n", + "10 0.5\n", + "11 0.75\n", + "12 1.0\n", + "13 2.5\n", + "14 5.0\n", + "15 7.5\n", + "16 10.0\n", + "17 inf\n", + "[ 0. 0. 0. 0. 0. 0. 3701.7 6257.55 7536.15\n", + " 8274.2 8279.3 8280.1 8280.4 8280.7 8280.7 8280.7 8280.7 8280.7 ]\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmoAAAHKCAYAAACzJmcMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAABmgUlEQVR4nO3deVxUVf8H8M8d9h1UFFEERFRU1MxdE60Utc0nK81yK3NpsYV6UlKRTM3Ksu2XpaaolUuUVmpqKpS477siyirgzgAi25zfHz4ziTOsM8y9zHzer9e8invP3PM9d3T8cs4950hCCAEiIiIiUhyV3AEQERERkWFM1IiIiIgUiokaERERkUIxUSMiIiJSKCZqRERERArFRI2IiIhIoZioERERESkUEzUiIiIihWKiRkRERKRQTNSIiIiIFIqJGhFZvKysLKxcuRJvvPEGevfuDRcXF0iShICAgErfm5OTg/fffx8dO3aEq6srXF1d0b59e8yaNQu3bt0y+J7S0lJs27YNERER6NGjB+rVqwc7Ozs0aNAADz/8ML7//nuUlpZWWvcPP/yAPn36wMvLCy4uLggNDcXs2bNx+/bt6t4CIqqjJO71SUSWbsGCBXjzzTf1jvv7+yM5Obnc9yUlJaF///64ePEiJElCSEgIHBwccOLECRQXFyMkJATx8fHw9vYu874lS5Zg3LhxAABJkhAUFAQPDw9cvHgR169fBwD06tULGzZsgIeHh169QgiMHTsWMTExAICAgAB4enri5MmTKC4uxn333Ye4uDi4u7vX9JYQUR3BHjUisnju7u546KGH8O6772Lt2rWYP39+pe/RaDR48skncfHiRbRs2RKnTp3CyZMncejQIaSlpaFfv344ffo0RowYofdeIQTatWuHb7/9FlevXkViYiIOHDiAq1ev4vvvv4e9vT0SEhLw8ssvG6x74cKFiImJgb29PX7++WdcvHgRhw8fRlJSEtq3b4/Dhw9j0qRJRt8XIlI+9qgRkdVZtWoVnn322Qp71DZs2IBHH30UAPDPP/+gd+/eZc5funQJLVu2RH5+PrZt24YHH3xQd+769evw8vKCJEkGrz179mxMmzYNNjY2uHz5MurVq6c7V1JSgqZNmyI7OxuRkZGYPXt2mfeeOXMGbdu2hRACJ06cQJs2bWpyC4iojmCPGhGRAf/88w8AoEmTJnpJGgD4+vqiT58+AIAff/yxzLl69eqVm6QBwODBgwHceZYtMTGxzLm///4b2dnZAICJEyfqvbd169YICwuDEAJr1qypRouIqC5iokZEZMC1a9cA3EnUyuPn5wcA2LlzZ7WuXVBQoPt/FxeXMud27doFAAgMDNRd/15hYWFlyhKR5WKiRkRkgKenJwAgIyOj3DJpaWkAgPPnz6OkpKTK19b2wHl7eyMkJKTMuXPnzgEAWrRoUe77g4KCAABnz56tcp1EVDcxUSMiMqBbt24A7iRqhnquMjMzdcOjpaWlUKvVVbruvn378O233wIApkyZAhsbmzLntbNC735u7V7aczdu3KhSnURUdzFRIyIy4PHHH4e/vz8AYMyYMTh69KjuXEZGBoYNG4a8vDzdsfLWVLtbZmYmhg4dipKSEvTp0wevv/66XhntsKi9vX2513F0dKxynURUtzFRIyIywN7eHmvXrkW9evWQmJiI++67D4GBgQgJCYG/vz927dqlWysNQKVrml29ehX9+/dHeno62rRpg9jYWL3eNABwcnICABQVFZV7Le2Ct87OzjVpGhHVIUzUiIjK0aVLFxw9ehSvvfYamjdvjszMTGRnZ2Pw4MHYtWsXHnroIQB3JgS4ubmVe50bN26gf//+OHnyJFq2bIlt27ahQYMGBst6eXkB+HcygyHa4VFtWSKyXLZyB0BEpGRNmzbFF198gS+++ELv3G+//QYA6Ny5c7nLceTk5KB///44cuQIWrRogR07dsDHx6fc+lq1agXgzgSF8iQlJZUpS0SWiz1qREQ1tH79egDAkCFDDJ5Xq9UYMGAADh48iObNm2PHjh3w9fWt8Jo9evQAACQnJ+tmld4rPj6+TFkislxM1IiIaiAmJgYnTpxA/fr1MWbMGL3zeXl5GDhwIPbt24fAwEDs2LEDTZs2rfS6YWFhaNiwIYA7W0nd68yZM4iPj4ckSXjmmWeMbgcRKRsTNSKicvz111/Yvn07NBqN7lhhYSG++uorjB8/HgDw9ddf69Zc07p16xYeffRR7N69GwEBAYiLi0OzZs2qVKetrS2mT58OAPjkk08QGxurO5eWloZhw4ZBo9HgmWeeQdu2bY1sIREpHff6JCKLl5aWhvvuu0/3c1FREXJzc6FSqco8kN+rVy/dcCYAzJw5E9HR0XBxcUFAQADs7e2RmJiIvLw8ODg44IsvvtAlbHebO3cuIiMjAQDBwcG6HjJD3nvvPQwaNKjMMSEERo0ahZUrVwK4s0uBh4cHTp48ieLiYrRv3x7x8fF6CSIRWR5OJiAii1daWmpwFqVGoylzPCcnp8z5gQMH4uLFi9izZw9SU1N1G6YPGDAAr7/+OoKDgw3WV1hYqPv/xMREvf0876bd1/NukiRhxYoVGDBgAL777jscP34cWVlZaNmyJYYPH463335bt5YaEVk29qgRERERKRSfUSMiIiJSKCZqRERERArFRI2IiIhIoZioERERESkUEzUiIiIihWKiRkRERKRQXEetijQaDS5dugQ3N7dyN18mIiIiqowQArm5ufD19YVKVXGfGRO1Krp06RL8/PzkDoOIiIgsRFpaWqV7ADNRqyI3NzcAd26qu7u7zNEQERFRXaVWq+Hn56fLLSrCRK2KtMOd7u7uTNSIiIjIaFV5lIqTCYiIiIgUiokaERERkUIxUSMiIiJSKCZqRERERArFRI2IiIhIoRSZqK1cuRITJkxA586d4eDgAEmSsGzZsmpfR6PR4Msvv0RoaCicnJzg7e2NZ599FhcuXDB90EREREQmpshEbdq0afjuu++QkpKCxo0b1/g6EyZMwOTJkyGEwOTJkzFw4ED88ssv6NKlCxITE00YMREREZHpKTJRW7x4MZKTk3HlyhVMnDixRtfYsWMHFi9ejD59+uDQoUOYN28eVqxYgXXr1uH69et49dVXTRw1ERERkWkpcsHbhx9+2OhrLFq0CAAwa9Ys2Nvb644PGjQIffv2xZYtW5CamopmzZoZXRcRERFRbVBkj5opxMXFwcXFBb169dI7Fx4eDgCIj483d1hEREREVabIHjVj5efnIzMzE+3atYONjY3e+eDgYACo8Dm1wsJCFBYW6n5Wq9WmD5SICIAQApvOXEbS1VsQENAIQCMExL3/xZ3/agTKP6eB7hpC3HUtABrNv+W079OLRS82Q/EaOKb3Tv1yBt5W7v2otEyVr1WFMlW8WlWuRZbDz9MJcx8JkTsMy0zUcnJyAAAeHh4Gz2v36tSWM2Tu3LmIjo42fXBERHcpKdVgUuxxLN6bKncoRHSX0MZuTNSUbOrUqXjrrbd0P2t3uiciMpW8whI8s/wgNp25DJUEPN7WBw62KqgkCRIAlQr//r8kQZLK/lclARL+91/tz1LZ9/xb/q4yd73n3j2h790iWv+8VMn5e98vVXi+PFXYq1ovFmOuZcr3kWVo4GJfeSEzsMhETduTVl6PmXYYs7weNwBwcHCAg4OD6YMjIgKQpb6NR5bsw6H0HDjZqfDT8/fjiXY+codFRApjkYmai4sLGjdujIsXL6K0tFTvOTXts2naZ9WIiMzpTHYuBi3ei+TrBWjgYo8/XuyKbv5ecodFRApksbM+w8LCkJ+fj4SEBL1zmzdvBgD06dPH3GERkZX758I19PwyAcnXC9CigQt2T+7NJI2IylXnE7WrV6/izJkzuHr1apnj48ePBwBMnz4dRUVFuuObNm1CXFwcBgwYAH9/f7PGSkTWbe3RS+j/7R7cKChGd38v7HqtF1o0cJE7LCJSMEUOfS5evBg7d+4EABw/flx3LC4uDgDQu3dvjBs3DgDw1VdfITo6GlFRUZg5c6buGv369cO4ceOwePFidOrUCY888ggyMzOxevVq1KtXD19++aVZ20RE1u2z+CRE/H4KQgBPtG2EH5/vBGd7RX4FE5GCKPJbYufOnYiJiSlzLCEhocwwpjZRq8i3336L0NBQfPfdd/j888/h6uqK//znP5g9ezaCgoJMHjcR0b1KNQIRv53E5/9cBAC82isAC4a0g42KUwqJqHKSqMrKggS1Wg0PDw/k5OTo1mEjIqpIQXEpnv/hEH45ngUA+PjRNojo21xvyQoisi7VySkU2aNGRFTXXc0rxBNL92NX8g3Y26gQ82xHDL+vidxhEVEdw0SNiMjELlzLx8Dv9iLxaj48neywbmxnhAU1kDssIqqDmKgREZnQ/tSbeHTJXlzOK0IzLydsGtcNbXzc5A6LiOooJmpERCbyx6lsDFtxELeKStHR1x0bxnWDr4ej3GERUR3GRI2IyAQW7krGK78ch0YA4a28sXZUZ7g58iuWiIzDbxEiIiMIIfDepjOYu+08AOCFrn5Y+FR72NnU+fXEiUgBmKgREdVQUYkGL6w+gh8OZQAAZg5oiRkDWnL5DSIyGSZqREQ1kFNQjCeXHcD281dhq5Lw3dPtMbZrM7nDIiILw0SNiKia0m4UYPDivTiRlQtXBxvEju6MAa0ayh0WEVkgJmpERNVw7JIagxfvRUbObTR2d8DGcd3QsYmH3GERkYViokZEVEV/nbuCJ5cdQG5hCdo0csWml7qhmZez3GERkQVjokZEVAXLD6ThxdVHUaIRCAuqj1/HdIaXs73cYRGRhWOiRkRUASEEZv+ViOl/ngUADO/oi2XPdoSDrY3MkRGRNWCiRkRUjpJSDSbFHsfivakAgP/2C8LcwSFQqbj8BhGZBxM1IiID8gpLMGzFQWw8fRkqCfhiSDu80jtQ7rCIyMowUSMiukd2biEeWbwXB9Nz4GSnwk/P348n2vnIHRYRWSEmakREdynVCAxZuh8H03PQwMUef7zYFd38veQOi4isFBM1IqK7fP7PBexJuQF3R1vseq0Xgr1d5Q6JiKwYdw0mIvqf81fz8d7GMwCA+Y+1YZJGRLJjokZEBECjERi35ihul2jwUHADvNiN+3YSkfyYqBERAfh2Twrik67B2d4Gi57uAEniEhxEJD8makRk9VKu38J//zgFAPhwcAgC63NbKCJSBiZqRGTVhBAYv/YY8gpL0SvAC6/0CpA7JCIiHSZqRGTVlu1Pw5ZzV+Boq8L3wzty1wEiUhQmakRktS7l3Mab608CAN4f2AotOcuTiBSGiRoRWSUhBCb+fAw5t0vQxc8Tb/ZpLndIRER6mKgRkVVadfgSfj+VDTsbCd8P6wBbG34dEpHy8JuJiKzOlbxCTF53AgAwvX9LtGvsLnNERESGMVEjIqvz2q8ncDW/CB183THlwRZyh0NEVC4makRkVX49nonVRy7BRnVnyNOOQ55EpGD8hiIiq3H9VhFejj0OAPhvvyB0auopb0BERJVgokZEVuOt9SeRlVuI1g1dMaN/S7nDISKqFBM1IrIKm05nI+ZAOiQJ+H5YBzja2cgdEhFRpZioEZHFU98uxvi1xwAAbzzQHD0C6skcERFR1TBRIyKL998/TiM95zaC6jvjg0Gt5A6HiKjKmKgRkUXbcf4qvt2dAgBY/EwHONvbyhwREVHVMVEjIouVX1iCcWuOAgAm9fRH3xYNZI6IiKh6mKgRkcWa9ucZXLh2C36ejvjwkRC5wyEiqjYmakRkkXZdvI7P/7kIAPju6Q5wd7STOSIioupjokZEFud2cSleWH0EQgBjuvhhYOuGcodERFQjTNSIyOJEbzmHs1fy4ePmgE8fbyN3OERENabYRG3//v0YPHgwPD094eLigu7du2PNmjXVusalS5fw+uuvo02bNnBxcUGjRo3Qu3dvrFixAqWlpbUUORHJ6UDaTXwclwQAWPhUe3g528scERFRzSlynvqOHTsQHh4OR0dHDB8+HG5uboiNjcWwYcOQlpaGiIiISq9x4cIFdOvWDdeuXUN4eDgee+wxqNVqrFu3DqNGjcL27duxdOlSM7SGiMylqESDF1YfQalGYHhHXzzRzkfukIiIjCIJIYTcQdytpKQErVu3Rnp6Ovbs2YOOHTsCAHJyctC1a1ckJyfj3Llz8Pf3r/A6L7/8Mr755hssWLAAr7/+uu74zZs30aFDB6SmpiI5ObnS62ip1Wp4eHggJycH7u7uNW4fEdWe97ecQ9Tms2jgYo9T/+0Lb1cHuUMiItJTnZxCcUOf27dvR1JSEkaMGKFL0gDAw8MDkZGRKCoqQkxMTKXXuXDhAgBg8ODBZY57enqid+/eAICrV6+aLnAiktXxTDU++OscAOCr/7RjkkZEFkFxiVpcXBwAYMCAAXrnwsPDAQDx8fGVXqddu3YAgI0bN5Y5fvPmTSQkJMDHxwdt2vAhYyJLUFJ6Z8izuFRgSDsfPNPRV+6QiIhMQnHPqCUmJgIAgoOD9c75+PjA1dVVV6Yi77zzDn7//Xe8+eab+PPPP9G+fXvdM2rOzs749ddf4eTkZPL4icj8Po2/gANpOfB0ssP/DQ2FJElyh0REZBKKS9RycnIA3BnqNMTd3V1XpiKNGjXC7t278fzzz2PTpk34888/AQBOTk6YOHEiOnToUOH7CwsLUVhYqPtZrVZXtQlEZEZnL+dhxuazAIDPHm+Lxu6OMkdERGQ6ihv6NJXz58+jV69euHLlCv755x/k5uYiLS0NM2bMwKxZs/DQQw9VuETH3Llz4eHhoXv5+fmZMXoiqopSjcALq4+gsESD8FbeGN2lqdwhERGZlOISNW1PWnm9ZtqZEpUZM2YMUlJS8Pvvv6N3795wdXVF06ZNMWXKFLz22mvYvXs3Vq1aVe77p06dipycHN0rLS2tZg0iolrzdcJF7Eq+AVcHG3z3dHsOeRKRxVFcoqZ9Ns3Qc2hZWVnIy8sz+Pza3XJzc5GQkICQkBD4+Oivo9SvXz8AwOHDh8u9hoODA9zd3cu8iEg5LlzLx9SNZwAAHz/aBs28nGWOiIjI9BSXqIWFhQEAtmzZondu8+bNZcqUp6ioCED5y29cuXIFwJ1kjIjqHiEEXlpzDLeKStE3qD7Gd6/aeohERHWN4hK1hx56CM2bN8ePP/6II0eO6I7n5ORgzpw5sLe3x6hRo3THMzMzcebMmTJDpfXr10erVq2QmpqKxYsXl7n+zZs38cknnwD4t2eNiOqWxXtTsf38VTjZqbD4mQ5QqTjkSUSWSXGJmq2tLRYvXgyNRoM+ffpg/PjxiIiIQIcOHXDu3DnMmTMHAQEBuvJTp05FSEgIfv311zLX+eyzz2Bra4uXXnoJDz/8MN555x2MGzcOLVu2xJkzZzB06FA8/PDDZm4dERkr7UYBIn47BQCYMzgEQQ1cZI6IiKj2KG55DuBOT9fOnTsRFRWF1atXo7i4GKGhoZg3bx6GDRtWpWsMGjQIu3btwscff4ydO3ciPj4ejo6OCAkJwYwZMzBp0qRabgURmZoQAhNjjyG3sAQ9/L3wWu9AuUMiIqpVitvrU6m41yeR/FYcSMOon47A3kaFIxF9ENLITe6QiIiqrU7v9UlEZEiW+jZeX3cSADAzvCWTNCKyCkzUiEjxhBB4+ZfjuFFQjE5NPfB23yC5QyIiMgsmakSkeD8fy8Svx7Ngq5Lw/bAOsLPhVxcRWQd+2xGRouUUFOPVX44DACIfCkYH38p3JiEishRM1IhI0X45nonLeUUIbuCCyIdbyB0OEZFZMVEjIkX7+VgmAGBU56ZwsLWRORoiIvNiokZEinWzoBhbz93Z8u2p9o1ljoaIyPyYqBGRYv1+MgvFpQJtfdzQmstxEJEVYqJGRIqlHfZkbxoRWSsmakSkSOrbxdh8lsOeRGTdmKgRkSJtOHUZhSUatPJ2QVsfDnsSkXViokZEivTzsUsAgKc6+EKSJJmjISKSBxM1IlKcvMISbDx9GQCHPYnIujFRIyLF2XTmMm6XaBBU3xkdfN3lDoeISDZM1IhIcX4+qp3tyWFPIrJuTNSISFFuFZVgw+lsAMBTHTjsSUTWjYkaESnK5rNXkF9UCn8vJ9zflBuwE5F1Y6JGRIry77BnYw57EpHVY6JGRIpxu7gUv5/SDnv6yhwNEZH8mKgRkWJsPXcFuYUlaOrhiK5+nnKHQ0QkOyZqRKQY2r09h7ZvDJWKw55EREzUiEgRiko0WH8iCwAXuSUi0mKiRkSKsC3xCnJul6CxuwN6BtSTOxwiIkVgokZEiqAd9nwylMOeRERaTNSISHbFpRqs47AnEZEeJmpEJLu489dw/VYxvF3t8UDz+nKHQ0SkGEzUiEh2Px+7BODOsKcNhz2JiHSYqBGRrEpKNfiVw55ERAYxUSMiWf1z8Tqu5BWhvrMdwoI47ElEdDcmakQkK+3enkPaNYadDb+SiIjuxm9FIpJNqUbgl+P/24S9A4c9iYjuxUSNiGSzK/k6snIL4elkhwdbNJA7HCIixWGiRkSy0S5y+0TbRrC35dcREdG9+M1IRLLQaARij2mHPX1ljoaISJmYqBGRLPam3kBGzm24Odiif0sOexIRGcJEjYhkoR32fLxtIzjY2sgcDRGRMjFRIyKzE0LoEjUucktEVD4makRkdgfScpB6owAu9jYIb91Q7nCIiBSLiRoRmZ12b89H2zSCkx2HPYmIysNEjYjMisOeRERVx0SNiMzqSIYaF67dgpOdCoM47ElEVCHFJmr79+/H4MGD4enpCRcXF3Tv3h1r1qyp9nUuX76MN998E8HBwXB0dET9+vXRo0cPfPPNN7UQNRFVRjvsOTikEVwcbGWOhohI2RT5Lbljxw6Eh4fD0dERw4cPh5ubG2JjYzFs2DCkpaUhIiKiStc5cuQIBgwYgBs3buCRRx7BU089hby8PJw+fRq///47Jk2aVMstIaK7CSGw9iiHPYmIqkoSQgi5g7hbSUkJWrdujfT0dOzZswcdO3YEAOTk5KBr165ITk7GuXPn4O/vX+F11Go1QkNDUVBQgL/++gvt27fXq8fWtup5qlqthoeHB3JycuDu7l7tdhERcDxTjfafxMPBVoUr0eFwc1Tk74pERLWqOjmF4oY+t2/fjqSkJIwYMUKXpAGAh4cHIiMjUVRUhJiYmEqv83//939ITU3Fhx9+qJekAahWkkZEpvHz/3rTBrbyZpJGRFQFivumjIuLAwAMGDBA71x4eDgAID4+vtLrrF69GpIkYejQoTh79iy2bNmCgoICtG7dGgMHDoS9vb1J4yaiymmfT+PenkREVaO4RC0xMREAEBwcrHfOx8cHrq6uujLlKSoqwvHjx+Ht7Y0vv/wSUVFR0Gg0uvPNmzfHunXrEBoaatrgiahcp7JycSo7D3Y2Eh5r00jucIiI6gTFDX3m5OQAuDPUaYi7u7uuTHmuX7+O0tJSXLt2De+//z4++ugjZGdnIz09HdOnT8fFixfx2GOP4fbt2+Veo7CwEGq1usyLiGou9vidYc8BLb3h4WQnczRERHWD4hI1U9D2npWWluLll19GREQEGjZsiCZNmuD999/H008/jZSUFPz888/lXmPu3Lnw8PDQvfz8/MwVPpFF+lk325PDnkREVaW4RE3bk1Zer5l2pkRVrgEAjz/+uN557bEDBw6Ue42pU6ciJydH90pLS6s0diIy7NyVPBzLVMNWJeHxdhz2JCKqKsUlatpn0ww9h5aVlYW8vDyDz6/dzcXFBU2aNAEAeHp66p3XHisoKCj3Gg4ODnB3dy/zIqKaif3fllEPBTdAPWdO5CEiqirFJWphYWEAgC1btuid27x5c5kyFXnwwQcBAKdOndI7pz0WEBBQ0zCJqBq4tycRUc0oLlF76KGH0Lx5c/z44484cuSI7nhOTg7mzJkDe3t7jBo1Snc8MzMTZ86c0RsqnThxIgDgww8/xM2bN3XHs7Ky8Pnnn0OlUmHo0KG12hYiAi5cy8eh9BzYqCQMaecjdzhERHWK4hI1W1tbLF68GBqNBn369MH48eMRERGBDh064Ny5c5gzZ06ZnrCpU6ciJCQEv/76a5nr9OzZE2+99RZOnjyJ9u3b45VXXsH48ePRoUMHZGRk4IMPPkDLli3N3Doi66Md9uwbVB8NXB1kjoaIqG5R3DpqANCvXz/s3LkTUVFRWL16NYqLixEaGop58+Zh2LBhVb7O/PnzERoaiq+//hrLli2DJEm47777sHDhQvznP/+pxRYQkRaHPYmIak5xe30qFff6JKq+lOu3EDB7GyQJyIwagEZu7FEjIqrTe30SkeX45X+L3PZpXp9JGhFRDTBRI6Jaw2FPIiLjMFEjolqRkVOAXck3AABPhjJRIyKqCSZqRFQrfjmWBQDoFeAFXw9HmaMhIqqbqpWovfXWWwYXoiUiupd2E/anOnBvTyKimqpWorZgwQLs2bOnzLF58+ahfv36Jg2KiOq27NxC/H3hGgDgyVAucktEVFNGD33evn27zMr/RES/Hs+EEEC3Zp5o5uUsdzhERHUWn1EjIpP7d7Ynhz2JiIzBRI2ITOpKXiHiku4Mew7lshxEREZhokZEJrX+RBZKNQL3N/VAYH0OexIRGaPae32mp6dj3759ZX4GgP3796O83ai6du1aw/CIqK7hIrdERKZTrb0+VSoVJEnSOy6EMHhcq7S0tGbRKQj3+iSq3PVbRWgUtQUlGoFzU/oh2NtV7pCIiBSnOjlFtXrURo8ebVRgRGTZfjuRjRKNQAdfdyZpREQmUK1EbenSpbUVBxFZgJ+PXQLAYU8iIlPhZAIiMomcgmJsOXcFABM1IiJTqfZkgrvl5ubi4MGDuHr1KgDA29sbnTp1gpubm0mCI6K64/dT2SguFWjr44bWjfgdQERkCjVK1E6cOIEpU6Zg8+bN0Gg0Zc7Z2Nhg8ODBmDNnDtq0aWOSIIlI+X4+ymFPIiJTq3aiFh8fj8ceewx5eXlwdnbG/fffD1/fO6uPX7p0CQcPHsRvv/2GuLg4bNiwAb169TJ50ESkLLm3S/DnWQ57EhGZWrUStVu3bmHkyJG4desWZs6ciYiICLi4uJQpk5+fj08++QSzZs3C888/j9OnT8PR0dGkQRORsmw4nY3CEg1aebugrQ+HPYmITKVakwnWrFmD9PR0zJ07FzNmzNBL0gDAxcUFUVFRmDNnDlJTU7F27VqTBUtEyqRb5LaDb4VrKhIRUfVUK1HbuHEjvL298cYbb1Ra9o033kD9+vXxxx9/1DQ2IqoD8gtLsPF0NgAOexIRmVq1ErWjR4/igQcegJ2dXaVl7e3t0adPHxw5cqSmsRFRHbDpzGUUFGsQVN8ZHXy5awcRkSlVK1G7fPkyAgICqlw+MDAQly9frm5MRFSH/Lu3J4c9iYhMrVqJWm5ubrX2uXR1dUVeXl61gyKiuqGguBR/nPrfsGcHDnsSEZlatRK1e9dMq633EFHdsPnMZeQXlcLfywn3N/WQOxwiIotT7XXUTpw4gTVr1lS5LBFZrn+HPRtz2JOIqBZUO1GLjY1FbGxslcoKIfjlTWShCktK8dtJ7bCnr8zREBFZpmolalFRUbUVBxHVMVvPXUVuYQmaejiiq5+n3OEQEVkkJmpEVCPavT2Htm8MlYo950REtaFakwkAYPbs2YiMjERxcXG5ZYqKivDee+/hww8/NCo4IlKmohIN1p/kIrdERLWtWonaX3/9hRkzZqB+/foVLnprb2+P+vXr47333sOOHTuMDpKIlGX7+au4WVCMxu4O6BlQT+5wiIgsVrUSteXLl8PLywuvvvpqpWVfeeUV1KtXD0uXLq1xcESkTD8fvTPb88lQDnsSEdWmaiVqu3btwsMPPwwHB4dKyzo4OODhhx9GQkJCjYMjIuUpLtXg1xP/LstBRES1p1qJ2qVLl9C8efMqlw8MDERmZma1gyIi5YpPuobrt4rh7WqPB5rXlzscIiKLVq1ETaVSVTiJ4F7FxcVQqao9X4GIFCz22L/DnjYc9iQiqlXVyqJ8fX2rtdvAiRMn0KRJk2oHRUTKteP8VQDAo20ayRwJEZHlq1ai9sADD2D79u1ITk6utGxycjK2b9+OPn361DQ2IlKYq3mFOHslHwDQM8BL5miIiCxftRK1V155BcXFxXjqqadw9erVcstdu3YNTz/9NEpKSjBp0iSjgyQiZdiTehMAENLIFfWc7eUNhojIClRrZ4JOnTrhjTfewIIFC9CmTRtMnDgR/fr1Q9OmTQEAGRkZ2LZtG7777jtcuXIFb731Fjp16lQrgROR+e1Kvg4A6OnPtdOIiMyh2puyz58/H46Ojvj4448xe/ZszJ49u8x5IQRsbGwwdepUfPDBByYLlIjktyv5BgAOexIRmUu1EzVJkjBnzhy8+OKLWLp0KXbt2oWsrCwAgI+PD3r16oUxY8YgKCjI5MESkXyKSzXYl8pEjYjInKqdqGkFBQWxx4zIihy9pEZBsQb1nO3Q0ttV7nCIiKyCYhc5279/PwYPHgxPT0+4uLige/fuWLNmTY2vd+PGDTRp0gSSJGHgwIEmjJTIOmifT+vh78Vto4iIzKTGPWq1aceOHQgPD4ejoyOGDx8ONzc3xMbGYtiwYUhLS0NERES1r/nqq68iJyenFqIlsg7/Pp/GiQREROaiuB61kpISvPTSS1CpVPj777/x3XffYf78+Th69ChatmyJyMhIpKSkVOuasbGx+PHHHzFv3rxaiprI8ulmfPL5NCIis1FcorZ9+3YkJSVhxIgR6Nixo+64h4cHIiMjUVRUhJiYmCpf78qVK5g0aRJGjhyJRx55pBYiJrJ8aTcKkHbzNmxUErr4ecodDhGR1VBcohYXFwcAGDBggN658PBwAEB8fHyVrzdx4kTY2Njg888/N0l8RNZod8qdYc8Ovu5wcVDkExNERBZJcd+4iYmJAIDg4GC9cz4+PnB1ddWVqczKlSvxyy+/YN26dfDy8qrWM2qFhYUoLCzU/axWq6v8XiJL8+9Ctxz2JCIyJ8X1qGmTKQ8PD4Pn3d3dq5RwXbp0CZMnT8azzz6LJ554otpxzJ07Fx4eHrqXn59fta9BZCk4kYCISB6KS9RMZdy4cbCzs8MXX3xRo/dPnToVOTk5uldaWpqJIySqG24VleBwxp1fjjiRgIjIvBQ39KntSSuv10ytVsPLq+J/LGJiYrBp0yasXbsWDRo0qFEcDg4OcHBwqNF7iSzJgbQclGgEfN0d0czLSe5wiIisiuJ61LTPphl6Di0rKwt5eXkGn1+72+HDhwEATz/9NCRJ0r0CAwMBAJs3b4YkSWVmlRKRYXcvyyFJXOiWiMicFNejFhYWhrlz52LLli0YPnx4mXObN2/WlalIjx49kJeXp3c8Ly8Pq1evRtOmTREeHo5mzZqZLnAiC8WN2ImI5CMJIYTcQdytpKQErVq1QkZGBvbs2aPr9crJyUHXrl2RnJyMs2fPIiAgAACQmZmJnJwcNG7cuNwJCFrJyckIDAxEeHg4/vzzz2rFpVar4eHhgZycHLi7u9ekaUR1jhAC3jM249qtYuyZ3BvdOOuTiMho1ckpFDf0aWtri8WLF0Oj0aBPnz4YP348IiIi0KFDB5w7dw5z5szRJWnAnYf+Q0JC8Ouvv8oXNJGFSryaj2u3iuFgq8J9TSr+RYiIiExPcUOfANCvXz/s3LkTUVFRWL16NYqLixEaGop58+Zh2LBhcodHZDV2Xbwz7NnFzxP2tor7vY6IyOIpbuhTqTj0SdZo/NqjWLQnFf/tF4R5j7aROxwiIotQp4c+iUg5uNAtEZG8mKgRkUE3C4pxMisXANCDkwiIiGTBRI2IDNrzv43YWzRwQUM3Lv5MRCQHJmpEZNDdC90SEZE8mKgRkUFc6JaISH5M1IhIT0mpBntTOZGAiEhuTNSISM+JrFzkFZbC3dEWbRq5yR0OEZHVYqJGRHq0w57dm3nBRsWN2ImI5MJEjYj0cCIBEZEyMFEjIj1c6JaISBmYqBFRGZnq27h4/RYkCejm7yl3OEREVo2JGhGVsft/vWmhPu5wd7STORoiIuvGRI2IyuDzaUREysFEjYjK4EK3RETKwUSNiHRuF5fiYHoOAE4kICJSAiZqRKRzKD0HRaUaNHS1R/P6znKHQ0Rk9ZioEZHO3ctySBIXuiUikhsTNSLS2ZXCiQRERErCRI2IAABCCC50S0SkMEzUiAgAcPH6LWTnFsLORsL9TT3kDoeIiMBEjYj+R9ubdn9TTzja2cgcDRERAUzUiOh/uNAtEZHyMFEjIgBc6JaISImYqBER1LeLcTxTDQDo4c+JBERESsFEjYiwL/UmNAIIqOcEXw9HucMhIqL/YaJGRP8Oe7I3jYhIUZioEREnEhARKRQTNSIrp9EI7E7hQrdERErERI3Iyp3KzoX6dglc7G0Q2thN7nCIiOguTNSIrJz2+bRuzbxga8OvBCIiJeG3MpGV4/NpRETKxUSNyMpxoVsiIuViokZkxa7kFSLxaj4AoLs/EzUiIqVhokZkxXb/rzetTSNXeDnbyxwNERHdi4kakRX7d9iTy3IQESkREzUiK7YrhRMJiIiUjIkakZUqKtFgf+pNAOxRIyJSKiZqRFbqyKUc3C7RoJ6zHVp6u8gdDhERGcBEjchK3f18miRJMkdDRESGMFEjslJc6JaISPmYqBFZISEEEi5yoVsiIqVTbKK2f/9+DB48GJ6ennBxcUH37t2xZs2aKr1XCIFNmzZh0qRJaN++PTw8PODs7IwOHTpgzpw5uH37di1HT6RsaTcLcEl9GzYqCV38POUOh4iIymErdwCG7NixA+Hh4XB0dMTw4cPh5uaG2NhYDBs2DGlpaYiIiKjw/YWFhRg8eDAcHBzQt29fhIeH4/bt29i8eTPee+89rFu3DnFxcXB2djZTi4iURft82n1N3OFsr8ivASIiggITtZKSErz00ktQqVT4+++/0bFjRwDAjBkz0LVrV0RGRuKpp56Cv79/udewsbHBBx98gJdffhleXv8O6xQXF2Po0KH4/fff8fXXX+Odd96p7eYQKRIXuiUiqhsUN/S5fft2JCUlYcSIEbokDQA8PDwQGRmJoqIixMTEVHgNOzs7vPfee2WSNO3xqVOnAgDi4+NNHjtRXaGbSMD9PYmIFE1xiVpcXBwAYMCAAXrnwsPDARiXZNnZ2QEAbG0V15lIZBb5hSU4ckkNgD1qRERKp7hELTExEQAQHBysd87Hxweurq66MjXx/fffAzCcCBJZg/1pN1GqEWjq4Qg/Lye5wyEiogoorlspJycHwJ2hTkPc3d11Zapr06ZN+PbbbxESEoIXX3yxwrKFhYUoLCzU/axWq2tUJ5HS8Pk0IqK6Q3E9arVl//79GDZsGDw8PLB27Vo4ODhUWH7u3Lnw8PDQvfz8/MwUKVHt4kK3RER1h+ISNW1PWnm9Zmq1utzetvIcOHAAAwYMgEqlwubNm9G2bdtK3zN16lTk5OToXmlpadWqk0iJNBqB3SnsUSMiqisUl6hpn00z9BxaVlYW8vLyDD6/Vp4DBw6gf//+0Gg02Lx5M7p06VKl9zk4OMDd3b3Mi6iuO3clD9dvFcPJToWOTfhnmohI6RSXqIWFhQEAtmzZondu8+bNZcpURpuklZaW4s8//0S3bt1MFyhRHaR9Pq2LnyfsbBT315+IiO6huG/qhx56CM2bN8ePP/6II0eO6I7n5ORgzpw5sLe3x6hRo3THMzMzcebMGb2h0oMHD6J///4oKSnBpk2b0KNHD3M1gUixOJGAiKhuUdysT1tbWyxevBjh4eHo06dPmS2kUlJS8MknnyAgIEBXfurUqYiJicHSpUsxZswYAMD169fRv39/3Lx5EwMHDsTWrVuxdevWMvV4enrijTfeMF/DiBRgVwonEhAR1SWKS9QAoF+/fti5cyeioqKwevVqFBcXIzQ0FPPmzcOwYcMqfb9arcaNG3d6Dv7880/8+eefemX8/f2ZqJFVuX6rCKez8wAAPbgjARFRnSAJIYTcQdQF2tmmOTk5nFhAddLG09l4ZPE+tPR2wdkpD8odDhGR1apOTqG4Z9SIqHbw+TQiorqHiRqRleBCt0REdQ8TNSIrUFKqwd7UmwDYo0ZEVJcwUSOyAscy1bhVVAoPR1uENHSVOxwiIqoiJmpEVkD7fFqPAC+oVJLM0RARUVUxUSOyApxIQERUNzFRI7ICuokEXD+NiKhOYaJGZOEycgqQcqMAKgno2oyJGhFRXcJEjcjC7f7fsGf7xu5wc1TkZiRERFQOJmpEFo7PpxER1V1M1IgsHBe6JSKqu5ioEVmwguJSHMrIAcAeNSKiuoiJGpEFO5h2E8WlAo3cHBBQz0nucIiIqJqYqBFZsH+fT/OCJHGhWyKiuoaJGpEF+3f9NA57EhHVRUzUiCyUEAK7Uv7tUSMiorqHiRqRhUq6dgtX8opgb6NCp6YecodDREQ1wESNyEJphz3vb+oBRzsbmaMhIqKaYKJGZKHunkhARER1ExM1Igv170K3nEhARFRXMVEjskA5BcU4kZULAOjBHjUiojqLiRqRBdqbegNCAIH1nNHY3VHucIiIqIaYqBFZID6fRkRkGZioEVkgPp9GRGQZmKgRWZhSjcCelJsA2KNGRFTXMVEjsjAns3KRW1gCVwcbtPNxkzscIiIyAhM1IgujHfbs1swLtjb8K05EVJfxW5zIwnAiARGR5WCiRmRhOJGAiMhyMFEjsiDZuYVIunYLANDdnz1qRER1HRM1Iguy+3+9aW193ODpZCdzNEREZCwmakQWhM+nERFZFiZqRBZE93yaP59PIyKyBEzUiCxEYUkpDqTnAAB6BrJHjYjIEjBRI7IQhzPUKCzRoL6zHYIbuMgdDhERmQATNSILcfeyHJIkyRwNERGZAhM1IgvBiQRERJaHiRqRBRBCIOEiF7olIrI0TNSILEDKjQJk5RbCViWhs5+H3OEQEZGJMFEjsgDa59Pua+IBZ3tbmaMhIiJTYaJGZAH4fBoRkWVSbKK2f/9+DB48GJ6ennBxcUH37t2xZs2aal2jsLAQ77//PoKDg+Ho6AhfX1+MHz8ely9frqWoieTBjdiJiCyTIsdIduzYgfDwcDg6OmL48OFwc3NDbGwshg0bhrS0NERERFR6DY1GgyeeeAKbN29G9+7dMXToUCQmJmLx4sXYtm0b9uzZA29vbzO0hqh25RWW4OglNQD2qBERWRpJCCHkDuJuJSUlaN26NdLT07Fnzx507NgRAJCTk4OuXbsiOTkZ586dg7+/f4XXWbp0KV544QU8++yz+OGHH3TrSi1cuBCTJk3C+PHj8e2331Y5LrVaDQ8PD+Tk5MDd3b3G7SMyte2JV/HQwt3w83RE6vT+codDRESVqE5Oobihz+3btyMpKQkjRozQJWkA4OHhgcjISBQVFSEmJqbS6yxatAgAMHfu3DKLf06YMAHNmzfHDz/8gIKCApPHT2RuHPYkIrJcikvU4uLiAAADBgzQOxceHg4AiI+Pr/Aat2/fxt69e9GqVSu9njdJktC/f3/k5+fjwIEDpgmaSEacSEBEZLkU94xaYmIiACA4OFjvnI+PD1xdXXVlypOUlASNRmPwGndfOzExEQ888ICREZvG8Uw1LucWyh0G1UG7U7SJGnvUiIgsjeIStZycHAB3hjoNcXd315Ux5hp3lzOksLAQhYX/Jk5qtbrCOo31/pZz+PlYZq3WQZbLyU6FDr58dpKIyNIoLlFTirlz5yI6Otps9TXzckJoYzez1UeWQ4KEUZ2bws5GcU8yEBGRkRSXqGl7wcrr7VKr1fDyqvhZnKpc4+5yhkydOhVvvfVWmff4+flVWK8x5j/ettauTURERHWT4n4Fv/v5sXtlZWUhLy+v3GfPtJo3bw6VSlXus2wVPQen5eDgAHd39zIvIiIiInNSXKIWFhYGANiyZYveuc2bN5cpUx4nJyd07doVZ8+eRUpKSplzQghs3boVLi4u6Ny5s4miJiIiIjI9xSVqDz30EJo3b44ff/wRR44c0R3PycnBnDlzYG9vj1GjRumOZ2Zm4syZM3rDnOPHjwdwZwjz7jV9v/32W1y4cAHPPfccnJycarcxREREREZQ3M4EQPlbSKWkpOCTTz4ps4XUmDFjEBMTg6VLl2LMmDG64xqNBoMHD9ZtIRUWFobz58/jl19+QUBAAPbu3VutLaS4MwERERGZQp3emQAA+vXrh507d6JXr15YvXo1vvnmGzRq1AirVq2q0j6fAKBSqbB+/XrMnDkTV65cwWeffYaEhAS8+OKL2L17N/f5JCIiIsVTZI+aErFHjYiIiEyhzveoERERERETNSIiIiLFYqJGREREpFBM1IiIiIgUiokaERERkUIpbq9PpdJOjtXuE0pERERUE9pcoioLbzBRq6Lc3FwAqNWN2YmIiMh65ObmwsPDo8IyXEetijQaDS5dugQ3NzdIkmTy66vVavj5+SEtLc1s67SZu0620TLqZBsto0620TLqZBvrZp1CCOTm5sLX1xcqVcVPobFHrYpUKhWaNm1a6/W4u7ubfUFdc9fJNlpGnWyjZdTJNlpGnWxj3auzsp40LU4mICIiIlIoJmpERERECsVETSEcHBwQFRUFBwcHi62TbbSMOtlGy6iTbbSMOtlGy6mzPJxMQERERKRQ7FEjIiIiUigmakREREQKxUSNiIiISKGYqBEREREpFBM1IiIisirHjh3D5cuX5Q6jSpioERERkVW57777sHDhQt3PDz74IJYvXy5jROVjombl8vLycPnyZWg0GrlDqTXW0EaqfdevX0dqaqrcYRCRCdjY2KC0tFT3c1xcHJKTk+ULqALc61PBlixZgoSEBHz//fc1vkZqaio8PT319ir7448/MG3aNBw/fhwA4OLigmHDhuGjjz6Cl5eXUXEbkp+fj0WLFiEhIQH5+fkICAjAiBEj0Lt3b6OvrZQ2lmfXrl04f/48Ro0aZfJrp6en45NPPilzX5977jk899xzJq9L68iRI2XqGzRoENzc3GqtPjnaaEhERARWrFiBkpISk19bCIH169eXaePTTz+NwMBAk9elpdFocPr0aeTn58Pf3x+NGjWqtboA87UxPT0d8fHxSExMRE5ODoA7eyoGBwejT58+8PPzM2l997p69Sr27t2ra2OXLl0gSZLJrr9z585y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xlTps2zatCmGDRtmdJ1aS5cuNcl1agMTNTMKDQ1Famoq3n333SqVP3PmjEkSteTkZPz9998AgMLCQgBAZmYm/P399cpmZWUZPSPy7tk/2r9weXl5cHR01Cubn58PZ2dno+oDzNvGli1borCwEJs2bapS+bFjx5pkfZ6776s2eblx44bBhPTGjRtwdXU1uk4tDw8PAHf+MTfExsam3HPVYc423n///di0aRMKCwvh4OBQrdhMpUGDBgDu/EPs4uKid764uBj29vYmq8/W9s5Xfr169Qyer1evnsn/gTdHG1u0aIENGzZg1qxZujaWp7i4GBs2bECLFi2MqvNuTk5OAGCwfdrjxiwP1LZtW8TGxiIqKqrSP/NqtRqxsbFo27ZtjeszpLbbCNyZGWyO91SkpKQEZ8+exc2bN8ss33G3Pn36mLTOyjBRM6P7778fhw4dQlpaWq1PEb9bTEyM7rcOIQQkSUJcXBxGjx6tV/b06dPl9mBU1Weffab77USbNJ04cQJ9+/bVK5uSkmKSZQHM2cZOnTph1apVuHnzJjw9PWt8neqaOXMmZs6cWebY4cOHMWjQIL2yFy9erFYPgyHr1q3TrSt06dIlAEBSUhI6duyoVzY9PV33D7IxzNnG++67D7///juOHj2Krl27Vlpe3HlUpMb1aS1btgxxcXEAgJs3bwIAzp07h27duumVTUtLQ8OGDY2q78iRI7pfFLTrwKWnpyMoKEivbEZGRrlJXHWYu40vvfQSXn/9dQwYMACzZs1Cz5499RJrIQQSEhIwffp0nDp1Cp9//rlRdWrbB9xpG3DnF8aQkBC9sunp6ahfv36N65o8eTJGjhyJrl274r333kP//v317tnly5exZcsWzJ49G6mpqZgzZ06N69MyZxuBO38nV69ejSlTpqBx48YVls3IyMDq1avL7eWvLiEEZsyYgS+//BK5ubkVli0vgastTNTM6IEHHsDmzZuRmJhYpUTNFOvhREVFGTxuKMFITEzE/v378corr9S4vmbNmkGSJN0/aPb29mjWrBn++ecfvUStoKAAf//9NwYPHlzj+gDzt7FTp0746aefcPDgQTz00EOVlq9fvz6aNWtW4/qAO7/BGerROXfunF4Sc+PGDfzzzz945plnjKrzyJEjeusMrVu3zmCitnv3boSGhhpVn7nbOGrUKAQGBlY5SZg/fz6i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sMz+/fuFp6encHd3F4MHDzZ66PPTTz8Vjo6Ouhm7bm5uokmTJqJJkya64UhJkoSjo6P47LPPjKpLiOp9jsXFxeLnn38WgwcPNrre6hgzZozR99Wcs+n79eunNxs3KSlJBAYG6s2uV6lUYtq0aTWuS0uO2fT3Sk9PFzt27BDr1q0T69atEzt27BDp6ekmu355qxJU9JLjUQQmamb2wQcfCDs7O91fbnd3d+Hn5yf8/Px0SZL2WZzZs2cbXd9nn30mJEkSf//9d4XlNBqNGD16tEn+IJq7jTVJ1IxRWFgowsPDdfcqJCREPP7442LkyJFi5MiR4vHHHxchISG6L9CBAwcaPZFh2rRpQqVSiaSkpArLXbt2TXTs2NHoz1GONpr7c+zevbsIDAwUarW60rI3b94UAQEBlSbLlZk4caJwcnISN2/erLDc/v37hZeXl+7vSk3JkYya+3OsCWMTtb179wobGxthb28vwsPDxaOPPiocHR2FSqUSEydO1CtvbKJm6J527dpVSJIkRo0aJRISEsTZs2dFTEyM8PHxESqVSvz11181rk9bZ7t27USDBg103wPNmjUTUVFRIjk52ahrV6SwsFB8+OGHokWLFro///e+goKCxLx588Tt27eNqis5OblGL3NjoiaDxMREMXXqVNGzZ0/h7e0t7O3thb29vfD29hY9e/YUU6dOLXd9rOrKyMgQU6ZMEb/++mulZTUajYiKijLJrBZztnHZsmXiyJEjJrlWVWk0GvH999+LHj166GaY3v2ysbERPXr0EEuXLjXJb6FHjhwR3bt3F1999VWlZa9fvy7CwsJEQECAUXWau41jxowR69evN/o6VeXi4iLefvvtKpePiIgQLi4uRtW5ceNGIUmSmDNnTqVlDxw4oEvWakqOZDQgIEB8/vnnRl2jurTrv1X11bt3b6Puq7ln09+bqO3du1dIkiRGjx6tV/b06dPC3t5ePPnkkzWu7+46zTWbXggh8vLyRLdu3XQ9vwMHDhSvvfaaeO+998R7770nXnvtNTFw4EDd2o7du3cXeXl5JqtfqZioERnp9u3b4uTJk2LXrl1i165d4uTJk6KgoEDusEzKEtvo6elZrRnK48ePF56enkbXe/v2bVFcXFylstevXzfqN3g5klE53L0Ic1VexvY4m3s2/b2J2ldffSVUKlW5yyANGTLE5LOwhajd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zs42GFd2djYkSYKbm1uZWAyVF0IgOzvbYIJSHe3atcPPP/+M69evY/fu3ZgxYwaysrIwbNgwXVKmrSMiIqLCexIVFWVULLVN247777+/wnbs2LFD5kiJ6h4makRkcpGRkfD19cX//d//ITk5GcCdoUx3d3ccOHBA1xNTVZIkISQkBK+88gq2bt0KAAaX8/jnn3/0jqWkpCAtLQ1t27aFvb09AOC+++4DAIOr+O/duxe3b982OORXE3Z2dujevTuio6PxxRdfQAiBP/74AwDQpUsXSJKE3bt3G12Ptnfx7p49c3Fzc0NISAhOnz5dZgiYiIzHRI2ITM7JyQnvvvsuiouLMWvWLAB3hssmTZqElJQUvP322waTtRMnTuDy5csA7iyFoU3y7qbtBXN0dNQ7t3z5chw7dkz3sxACkZGRKC0t1S1hAQAjRoyAra0tPv30U1y6dEl3vKioCO+++y4AlClfXQcPHtQNr1YUu4+PD5555hns2rULH3/8sd76asCdxLEqOwpoJymkpaXVOG5jTJ48Gbdu3cJLL71kcIjz4sWLBj9PIqoYn1Ejoloxfvx4zJs3D8uXL0dkZKRutuehQ4fwxRdfYMOGDejTpw8aNmyIjIwMHD9+HEePHsXu3bvRsGFDHDlyBE8++SS6du2KNm3awMfHBxkZGVi3bh1UKhXefPNNvTrDw8PRo0cPDB8+HN7e3ti2bRsOHDiA7t2747XXXtOVCwoKwrx58xAREYH27dvjmWeegYuLC37//XecPXsWTzzxhG5brJpYsWIFvv32W/Tp0wdBQUFwd3fHqVOnsHHjRtSrVw9jx47Vlf2///s/nD17Fv/973+xYsUK9OjRA56enkhLS8OBAweQmJiIzMxMODs7V1indqHbyMhInDx5Eh4eHvD09NStS1fbJkyYgD179iAmJgYJCQl4+OGH4evri+zsbJw5cwZ79+7Fjz/+WGYRXiKqAnOtA0JElqWiddS0vvzySwFAjBw5UnespKREfPvtt6JXr17C3d1dODg4iGbNmomBAweKb775RuTl5QkhhEhLSxNTpkwR3bt3Fw0bNhT29vaiWbNm4sknnxS7d+8uU8/da4gtWrRItG3bVjg4OIjGjRuL119/XajVaoPxrV+/XoSFhQk3Nzfh4OAgQkNDxfz580VxcbHBto4ePdrgdQCIsLAw3c979uwREyZMEO3atROenp7CyclJBAcHi1dffVWkpKTovf/WrVvio48+Evfff79wcXERTk5OIjAwUAwZMkQsX75cL57yLFu2TISGhgoHBwcBQPj7++vOVbSO2tKlS/WuVdG6bKNHjxYAxMWLF/XOrV69Wjz88MPCy8tL2NnZiSZNmoi+ffuK+fPniytXrlSpHUT0L0kIA33tRER1yMyZMxEdHY0dO3YYXHKDiKiu4jNqRERERArFRI2IiIhIoZioERERESkUn1EjIiIiUij2qBEREREpFBM1IiIiIoViokZERESkUEzUiIiIiBSKiRoRERGRQjFRIyIiIlIoJmpERERECsVEjYiIiEihmKgRERERKdT/A/xQjQvGghK3AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "yesterday = datetime.date.today() - datetime.timedelta(days=1)\n", + "duration = '[' + str(yesterday.day) + 'd]'\n", + "\n", + "response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query\",\n", + " params={\n", + " \"query\": f\"DbscanServing_Detect_histogram_duration_bucket{duration}\",\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + ")\n", + "\n", + "parsed = response.json()\n", + "# print(\"root:\", parsed.keys())\n", + "\n", + "# print(\"data:\", parsed[\"data\"].keys())\n", + "\n", + "# print(\"resulttype:\", parsed[\"data\"][\"resultType\"])\n", + "\n", + "# print(\"results:\", len(parsed[\"data\"][\"result\"]))\n", + "\n", + "# print(\"results keys:\", parsed[\"data\"][\"result\"][0].keys())\n", + "\n", + "# print(\"results metric:\", parsed[\"data\"][\"result\"][0][\"metric\"])\n", + "\n", + "cdf = {}\n", + "\n", + "for load in loads:\n", + " cdf[load] = {}\n", + "\n", + "for metric in parsed[\"data\"][\"result\"]:\n", + " # we may have more than one endpoint with this information\n", + " for load, _time in zip(loads, times_services):\n", + " if float(metric[\"metric\"][\"le\"]) not in cdf[load]:\n", + " cdf[load][float(metric[\"metric\"][\"le\"])] = []\n", + " print(metric[\"metric\"])\n", + " for value in metric[\"values\"]:\n", + " if _time[0] < value[0] and value[0] < _time[1]:\n", + " print(load, metric[\"metric\"][\"le\"], value)\n", + " cdf[load][float(metric[\"metric\"][\"le\"])].append(float(value[1]))\n", + " break # stops the loop over values when the first one is found\n", + " # print(\"\\tmetric:\", metric[\"metric\"][\"le\"], type(metric[\"metric\"][\"le\"]))\n", + " # print(\"\\tvalue:\", metric[\"values\"])\n", + "\n", + "for load in loads:\n", + " probabilities = np.zeros((len(cdf[load].keys()),))\n", + " i = 0\n", + " for key in sorted(cdf[load].keys()):\n", + " if cdf[load][key] == float('Inf'):\n", + " continue\n", + " print(i, key)\n", + " probabilities[i] = np.mean(cdf[load][key])\n", + " i += 1\n", + " probabilities[i-1] = np.mean(cdf[load][float('Inf')])\n", + " print(probabilities)\n", + " probabilities = probabilities / probabilities.max()\n", + "\n", + " plt.figure()\n", + " plt.title(load)\n", + "\n", + " plt.plot(range(len(cdf[load].keys())), probabilities)\n", + "\n", + " plt.xticks(range(len(cdf[load].keys())), [x for x in sorted(cdf[load].keys()) if x != float(\"Inf\")] + [\"Inf\"], rotation=90)\n", + "\n", + " plt.xlabel(\"Response time\")\n", + " plt.ylabel(\"CDF\")\n", + "\n", + " plt.tight_layout()\n", + " plt.show()\n", + " plt.close()\n", + " # for value in parsed[\"data\"][\"result\"][0][\"values\"]:\n", + " # print(\"\\t\\t\", datetime.datetime.fromtimestamp(value[0]), value[1])\n", + "\n", + "\n", + "# print(\"results values:\", parsed[\"data\"][\"result\"])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "root: dict_keys(['status', 'data'])\n" + ] + }, + { + "ename": "KeyError", + "evalue": "inf", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [25], line 64\u001b[0m\n\u001b[1;32m 62\u001b[0m probabilities[i] \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mmean(cdf[load][key])\n\u001b[1;32m 63\u001b[0m i \u001b[39m+\u001b[39m\u001b[39m=\u001b[39m \u001b[39m1\u001b[39m\n\u001b[0;32m---> 64\u001b[0m probabilities[i\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m] \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mmean(cdf[load][\u001b[39mfloat\u001b[39;49m(\u001b[39m'\u001b[39;49m\u001b[39mInf\u001b[39;49m\u001b[39m'\u001b[39;49m)])\n\u001b[1;32m 65\u001b[0m \u001b[39m# print(probabilities)\u001b[39;00m\n\u001b[1;32m 66\u001b[0m probabilities \u001b[39m=\u001b[39m probabilities \u001b[39m/\u001b[39m probabilities\u001b[39m.\u001b[39mmax()\n", + "\u001b[0;31mKeyError\u001b[0m: inf" + ] + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "yesterday = datetime.date.today() - datetime.timedelta(days=1)\n", + "duration = '[' + str(yesterday.day) + 'd]'\n", + "\n", + "labels = collections.OrderedDict({\n", + " \"OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket\": \"Cache\",\n", + " \"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket\": \"Inference\",\n", + " \"OPTICAL_ATTACK_DETECTOR_WORKER_RESPONSE_TIME_bucket\": \"Worker\",\n", + "})\n", + "\n", + "\n", + "plt.figure()\n", + "for (key, label) in labels.items():\n", + "\n", + " response = requests.get(\n", + " f\"{prometheus_endpoint}/api/v1/query\",\n", + " params={\n", + " \"query\": f\"{key}{duration}\",\n", + " # \"time\": time.mktime(yesterday.timetuple())\n", + " }\n", + " )\n", + "\n", + " parsed = response.json()\n", + " print(\"root:\", parsed.keys())\n", + "\n", + " # print(\"data:\", parsed[\"data\"].keys())\n", + "\n", + " # print(\"resulttype:\", parsed[\"data\"][\"resultType\"])\n", + "\n", + " # print(\"results:\", len(parsed[\"data\"][\"result\"]))\n", + "\n", + " # print(\"results keys:\", parsed[\"data\"][\"result\"][0].keys())\n", + "\n", + " # print(\"results metric:\", parsed[\"data\"][\"result\"][0][\"metric\"])\n", + "\n", + " cdf = {}\n", + "\n", + " for load in loads:\n", + " cdf[load] = {}\n", + "\n", + " for metric in parsed[\"data\"][\"result\"]:\n", + " # we may have more than one endpoint with this information\n", + " for load, _time in zip(loads, times_services):\n", + " if float(metric[\"metric\"][\"le\"]) not in cdf[load]:\n", + " cdf[load][float(metric[\"metric\"][\"le\"])] = []\n", + " # print(metric[\"metric\"])\n", + " for value in metric[\"values\"]:\n", + " if _time[0] < value[0] and value[0] < _time[1]:\n", + " # print(load, metric[\"metric\"][\"le\"], value)\n", + " cdf[load][float(metric[\"metric\"][\"le\"])].append(float(value[1]))\n", + " break # stops the loop over values when the first one is found\n", + " # print(\"\\tmetric:\", metric[\"metric\"][\"le\"], type(metric[\"metric\"][\"le\"]))\n", + " # print(\"\\tvalue:\", metric[\"values\"])\n", + "\n", + " for load in loads:\n", + " if load != 480: continue\n", + " probabilities = np.zeros((len(cdf[load].keys()),))\n", + " i = 0\n", + " for key in sorted(cdf[load].keys()):\n", + " if cdf[load][key] == float('Inf'):\n", + " continue\n", + " # print(i, key)\n", + " probabilities[i] = np.mean(cdf[load][key])\n", + " i += 1\n", + " probabilities[i-1] = np.mean(cdf[load][float('Inf')])\n", + " # print(probabilities)\n", + " probabilities = probabilities / probabilities.max()\n", + "\n", + " # plt.title(load)\n", + "\n", + " plt.plot(range(len(cdf[load].keys())), probabilities, label=label)\n", + "\n", + "plt.xticks(range(len(cdf[load].keys())), [x * 1_000 for x in sorted(cdf[load].keys()) if x != float(\"Inf\")] + [\"Inf\"], rotation=90)\n", + "plt.xlabel(\"Response time\")\n", + "plt.ylabel(\"CDF\")\n", + "plt.legend(loc=2)\n", + "plt.xlim([0.0001, 15])\n", + "plt.grid()\n", + "plt.tight_layout()\n", + "plt.show()\n", + "plt.close()\n", + " # for value in parsed[\"data\"][\"result\"][0][\"values\"]:\n", + " # print(\"\\t\\t\", datetime.datetime.fromtimestamp(value[0]), value[1])\n", + "\n", + "\n", + " # print(\"results values:\", parsed[\"data\"][\"result\"])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket\n", + "OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket\n", + "OPTICAL_ATTACK_DETECTOR_WORKER_RESPONSE_TIME_bucket\n" + ] + }, + { + "ename": "ValueError", + "evalue": "list.remove(x): x not in list", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn [26], line 34\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39m\\t\u001b[39;00m\u001b[39m\"\u001b[39m, le \u001b[39m*\u001b[39m \u001b[39m1_000\u001b[39m, vec)\n\u001b[1;32m 33\u001b[0m data[key][le\u001b[39m*\u001b[39m\u001b[39m1_000\u001b[39m] \u001b[39m=\u001b[39m vec\n\u001b[0;32m---> 34\u001b[0m indices\u001b[39m.\u001b[39;49mremove(\u001b[39m67.5\u001b[39;49m)\n\u001b[1;32m 35\u001b[0m indices\u001b[39m.\u001b[39msort()\n", + "\u001b[0;31mValueError\u001b[0m: list.remove(x): x not in list" + ] + } + ], + "source": [ + "data = {}\n", + "\n", + "indices = []\n", + "\n", + "for key, label in labels.items():\n", + " response = requests.get(f\"http://localhost:9090/api/v1/query_range?query={key}&start=1675152891.996&end=1675170891.996&step=68\")\n", + " parsed = response.json()\n", + " print(key)\n", + " data[key] = {}\n", + "\n", + " processed_results = {}\n", + " max_value = 0\n", + "\n", + " for i, result in enumerate(parsed[\"data\"][\"result\"]):\n", + " if float(result[\"metric\"][\"le\"]) >= 0.008 and float(result[\"metric\"][\"le\"]) < 0.025:\n", + " continue\n", + " # print(i, \"\\t\", result[\"metric\"], len(result[\"values\"]), np.sum([float(x[1]) for x in result[\"values\"]]))\n", + " if float(result[\"metric\"][\"le\"]) not in processed_results:\n", + " processed_results[float(result[\"metric\"][\"le\"])] = np.sum([float(x[1]) for x in result[\"values\"]])\n", + " else:\n", + " processed_results[float(result[\"metric\"][\"le\"])] += np.sum([float(x[1]) for x in result[\"values\"]])\n", + " max_value = max(max_value, processed_results[float(result[\"metric\"][\"le\"])])\n", + " if float(result[\"metric\"][\"le\"]) * 1_000 not in indices:\n", + " indices.append(float(result[\"metric\"][\"le\"]) * 1_000)\n", + "\n", + " for le in sorted([float(x) for x in processed_results.keys()]):\n", + " vec = processed_results[le]\n", + " vec = vec / max_value\n", + " if le == 0.0675:\n", + " le = 0.0625\n", + " processed_results[le] = vec\n", + " print(\"\\t\", le * 1_000, vec)\n", + " data[key][le*1_000] = vec\n", + "indices.remove(67.5)\n", + "indices.sort()\n", + "# data[\"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket\"][62.5] = data[\"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket\"][67.5]\n", + "# del data[\"OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket\"][67.5]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.1, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 25.0, 50.0, 62.5, 75.0, 87.5, 100.0, 175.0, 250.0, 375.0, 500.0, 675.0, 750.0, 1000.0, 1750.0, 2500.0, 5000.0, 7500.0, 10000.0, inf] 26\n" + ] + } + ], + "source": [ + "print(indices, len(indices))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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27dvg7EL895779X/84LmXNh87777bs4444x87Wtfy49+9KNFrrc4xo4d2+D306dPT5LMmjUrnTp1SkVFRZKktrY2c+bMSZK0a9eufodfTU1N5s6dmyTp0KFD/TzV1dWZN29eCoVC2rdvX3993rx5qa6uTqtWrdKuXbv5rldUVKRt27b11+fOnZuampq0bt06bdq0qb8+Z86c1NbWznd99uzZKRaLadOmTYMTcusOAmnbtq2e9KQnPelJT3rSk570pCc96UlPetLTUu2pOQeWLndBXV041alTpwWO6dy5c5Jk2rRpTZ5vYXMuaL7a2tocccQRmTt3bq677roGf7hLQl1g+EWPPvpodt5553Tt2jXJZz+Idd/T22mnner/ElRVVeWJJ55Ikuy11171z3/88ccZOXJk2rdvn5133rn++vvvv5/XXnstK620Urbddtv662+++Wbefffd9OrVK5tvvnn99Zdeeinjxo3LwIEDs/7669dff/bZZzNlypQMGjQoa6yxRv314cOHZ/bs2dlss83Su3fv+ut1tQ8ePFhPetKTnvSkJz3pSU960pOe9KQnPelpqfb06KOPpqmWu1dfy8kll1ySJ598Mv/93/+dDTbYYGmXAwAAAMBSVCgWi8WlXcSX6fLLL89JJ52UjTfeeIHfjDv55JNz2WWXZf/9988tt9yy0PleeeWVbLjhhkmSqVOnpkuXLvONueOOO7LvvvumW7dumThxYpLPUtyNN944a6+9dkaMGNFgC+V7772XAQMGpKKiItXV1aW2Op/GXn1db731Mn78+HTr1m2Z32qqJz3pSU960pOe9KQnPelJT3rSk5709GX3NHHixPTs2TNVVVWprKzMwix3Qd0999yTPffcMyuvvHI++eSTRsfsu+++ueOOO3L66afnwgsvXOh806ZNqw/nXn755UZ3xl122WU5+eSTs9lmm9WfOHvJJZfkhz/8YdZYY40G2ySTz/7An3322STJkCFDkiRnnnlmvvWtbzWv2UWoq70pPygAAAAANF9z8pfl7ht1m2yySZJk0qRJGT16dKMnv44cOTJJsummmy5yvsrKyqyxxhp55513MnLkyEaDuoXN984779SfGtuY4cOHJ0mOOOKIRdYCAAAAwFfXcveNuj59+tR/MPCmm26a7/6TTz6ZDz74IO3atcuuu+7apDn32WefBc43Y8aM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i7vllluy3XbbZaWVVkqnTp2y0UYb5Ve/+lXmzZtX0nzPP/98DjjggPTo0SPt27fPgAEDcuKJJ2bChAmNjh8zZkx+97vfZd99902/fv3Srl27dO7cORtttFF++tOfZuLEiYvTHgAAAABfIYVisVgs9eGampr85S9/yTPPPJPKysrssssu2XbbbRuMmTdvXvbee+/MnDkzl19+edZff/3FLrolnHLKKbn00kvTunXrbL/99uncuXMeffTRTJ06Ndtss00efPDBdOjQocnz3XrrrTn44INTXV2dzTffPAMGDMjIkSMzatSo9OjRI08++eR8Owq32WabPPXUU2ndunU22WSTrL766pk8eXKeffbZTJs2Ld27d8+DDz6YjTfeuIW7/8y0adPSpUuXVFVVpbKycomsAQAAALA8a07+slhB3VfVnXfemX322SedO3fO8OHDs+mmmyb57NTa7bffPq+88kpOO+20/PrXv27SfOPGjcuaa65Zv7vwmGOOSfJZkHnEEUfkxhtvzOabb55nn302hUKh/rlvf/vb2WqrrXLYYYdl5ZVXrr8+ceLEHHjggRk2bFjWXHPNvPHGG6moqGjBfwOfEdQBAAAALFlfSlD3+OOPp23bttlyyy2bNP65557L7Nmz59txtzR8/etfz4gRI3L++efnZz/7WYN7Tz75ZAYPHpx27drl448/TpcuXRY5349//ONceOGF2XHHHfPQQw81uDdjxoz06dMnVVVV+fvf/56dd965STWOHTu2/hXiJ554Ittss00Tu2s6QR0AAADAktWc/KXkb9Rtt9122W+//Zo8/tvf/na23377UpdrMR9++GFGjBiRJPnOd74z3/1tttkmffv2zZw5c3L//fc3ac477rhjgfN17tw5e+65Z5Lk9ttvb3Kdffr0Sbdu3ZIkH3zwQZOfAwAAAOCrqeSgLkmauxmvHN6yfeGFF5IkXbt2zYABAxods9lmmzUYuzDTp0/PO++80+C5xZmvzieffJIpU6YkSVZdddUmPwcAAADAV1PrL2uh6dOnp02bNl/Wcgs0evToJMlqq622wDF1r5zWjV2Y9957r/6fFzRnc+ar8+tf/zo1NTVZddVV841vfKPJzy3M2LFjG/x++vTpSZJZs2alU6dO9d/Bq62tzZw5c5Ik7dq1S6tWn+W5NTU1mTt3bpI0OGijuro68+bNS6FQSPv27euvz5s3L9XV1WnVqlXatWs33/WKioq0bdu2/vrcuXNTU1OT1q1bN/hZmTNnTmpra+e7Pnv27BSLxbRp0yatW//nR3nWrFlJkrZt2+pJT3rSk570pCc96UlPetKTnvSkJz0t1Z7qrjfFlxLUPffcc5k8eXL69ev3ZSy3UHXhVKdOnRY4pnPnzkk+e4e4qfMtbM7mzJckDz/8cP1BFhdddFGDH57FURcYftGjjz6anXfeOV27dk3y2Q/igw8+mCTZaaed6v8SVFVV5YknnkiS7LXXXvXPf/zxxxk5cmTat2/f4Bt877//fl577bWstNJKDb5N+Oabb+bdd99Nr169svnmm9dff+mllzJu3LgMHDiwwenAzz77bKZMmZJBgwY1ODl3+PDhmT17djbbbLP07t27/npd7YMHD9aTnvSkJz3pSU960pOe9KQnPelJT3paqj09+uijaaomB3V//OMf88c//rHBtcmTJy/0u3PFYjFTp07N66+/nkKhUBbfqCt3r7zySg444IDU1NTkxBNPzMEHH7y0SwIAAADgS9DkU19//vOf5+c//3nJC6255pp59NFHGySNS8Pll1+ek046KRtvvPECvxl38skn57LLLsv++++fW265ZaHzvfLKK9lwww2TJFOnTm30lNg77rgj++67b7p165aJEycucK5///vfGTJkSCZMmJAjjzwy1157bQqFQjO6W7jGXn1db731Mn78+HTr1m2Z32qqJz3pSU960pOe9KQnPelJT3rSk5709GX3NHHixPTs2bNJp742OagbPnx4hg0bVv/7n//85+ncuXNOO+20BT7TqlWrVFZWZv311892221XX+TSdM8992TPPffMyiuvnE8++aTRMfvuu2/uuOOOnH766bnwwgsXOl/dEbtJ8vLLL2eDDTaYb8xll12Wk08+OZtttln9ibNf9NZbb2W77bbLRx99lMMPPzzXXXdd/Q/kktKc44EBAAAAaL7m5C9NfvV1yJAhGTJkSP3v64K6c845p/RKl4JNNtkkSTJp0qSMHj260ZNfR44cmSTZdNNNFzlfZWVl1lhjjbzzzjsZOXJko0HdouZ7++23M3To0Hz00Uc59NBDv5SQDgAAAIDyUnIaNHr06Dz33HMtWcuXok+fPvUfDLzpppvmu//kk0/mgw8+SLt27bLrrrs2ac599tlngfPNmDEj99xzT5LPdup90bvvvpuhQ4dm3LhxOfTQQ/PHP/5RSAcAAACwHCo5EerXr1/69OnTkrV8aX76058mSS644IL861//qr8+adKkHH/88UmSH/zgBw2+N3fHHXdknXXWyQ477DDffKeccko6duyYhx9+OFdffXX99Zqamhx//PGZOnVqNt988+y0004Nnhs9enSGDh2aDz/8MIcddpiQDgAAAGA51uRv1H3RlClT8sILL6SysjKbbbZZg3vjx4/PKaeckmHDhmXOnDnZddddc9FFF6Vnz54tUnRLqDswok2bNtlhhx3SqVOnPPLII5k6dWq23nrrPPTQQw0+UHj99dfnyCOPTL9+/fLee+/NN98tt9ySgw8+ODU1Ndliiy3Sv3//jBgxIqNGjUqPHj3y5JNPNjjKN/nsVdgXXngh7dq1y4EHHrjAkO7oo4/ONtts06L9J75RBwAAALCkLZFv1H3R1VdfnZ/85Cc56aSTGgR1c+fOzbbbbpt33303dRngX//617zwwgv517/+1eAUjqXp0ksvzdZbb50rr7wyTz/9dObNm5eBAwfmzDPPzA9/+MMGp380xQEHHJDVV189v/zlL/PEE0/khRdeyKqrrpoTTjghZ511Vnr06DHfM5MnT07y2Skif/rTnxY493bbbbdEgjoAAAAAykfJO+p23HHHPPbYY3n22WcbBHXXXHNNjjnmmHTp0iVnnXVWOnTokPPOOy8TJkzIhRdemFNPPbXFimfx2FEHAAAAsGQ1J38p+YNoo0aNSpKst956Da7feuutKRQK+eUvf5lTTz01xx13XK699toUi8XcfvvtpS4HAAAAAMu0knfUde7cOW3btq1/fTNJamtrU1lZmdmzZ2fChAnp2rVrks8OVWjXrl26dOmSSZMmtUzlLDY76gAAAACWrC9lR11NTU1mz57d4NqLL76YmTNnZv31168P6ZKkoqIiK664YmbMmFHqcgAAAACwTCs5qOvVq1fmzJmTt99+u/7afffdlySNHnwwY8aMrLzyyqUuBwAAAADLtJKDum233TbFYjGnnXZaJk6cmJdffjlXXnllCoVCdtlllwZj33nnncydOze9evVa7IIBAAAAYFlUclB32mmnpW3btrnvvvvSs2fPbLLJJpkwYULWW2+97Lrrrg3G/v3vf0+SbL755otXLQAAAAAso0oO6tZff/3ceeed6d+/f4rFYgqFQoYOHZq77747hUKhwdhrr702SbLDDjssXrUAAAAAsIwq+dTXz5s4cWI6d+6cDh06zHdv3rx5efrpp5N8tqOuY8eOi7scLcSprwAAAABLVnPyl9YtsWD37t0XeK9NmzYZMmRISywDAAAAAMuskl99/aJisZhPPvkkY8aMaakpAQAAAGC5sdhB3YgRI7L33nunS5cu6dGjR1ZfffUG96dOnZrvf//7OfbYYzNr1qzFXQ4AAAAAlkmLFdRdc8012XrrrXP33XdnxowZKRaL+eIn71ZcccV88MEHufrqq3PHHXcsVrEAAAAAsKwqOah78cUXc9xxx6W6ujrf//738/jjj6dbt26Njj3iiCNSLBbzwAMPlFwoAAAAACzLSj5M4uKLL05NTU1OOeWUXHzxxUmSioqKRscOHTo0SfL888+XuhwAAAAALNNK3lE3fPjwFAqF/PjHP17k2O7du6dTp04ZO3ZsqcsBAAAAwDKt5KDu448/TufOndOzZ88mjW/Xrl3mzJlT6nIAAAAAsEwrOajr1KlTZs2aldra2kWOnTFjRqZOnZquXbuWuhwAAAAALNNKDurWXXfd1NTU5KWXXlrk2Ntvvz21tbXZdNNNS10OAAAAAJZpJQd1++23X4rFYn7xi18sdNyoUaNyxhlnpFAo5MADDyx1OQAAAABYppUc1B133HFZY401ctddd2X//ffP008/nWKxmCSZOHFiRo4cmXPPPTebbbZZPv7442y00UY59NBDW6xwAAAAAFiWFIp16VoJ3nnnneyyyy559913UygUGh1TLBaz1lpr5aGHHkrfvn1LLpSWN23atHTp0iVVVVWprKxc2uUAAAAALHOak7+UvKMuSdZYY4288MILOfvss9OnT58Ui8UGv3r06JGf/vSnGTFihJAOAAAAABZisXbUfdGHH36Yjz76KDU1NenRo0f69+/fUlOzBNhRBwAAALBkNSd/ad2SC/fu3Tu9e/duySkBAAAAYLmwWK++AgAAAAAto+QddWPGjCnpudVWW63UJQEAAABgmVVyUDdgwIBmP1MoFFJdXV3qkgAAAACwzCo5qCvlDIoWPLcCAAAAAJYpJQd1o0ePXuj9qqqqjBgxIpdcckk++uij/PGPf8z6669f6nIAAAAAsEwrFJfwNre5c+dml112yauvvpp//etfToUtI805HhgA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ZUBQBwAAAABlQFAHAAAAAGWgSUHd448/nn/+859LuhYAAAAAWG61bsqg7bbbLquuumo+/PDD+mvf+973suKKK+biiy9eYsVRforFYj799NN8+umnmTdv3tIuBxZbmzZt0qlTp3Tu3HlplwIAAMByrlAsFouLGtSqVav07Nkz48aNW+g1vlqmTZuWLl26pKqqKpWVlYscXywWM378+LRu3TpdunRJ27Ztv4QqYcmaO3duqqqqUl1dnZ49e6ZQKCztkgAAAFiGNCd/adKrrx07dszkyZNTW1vbIgXy1TR9+vS0b98+3bt3F9KxzGjbtm26d++e9u3bZ/r06Uu7HAAAAJZjTXr1dd11182//vWvnHHGGTnyyCPrXxGrqanJBx98kCZsyqu32mqrlVYpS920adPSq1evpV0GLBFdunTJuHHjmrS7FAAAAJaEJgV1Rx11VJ5//vlcfPHFDb5J98knn6R///5NXqxQKKS6urrZRVI+WrVyUDDLJj/bAAAALG1NCuqOPfbYTJkyJZdeemkmTJhQf705O+lKGQ8AAAAAy4smBXVJ8pOf/CQ/+clPMnHixMycOTMDBgxI9+7d89xzzy3J+gAAAABgudDkoK5O9+7d6/+5oqIi/fr1a9GCAAAAAGB51Oygrs5jjz3m5E8AAAAAaCElfz19yJAh2WqrrVqyFljmPPTQQznyyCOz1lprpbKyMu3atcuqq66ab37zm/m///u/TJw48Uuv6YgjjkihUMj111//pa8NAAAALFjJO+o+b8SIEbn55pvz/PPP1x82scoqq+RrX/taDjrooGy22WYtsQx8ZXzyySc5+OCD8/DDDydJ+vfvn6FDh6ZTp04ZP358nn766Tz88MM5++yz8/DDD2eLLbZYyhUDAAAAS9tiBXXTpk3L9773vdxxxx1JGp7q+sYbb+Txxx/P//3f/2W//fbLNddck8rKysWrluXWzLnV6di2RXLlJa6qqirbbLNN3nzzzayzzjr5/e9/n8GDBzcYM2fOnPzxj3/MOeeck48++mgpVQoAAACUk5KTj5qamuy666555plnUiwWs/baa2fHHXdMnz59kiRjx47NI488kn//+9+57bbbMn78+Dz22GOpqKhoseJZtr08bloue2J0/vrih/l0bk06ta3IQRv3zkmDB2TDXuUb+p544ol58803079//zz11FPp2rXrfGPatWuXY445JnvttVemTp365RcJAAAAlJ2Sv1F3zTXX5Omnn07Hjh1z00035Y033sjll1+eM844I2eccUYuv/zyvP766/nzn/+cDh065Kmnnsq1117bkrWzDPvrCx9ms0sez7XPjcmnc2uSJJ/Orcm1z43JZpc8nr++8OFSrrBxo0aNyk033ZQkufjiixsN6T6vR48eWXvttZMk06dPz9VXX5199903a665Zjp16pROnTplgw02yM9+9rOFBnrV1dX5wx/+kB133DHdunVLu3bt0qdPn+y44465/PLLF/jc6NGjc9hhh6Vnz55p165dBg4cmP/+7//OnDlzFvjM888/n0MOOSSrrbZa2rVrl65du2bnnXfO/fffv9BeAQAAgIUrOai78cYbUygUcsUVV+Sggw5a4LiDDz44l19+eYrFYv70pz+VuhzLkZfHTcvhf3kh82qKjd6fV1PM4X95Ia98NO1LrmzR7r333tTU1GTFFVfMnnvu2axnX3rppRxzzDF58skn07Nnz+yxxx7ZZptt8tFHH+WXv/xlNt9880yaNGm+56qqqjJ06NAcddRRefzxx7P++utnv/32y1prrZWXX345J510UqPrvfjii9l4443zxBNPZMiQIdl2223z0Ucf5X/+538W+Hf60ksvzde//vXcdNNNWXnllbPnnntm0KBBGTZsWHbbbbecd955zeoZAAAA+I+SX3197bXX0qZNmxxyyCGLHHvooYfm2GOPzWuvvVbqcnxFVP70gZKeu3yf9fPdzfsmSS57YvQCQ7o682qK+drFj6d9mwW/Sj3tl7s0en2H3zyTER9MXeS4UowcOTJJsummmzb7Ne/+/fvn4YcfztChQ9Oq1X8y9JkzZ+a4447LDTfckLPPPjtXXnllg+e+973v5cknn8wmm2yS22+/Pf3796+/V11dnfvuu6/R9S699NL87Gc/y89//vP6Wl999dVsueWWufPOO/PMM880ONn5H//4R374wx9m5ZVXzm233ZZtt922/t4rr7ySXXfdNeecc06GDBmSIUOGNKt3AAAAYDF21M2aNSsdO3ZM69aLzvratGmTTp06ZdasWaUux1fE9DnVJf2aV1NbP8dfX2zaa63zaosLnXNBZs6radK4UkycODHJZ6ceN1efPn2yww47NAjpkqRjx475zW9+k9atW+eWW25pcO+ll17K7bffnvbt2+eee+5pENIlSevWrbPXXns1ut7Xvva1/OIXv2gQKK6//vo57LDDkqT+xNo655xzTorFYn772982COmSZIMNNsjFF1+cJAt91RYAAABYsJJ31PXs2TNjxozJe++9N1848EWjRo3K1KlT069fv1KXYzkxc251/TfplldPP/10nnjiiYwZMyYzZ86sP025bdu2mThxYqZMmZKVVlopSfL3v/89SbLbbruld+/ezVpn9913T6FQmO/6uuuumyT58MP/BKaffPJJnnvuuXTo0CF77LFHo/Ntt9129fUDAAAAzVdyUDd06NBcf/31OfHEE3PnnXcu8DW/mpqanHTSSSkUCtl+++1LLpSvhhXalfYj1abis11kHdu2Tqe2FU0O60pZr2ObipLrXJTu3bsnSSZMmNDsZydMmJD99tsvTz755ELHTZs2rT6oe//995Mk66yzTrPXW2211Rq9Xln52Ym6s2fPrr82evToFIvFzJo1K+3atVvovHW7CgEAAIDmKTmt+NGPfpQbb7wx999/f7baaqv85Cc/ydChQ7PiiismSaZOnZpHHnkkF1xwQZ5//vm0adMmp59+ekvVTZlqie+9HbRx71z73JhFjjt6i9Vy9YEbNXv+R47batGDSvS1r30tf/rTn/Kvf/0rNTU1zfpO3dFHH50nn3wyW221VX7+859no402ykorrZQ2bdokSXr16pWPPvqofofd4vriK7YLU1v72avJnTt3zn777dci6wMAAAANlRzUrbvuurnmmmty9NFHZ+TIkdl///2TJO3bt0/yn904xWIxrVu3zjXXXFP/Sh0szEmDB+SG5z9Y6IESbSoKOWnwgC+xqqbZfffdc+qpp2bq1Km5++67s88++zTpuU8//TT3339/WrVqlfvvv78+8P78/fHjx8/3XN2uuH//+9+LXfvC9O372UEfhUIhf/jDH5oV8gEAAABNs1j/a/vwww/Pk08+mR133DFJ6l+NmzVrVv2un5122ilPPfVU/QfqYVE27FWZGw7eJG0q5v9+WvJZSHfDwZtkg1Urv+TKFm3gwIE5+OCDkySnnXZaJk+evNDxEyZMyJtvvpmqqqrU1NSksrJyvpAuSW688cZGd9J961vfSpLcf//9GTdu3OI3sAC9evXKhhtumOnTp9d/Fw8AAABoWYu9LebrX/96HnzwwUyaNCkPP/xw/vKXv+Qvf/lLHn744UyaNCl///vfs/nmm7dErSxHDtqkd57/4bY5eovV0qntZ6+PdmpbkaO3WC3P/3DbHLRJ8w5O+DJdfvnlWWONNTJ69Ohss802jX5zbu7cufnDH/6QTTbZJG+88UZ69OiRlVZaKVOnTs2f/vSnBmP/+c9/5ic/+Umja2288cbZa6+9MmvWrOy1114ZM6bhK8PV1dW5++67W6Sv888/P0ly5JFH5p577pnvfrFYzLPPPpsHH3ywRdYDAACA5U2LfVF/xRVXdFgELWqDVStz9YEb5eoDN8qseTXp0Kbp33tbmlZaaaU89dRT+fa3v51hw4Zl8ODBGTBgQDbccMN07NgxH3/8cZ577rnMmDEjlZWV6dWrVyoqKnL22Wfnhz/8YQ4//PBceeWVWX311TNmzJg8/fTTOfTQQ/P444/XHx7xedddd1123XXX/POf/8yaa66Zb3zjG+nVq1fGjx+fV155JRMnTmyR79rtscceufTSS3Paaadlzz33zBprrJG11147Xbp0ycSJE/PSSy9lwoQJOeOMM7LTTjst9noAAACwvFkyR19CC/uqhHR1VllllTz22GP5+9//nr/85S95+umn88gjj2TOnDlZeeWVs9VWW2W33XbLYYcdlq5duyZJTjnllAwYMCC/+tWv8vrrr+e1117LOuuskyuvvDLHHntsBgxo/Jt8K620UoYPH54//OEPuemmm/Liiy/m6aefziqrrJKNN944e++9d4v1ddJJJ2X77bfP5ZdfnsceeyyPPPJIWrVqlZ49e2aTTTbJbrvt5rAJAAAAKFGh2FJHSPKVM23atHTp0iVVVVWprFz0997Gjh2bPn36fAmVwdLhZxwAAICW1pz8xdGNAAAAAFAGBHUAAAAAUAYEdQAAAABQBgR1AAAAAFAGBHUAAAAAUAZal/rgZZddliTZf//906tXrxYrCAAAAACWRyUHdT/84Q9TUVGRY489tiXrAQAAAIDlUslBXbdu3VJdXZ22bdu2ZD0AAAAAsFwq+Rt1m266aaqqqjJx4sSWrAcAAAAAlkslB3UnnXRSamtr84tf/KIl6wEAAACA5VLJQd0uu+ySX//61/ntb3+bww47LC+99FJL1gUAAAAAy5WSv1G3+uqrfzZB69a56aabctNNN6VDhw5ZeeWVU1FR0egzhUIh7777bqlLAgAAAMAyq+Sg7r333pvv2syZMzNz5swFPlMoFEpdDgAAAACWaSUHddddd11L1gEAAAAAy7WSg7rvfve7LVkHLDP69++f999/P9ddd12OOOKIxZ5vzpw5+fnPf55bbrklY8aMydy5c9OvX79Gd7UCAAAAX10lB3XAl+Oss87KhRdemB49emSvvfZKx44d061bt6VdFgAAANDCWiyoKxaLmTRpUmbOnJnVVlutpaZdom655ZZceeWVeemllzJ37tysscYaOeSQQ/LDH/4wbdq0afZ8zz//fC644II8/vjjqaqqyqqrrprdd989Z511VlZZZZUFPvfxxx/nF7/4Re67776MGzcuK664Yrbddtv85Cc/yaabbro4LX7lbPfAVRk+flSTxg7puXqG7XL8Eq5o6fvb3/6WJHniiSey5pprLuVqAAAAgCWl1eJOMGLEiOy9997p0qVLevToUX8abJ2pU6fm+9//fo499tjMmjVrcZdrMaecckoOPPDAPPXUU/n617+eb33rWxkzZkzOOOOMbL/99s2u9dZbb82WW26ZW2+9Nf369ctee+2VVq1a5YorrsiGG26Yd955p9Hn3nrrrWy44Ya58sor06pVq+y9997p169fbr311myxxRa54447WqLdr4xzN95piYz9KhszZkySCOkAAABgGbdYQd0111yTrbfeOnfffXdmzJiRYrGYYrHYYMyKK66YDz74IFdffXXZhE533nlnLr300nTu3DnPPvts/vGPf+S2227L22+/nQ022CBPPvlkzjrrrCbPN27cuHz3u99NdXV1fve73+W5557LzTffnLfeeiuHHnpoPv7443znO9+Z799NsVjMQQcdlAkTJuSwww7LW2+9lZtvvjnPPfdcfve736W6ujqHH354xo8f39L/CsrWdquukSE9V1/kuCE9V892q67xJVTUMs4999wUCoWce+65mThxYk444YT07ds3bdu2Td++fXPiiSdm6tSpDZ7p379/CoVC/c9NoVCo/3X99dc3GPv888/nkEMOyWqrrZZ27dqla9eu2XnnnXP//fc3Wk/d3O+9917uuuuubL/99unatWsKhUKGDRtWP27KlCk555xzsvHGG2eFFVZIx44ds8EGG+T8889v9ITnUvr8vLfeeivHH3981l577XTs2DGVlZVZb731cvzxx+fVV1+db3xz6wMAAIByVnJQ9+KL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xIl5//33c++99+ayyy7L1KlTs/HGG+fQQw8tdbkW079//yTJBx98sMAxdffqxi7M53frjBkzJhtssEGT5+vfv38mT56cMWPGLLSOltoV1KdPnwa/r3vFsEOHDvXvTief7YZqbKdVoVBodKdUY99Tq5unMc25XrerLkm277XmIscv6PqCamzu9VJ7+uJcC9tx1tQ1evfunQ033DAvv/xy/vGPf2TXXXddaO3N6WmXXXbJQw89lFtvvTUHHnjgIsfXXS/l31mrVq3yzW9+M3fddVeuueaaXHrppYusva6+W265JQcccECz11xYLZ/3+W8ZfN6CXjVu7O/Ngv4+VVRUNHq9devWDXYw1mnTps18r1Yv7PqCdlPqSU960lOip0RPetLTwq7rSU960tPCruupZXpakJLfT2vfvn3uv//+rL766rn99tszePDg+m9B9ezZM1tssUV+8YtfZOrUqVlrrbVy1113NQiDlpa613QnTZq0wMMiRo4cmSRNelW3srKy/j3luueaOl/d7xf13Jprrtnge3XLm3M33mmhp8Auz84///wkyZFHHpl77rlnvvvFYjHPPvts/XvyTXXMMcekX79+ueWWW3LGGWc0ehDM+PHjc/XVV5dW+Bf87Gc/S+vWrXPFFVfkqquumu/Qi/fffz/PP//8UqsPAAAAvgyL9SGpNdZYIy+88ELOPvvs9OnTp/5kxrpfPXr0yE9/+tOMGDFigQcZfNn69OlT/8HAm266ab77Tz75ZD744IO0a9eufofSouyzzz4LnG/GjBn1Acq+++7b6HN33333fN9n+/x8X3xuebPdqmvUn/RKQ3vssUcuvfTSTJ48OXvuuWfWXHPN7L777jnkkEOy0047pWfPntlyyy2b9eHK5LMDTu677770798/v/rVr7LaaqtlyJAhOeSQQ7LPPvtk0KBB6dWrV84666wW6WPzzTfPtddem4qKipxwwgkZMGBADjjggOy3337ZZJNNMmDAgAZB5JddHwAAAHwZFvuL7507d865556b999/Px988EGee+65PPPMMxk1alTGjRuX888/v8HpmOXgpz/9aZLkggsuyL/+9a/665MmTcrxxx+fJPnBD37Q4LTPO+64I+uss0522GGH+eY75ZRT0rFjxzz88MMNdvDU1NTk+OOPz9SpU7P55ptnp50a7grbZZddsskmm2Tq1Kk5/vjjU1NTU3/v97//fR555JF07tw5J598css0zjLppJNOygsvvJBjjjkmhUIhjzzySO688868++672WSTTXLZZZflpJNOava8gwYNyssvv5xf/epXWXfddfPyyy/nlltuybPPPptOnTrl9NNPzx133NFifRx++OF58cUXc9RRR6VVq1a555578sgjj2Tu3Lk54YQT5nsF98uuDwAAAJa0QvGL75gtJ04++eRcdtlladOmTXbYYYd06tQpjzzySKZOnZqtt946Dz30UIN3iK+//voceeSR6devX95777355rvlllty8MEHp6amJltssUX69++fESNGZNSoUenRo0eefPLJBkf51nnzzTfrXxteffXVs/nmm2f06NF57rnn0rp16/ztb3+r33nX0qZNm5YuXbqkqqoqlZWVixw/duzY+b5zB8sSP+MAAAC0tObkL4u9o+6L5s2bl3nz5rX0tC3u0ksvzc0335ytttoqTz/9dO6///706dMnF1xwQR599NFmfegvSQ444IA8++yz2XfffTNq1KjccccdqampyQknnJCXXnqp0ZAuSdZee+28/PLLOeGEE1JTU5M77rgjo0ePzr777ptnn312iYV0AAAAAJSXxd5RN2fOnFx33XW55ZZb8q9//av+JNHKyspsuummOfDAA3PEEUcs8KQMlh476qAhP+MAAAC0tObkL/OfYdsML7/8cvbbb7+MGjVqvlMaq6qq8thjj2XYsGG56KKLctttt2WDDTZYnOUAAAAAYJlVclA3duzYDB06NFOmTEm7du3y7W9/O0OGDEnv3r2TJOPGjcvw4cNz880355133sn222+fF198sf4+AAAAAPAfJQd15557bqZMmZI11lgjDzzwQAYOHDjfmCOOOCJnnXVWdtlll7zzzjs599xzG5yKCgAAAAB8puTDJB544IEUCoVcd911jYZ0dVZfffX84Q9/SLFYzAMPPFDqcgAAAACwTCs5qJs8eXI6d+6crbfeepFjt95663Tu3DmTJ08udTkAAAAAWKaVHNT17t07NTU1TRpbLBZTU1OTXr16lbocAAAAACzTSg7q9tprr8yaNSv333//Isc+8MADmTVrVvbee+9SlwMAAACAZVrJQd3ZZ5+d1VdfPUcddVSeeeaZBY775z//maOOOiprrrlmzjrrrFKXAwAAAIBlWpNOfb3hhhsavX788cfnvPPOy+DBgzN48OBst9126d27d5Jk3LhxGT58eIYPH57Kysocd9xxueuuu3L44Ye3XPUAAAAAsIwoFIvF4qIGtWrVKoVCYYH3i8XiAu9//l6hUEh1dXWJpdLSpk2bli5duqSqqiqVlZWLHD927Nj06dPnS6gMlg4/4wAAALS05uQvTdpRt9pqqy00qAMAAAAAFk+Tgrr33ntvCZcBAAAAAMu3kg+TABp69913UygU0qpVq0ycOLHRMTfeeGMKhUIKhUJuvPHGRsdMnDix/nXzd999d4nVe/3116dQKOSII45YYmsAAAAATSeogxYycODA9O3bN8ViMcOHD290zGOPPVb/z8OGDWt0zLBhw1IsFtO3b98MHDhwSZQKAAAAlCFBHWXv0zeG5dM3hi3tMppk6NChSRoGcp83bNiwdO/ePX369FloUPf5uQAAAIDlQ5O+Ubcwb775Zm699da88sormTJlSubNm7fAsYVCIY888sjiLslyZuKd5yZJOq07bKnW0RRDhw7NDTfc0GhQ98EHH2TUqFHZf//9065du/z5z3/OBx98kL59+zYYV/esoA4AAACWLyXvqCsWizn11FMzaNCgnH322fnb3/6Whx56KMOGDVvoL2iOT98Ylpn/Hp6Z/x7+ldhVVxeuvfHGG/n4448b3Kv7+d9uu+0yZMiQBtfqfPzxx3njjTcazJUkzz33XA488MD06tUrbdu2zSqrrJI99tgjDz30UKN1HHHEESkUCrn++uvz6quv5tvf/nZWXXXVVFRU5Nxzz11kH6NGjco666yTQqGQH/7wh6mtra2/N27cuJx66qlZd91107Fjx6ywwgrZfPPNc8UVV6S6urrFawEAAIDlRck76i6++OJccsklSZI11lgjQ4cOTY8ePVJRUdFStUH9brq6fy73XXX9+vXLgAEDMnr06AwbNizf/va36+/VhXJDhgxJ27Ztk3y2e+6www6bb8yAAQPSr1+/JMnVV1+dY489NrW1tdlkk02y3Xbb5f3338+9996be++9N+eee27OOeecRut5+umnc+yxx2bVVVfNtttum1mzZmWFFVZYaA///Oc/s+eee2bSpEm5/PLL84Mf/KD+3uOPP5699947U6ZMSf/+/fPNb34zc+bMyXPPPZcTTzwx99xzT+699960adOmRWoBAACA5UnJQd3VV1+dQqGQY489NldccUUKhUJL1sVXzFsn907t7OktOmexpjrFebPqfz/z38PzxtEdU6hY7De259Oq/QpZ69IPW2SuoUOHZvTo0XnsscfmC+q6d++eQYMGpVAopGfPnvPtqPvi9+leeeWVHH/88SkWi7nhhhsahHoPPPBA9t5775x77rn5xje+kW9+85vz1XL11VfnzDPPzP/8z/+kVatFb6C97bbbcthhh6VQKOSOO+7InnvuWX9v/Pjx2XfffTN16tRcddVV+f73v18/56RJk3LggQfmwQcfzP/+7//m7LPPXuxaAAAAYHlT8v9afv/991MoFPL//t//E9KR2tnTW/zX50O6OsV5s5bIWi0ZMjZ2oMSYMWMyatSobLvttvV/X4YMGZLRo0fn/fffrx/3xe/TXXrppamurs4+++zTIKRLkl122SXHHHNMkuTCCy9stJa11lor559/fpOCsV//+tc54IADUllZmeHDhzcI6ZLkkksuyaRJk3LCCSfkuOOOazDnyiuvnBtuuCFt2rTJFVdckWKxuFi1AAAAwPKo5P/F3L1791RWVqZz584tWQ985dWFbG+99VY++uijJA1fe63zxe/UjR8/Pm+++WaDOeruHXHEEY2uddRRRyVJnnjiidTU1Mx3f++9917k6+g1NTU5/vjj86Mf/SjrrLNO/vnPf2azzTabb9x9992XJA12CX5e7969s+aaa2bixIl5++23S6oFAAAAlmclv0O444475o9//GPef//9+m9psfxq1b5lvzVWO2dmUpw/eEqSFCrSql3HFl2vJeuvC6zefvvtPPbYY/nOd77T4CCJOp8P6r773e/Wj1lzzTXTu3fvJMmHH372Ou6AAQMaXWvgwIFJktmzZ2fSpElZZZVVGtzv37//Iuv961//murq6qyyyip56qmnstJKKzU6btSoUUmSwYMHL3LOiRMnZq211mp2LQAAALA8Kzmo+9nPfpY777wzJ598cm6//Xavsy3nWur7bslnJ72+f8HQBQ8o1qTvKXen07rbtdiaLW3o0KHzBXUrr7xy1l9//fox6623Xrp3717/uusXX3ttCR06dFjkmMGDB+e9997L6NGj86Mf/Si///3vG/37XHfy6/77759OnTotdM6VV165pFoAAABgeVZyUDdw4MDcf//9OeiggzJo0KCcfvrpWX/99bPqqqsu9LnVVlut1CVZTnz+pNeFjSnnE2CHDh2a3//+93nssccyZsyYjB49Ovvss89833Pcdtttc9ttt+W9996b7yCJ5LPdee+++25GjRrVIOSrU7fLrX379unatWtJta622mq58cYbs+OOO+baa6/NjBkzcuONN6Z164b/eejbt2/efvvtnHHGGY2+GgsAAAAsnsXaBrf22mtn9913z5tvvpljjjkm3/jGNzJgwIAF/lp99dVbqm6WUZ++MSwz/z18keNm/nt4Pn1j2JIvqER1r7i+++67ufHGGxtc+7y611///Oc/56233ppvXN0/X3/99Y2u84c//CHJZ7vivhisNUevXr3y+OOPZ5NNNsnNN9+cfffdN3PmzGkwZpdddkmS/O1vfyt5HQAAAGDBSg7qxo8fn6222iq/+c1vkiTFYnGRv+penYMFacpuulLGftl69uyZddddN0ly0UUXJVl4UHfxxRcnSdZdd9307Nmz/v7JJ5+c1q1b584776wP/Oo8+OCD+d3vfpckOf300xe75m7duuWxxx7L1ltvnXvuuSe77bZbPv300/r7P/rRj7Liiivm4osvzkUXXZS5c+fON8fo0aPnqxMAAABompK34Jx11ll56623ssIKK+RHP/pRdtxxx6yyyipOdWSx9P/JsKVdQosZOnRo3njjjUyePDldu3bNBhtsMN+YDTbYIF27ds3kyZPrn/ni/SuvvDLHHXdcDjvssPzf//1f1llnnbz//vt5+umnUywWc+6552annXZqkZq7dOmSf/zjH9l7773z8MMP55vf/Gbuv//+rLjiiunTp0/uuuuu7Lfffjn99NPzq1/9qv5196qqqrzxxht59913s8UWW+TQQw9tkXoAAABgeVJyUPfAAw+kUCjkxhtvzB577NGSNcEyYejQobnqqquSfPYtui9+ny5JCoVCBg8enLvuuqv+mS865phjstFGG+XXv/51nnzyybz88svp0qVLdt1115x88sn55je/2aJ1d+rUKffee2++/e1v56677srQoUPz4IMPpnv37tl2223z2muv5Yorrsh9992XESNGZM6cOVlllVWy2mqr5dBDD81+++3XovUAAADA8qJQLBaLpTxYd+rjjBkzGg0gKH/Tpk1Lly5dUlVVlcrKykWOHzt2bPr06fMlVAZLh59xAAAAWlpz8peSv1E3YMCAJBHSAQAAAEALKDmoO/TQQzN79uz8/e9/b8l6AAAAAGC5VHJQd/rpp2fbbbfNUUcdlSeffLIlawIAAACA5U7Jh0n88pe/zDbbbJOXXnopQ4YMyVZbbZUNNtggq6666kKfO/vss0tdEgAAAACWWSUfJtGqVasUCoV8/vGmfK+upqamlOVYAhwmAQ35GQcAAKClNSd/KXlH3bbbbusgCQAAAABoISUHdcOGDWvBMgAAAABg+VbyYRIAAAAAQMsR1NEsJX7SEMqen20AAACWNkEdTdauXbvMnj17aZcBS8Ts2bPTrl27pV0GAAAAy7GSv1G3/fbbN/uZQqGQRx55pNQlWcoqKyvzySefpFevXg4SYZlSLBYzefLkdOvWbWmXAgAAwHJsiR8mURfoFItF4c5XXLt27bLCCitk3Lhx6dq1a9q3b+/PlK+0YrGY2bNnZ/LkyVlhhRXsqAMAAGCpKjmoO+eccxZ6v6qqKiNGjMhTTz2Vrl275rjjjkvr1iUvR5morKxMu3btMm3atEyaNGlplwOLrV27dunWrZuQDgAAgKWuUFzCX1B/4oknss8+++Qb3/hG7r777iW5FM00bdq0dOnSJVVVVamsrFza5QAAAAAsc5qTvyzxwyQGDx6c3/zmN7nvvvty+eWXL+nlAAAAAOAr6Us59XWfffZJmzZt8oc//OHLWA4AAAAAvnK+lKCudevWadu2bd5+++0vYzkAAAAA+Mr5UoK6V199NTNmzEibNm2+jOUAAAAA4CtniQd1L7zwQg455JAUCoVsscUWS3o5AAAAAPhKal3qg9tvv/1C78+ePTtjx47Nhx9+mGKxmNatW+dnP/tZqcsBAAAAwDKt5KBu2LBhTR7bp0+fXHXVVRk8eHCpywEAAADAMq3koO6cc85Z+MStW2ellVbKBhtskK233jqtWn0pn8MDAAAAgK+kQrFYLC7tIlg6pk2bli5duqSqqiqVlZVLuxwAAACAZU5z8hfb3AAAAACgDAjqAAAAAKAMlPyNus+rqanJ22+/nSlTpmTevHkLHbvtttu2xJIAAAAAsExZrKDu/fffz09+8pPceeedmTNnziLHFwqFVFdXL86SAAAAALBMKjmoGz16dLbccst88sknaep5FM6tAAAAAIDGlfyNurPPPjsTJ05Mly5d8utf/zrvvPNOZs2aldra2oX+AgAAAADmV/KOuocffjiFQiE33HBDdt9995asCQAAAACWOyXvqJs6dWratWuXXXfdtSXrAQAAAIDlUslBXe/evVNRUZFWrUqeAgAAAAD4/5Wcsu27776ZOXNmnnvuuZasBwAAAACWSyUHdT/72c/Sr1+/HHfccZk6dWoLlgQAAAAAy5+SD5N46aWX8j//8z/5wQ9+kPXWWy/HHHNMNt9886ywwgoLfW7bbbctdUkAAAAAWGYVisVisZQHW7VqlUKh0LzFCoVUV1eXshxLwLRp09KlS5dUVVWlsrJyaZcDAAAAsMxpTv5S8o66JGluxldiJggAAAAAy7ySg7ra2tqWrAMAAAAAlmslHyYBAAAAALQcQR0AAAAAlAFBHQAAAACUAUEdAAAAAJQBQR0AAAAAlAFBHQAAAACUAUEdAAAAAJQBQR0AAAAAlIEmBXXnnXdeLr744iVdCwAAAAAstwrFYrG4qEGtWrVKz549M27cuPprq6++elZZZZX885//XKIFsuRMmzYtXbp0SVVVVSorK5d2OQAAAADLnObkL62bMmGhUEhtbW2Da++9915mz55depUAAAAAQL0mvfq64oorZtKkSZk+ffqSrgcAAAAAlktN2lH3ta99LY888kj22GOPHHjggencuXOSZNasWbnhhhuateDhhx/e/CoBAAAAYBnXpG/UPfLII/nWt76VmpqaFAqFJEmxWKz/5yYvViikurq6tEppcb5RBwAAALBktfg36nbYYYc89thjufzyy/Pqq69m1qxZee+999KqVav06dOnRYoGAAAAgOVZk3bUNaaxk2D5arGjDgAAAGDJak7+0qTDJAAAAACAJatJr742pra2tiXrAAAAAIDlWslBXWNqamoyefLkJEnXrl1TUVHRktMDAAAAwDJrsV99nTFjRi688MJsttlm6dChQ3r27JmePXumQ4cO2WyzzXLRRRfl008/bYlaAQAAAGCZVfJhEkny6quvZs8998z777+fBU1TKBTSv3//3H333Rk0aFDJhdLyHCYBAAAAsGQ1J38p+dXXKVOmZKeddsr48ePToUOHHH744dlxxx3Tp0+fJMnYsWPz0EMP5U9/+lNGjx6dnXfeOa+88kpWWmmlUpcEAAAAgGVWyUHdRRddlPHjx2fgwIH5xz/+kdVXX73B/S222CL77bdffvSjH2XnnXfO6NGjc/HFF+cXv/jFYhcNAAAAAMuakr9Rd/fdd6dQKOTaa6+dL6T7vIEDB+baa69NsVjMXXfdVepyAAAAALBMK/kbdSussEKSZPr06U0a37lz5xQKhSaPZ8nzjToAAACAJas5+ctin/raVIVC4ctaCgAAAAC+ckoO6gYMGJCZM2fmqaeeWuTYJ554Ip9++mn69+9f6nIAAAAAsEwrOajbfffdUywWc/TRR2fs2LELHDd27Nj813/9VwqFQvbcc89SlwMAAACAZVrJ36ibPHly1ltvvUycODGdO3fOEUcckaFDh6Z3795Jkg8//DCPPPJIbrjhhkyfPj09evTIa6+9lq5du7ZoA5TON+oAAAAAlqzm5C8lB3VJ8uKLL2bPPffM2LFjF/gNumKxmL59++auu+7KxhtvXOpSLAGCOgAAAIAl60s7TGLjjTfOq6++mvPPPz8bbrhhWrVqlWKxmGKxmFatWmWjjTbKL3/5y7zyyitCOgAAAABYiMXaUfdF8+bNy+TJk5MkXbt2TZs2bVpqapYAO+oAAAAAlqzm5C+tW3LhNm3apEePHi05JQAAAAAsFxbr1VcAAAAAoGUI6gAAAACgDAjqAAAAAKAMCOoAAAAAoAwI6gAAAACgDAjqAAAAAKAMCOoAAAAAoAwI6gAAAACgDDQ5qLv77rvz4IMPLslaAAAAAGC51bqpA/fee++suuqq+fDDD+e7d+6552b69Om56KKLWrQ4AAAAAFheNOvV12Kx2Oj13/3ud7nkkktaoh4AAAAAWC75Rh0AAAAAlAFBHQAAAACUAUEdAAAAAJQBQR0AAAAAlAFBHQAAAACUgdbNGTxjxoycd955jV5P0ui9Lzr77LObsyQAAAAALBcKxWKx2JSBrVq1SqFQWOwFa2pqFnsOWsa0adPSpUuXVFVVpbKycmmXAwAAALDMaU7+0uQddauttlqLBHUAAAAAwPyaHNS99957S7AMAAAAAFi+OUwCAAAAAMqAoA4AAAAAykCzTn1tzJw5czJ27NhMnjw5SdK1a9f06dMn7dq1W+ziAAAAAGB5UVJQN3fu3Fx77bX585//nJEjR2bevHkN7rdp0yabb755DjvssBx55JFp06ZNixQLAAAAAMuqQrFYLDbngddffz177LFH/eESC3q87oTYgQMH5p577snaa6+9eJXS4ppzPDAAAAAAzdec/KVZO+rGjBmTbbbZJlVVVSkWi9lwww2zyy67ZMMNN0zXrl2TJJMnT87LL7+c+++/P6+88kreeeedbLPNNnnxxRfTu3fv0rsCAAAAgGVYs3bUfetb38qDDz6Yrl275tprr81ee+210PF33nlnjj766EyZMiW77LJL7r333sUumJZjRx0AAADAktWc/KXJQd2///3vrLfeemnTpk2GDx+eLbfcsknFPPPMM9luu+1SXV2dN954I2uttVaTnmPJE9QBAAAALFnNyV9aNXXSm2++OUlyyCGHNDmkS5KtttoqhxxySIM5AAAAAICGmhzUjRw5MoVCIYcddlizFznssMNSLBYzYsSIZj+7JEyfPj0//elPs/baa6dDhw7p1q1bdttttzz66KMlz1lbW5vf/e532WKLLbLCCitkhRVWyBZbbJHf//73jR64UVtbm6effjpnn312ttlmm6y88spp06ZNunXrlm9+85v585//vMCDOgAAAABY9jT51deBAwfmvffeS1VVVTp37tysRWbMmJHKysqsvvrqeeedd0oqtKVMmDAhgwcPzltvvZVVV10122yzTT7++OM88cQTSZJLL700J554YrPmrKmpyYEHHpjbb789HTt2zA477JAkefjhhzNr1qwccMAB+etf/5pWrf6Ti77zzjtZc801kyRdu3bNZpttlpVWWimjRo2qDzR333333HbbbWnbtm1LtD4fr74CAAAALFlL5NXXqVOnpkOHDs0O6ZKkc+fO6dixY6ZMmdLsZ1vaMccck7feeis77LBD3nnnnfztb3/L8OHDc++996ZVq1Y55ZRT8vLLLzdrzssvvzy33357evfunVdffTV333137r777rz22mvp1atXbrnlllx11VUNnikUCtl+++3zwAMPZMKECfnHP/6Rv/71r3nuuecybNiwdOrUKffee28uuOCClmwfAAAAgDLV5B11da9lfvTRRyUttOqqq2bSpEmZO3duSc+3hNdffz2DBg1KRUVF3n333fTr16/B/aOPPjrXXnttDjrooPzlL39p0py1tbXp3bt3xo8fnxtvvLH+e3x1brzxxhx22GHp1atXPvjggwa76hbm/PPPz1lnnZWBAwcusV2IdtQBAAAALFlLZEddTU1NCoXCYhVWU1OzWM8vrjvuuCNJsvXWW88X0iXJd77znSTJPffck3nz5jVpzmeeeSbjx49Pu3btst9++813f7/99kvbtm0zbty4PPvss02udZNNNkmSfPDBB01+BgAAAICvriYHdcuCF154IUmy2WabNXq/7vqnn36at99+u1lzDho0KO3bt5/vfocOHTJo0KAGY5uibv1VV121yc8AAAAA8NXVujmDJ0+enO23376khSZPnlzScy1p9OjRSZLVVlut0fuVlZWprKzMtGnTMnr06Ky33nqLPWeS9O3bNy+88EL92EWZOXNmLrvssiRpdJdeqcaOHdvg99OnT0+SzJo1K506dUpFRUWSz17nnTNnTpKkXbt29a/r1tTU1L+63KFDh/p5qqurM2/evBQKhQZh5bx581JdXZ1WrVqlXbt2812vqKhocFDG3LlzU1NTk9atW6dNmzb11+fMmZPa2tr5rs+ePTvFYjFt2rRJ69b/+VGeNWtWkqRt27Z60pOe9KQnPelJT3rSk570pCc96UlPS7WnuutN0aygbu7cuRk2bFhzHmlgcV+dXVx1wVSnTp0WOKZz586ZNm1apk2b1qJzJmnynMcff3xGjx6dXr165ac//WmTnmmKvn37Nnr90Ucfzc4775yuXbsm+ewH8cEHH0yS7LTTTvV/CaqqqupPx91rr73qn//4448zcuTItG/fPjvvvHP99ffffz+vvfZaVlpppWy77bb119988828++676dWrVzbffPP66y+99FLGjRuXgQMHZv3116+//uyzz2bKlCkZNGhQ1lhjjfrrw4cPz+zZs7PZZpuld+/e9dfrah88eLCe9KQnPelJT3rSk570pCc96UlPetLTUu3p0UcfTVM1Oaj77ne/2+RJl4Qf//jHufvuu5v93DXXXJNtttlmCVS0ZPziF7/IH//4x7Rv3z5/+9vfsvLKKy/tkgAAAAD4EjT51Nel7dBDD82f//znZj/3wAMP5Fvf+laS5Gtf+1r+9a9/5ZJLLsnJJ5/c6PguXbpk2rRpuffee7Pbbrstcv7TTjstF198cfbee+/6wyq+aK+99srdd9+d008/PRdeeOEC57r44otz2mmnpV27drnzzjvr624pjb36ut5662X8+PHp1q3bMr/VVE960pOe9KQnPelJT3rSk570pCc96enL7mnixInp2bNnk059/coEdS1hv/32y+23355TTz01F1100Xz3647LTZJXX321/hCIhbn88stz0kknZdNNN83zzz/f6JhNN900L7zwQq644oqccMIJC52nbdu2uf3225sUEi6u5hwPDAAAAEDzNSd/Wa5Ofd10002TJCNHjmz0ft31Tp06Za211mrWnK+99lpmz5493/1Zs2bltddeazD2i6688sr6kO622277UkI6AAAAAMpLs4K66667Lvvuu29OOeWUJo0vFos5+eSTs++++5b02mpL23vvvZMkTz31VMaMGTPf/ZtuuilJssceezTY0rgwW221VXr27Jk5c+bktttum+/+bbfdlrlz56ZXr17ZYost5rv/29/+Nj/4wQ/qQ7rdd9+9GR0BAAAAsKxoclA3ZcqUnHLKKbn77rtz8MEHN+mZQqGQgw46KHfddVdOPvnk+hNSl5ZBgwZlr732Sk1NTY466qgGx+M+8MADuf7669OqVav85Cc/me/Zww8/POuss06uuOKKBtdbtWqVM844I0lyxhlnZPTo0fX3Ro8enTPPPDNJ8pOf/KT+3eo6V199dY4//nghHQAAAABNP/X1pptuyvTp03PggQc2ujNsQbbaaqvsv//+ufXWW/PXv/41//Vf/1VSoS3l97//fV5//fU8/PDDGThwYAYPHpwJEyZk+PDhKRaLufTSS7PhhhvO99yYMWPy5ptv5pNPPpnv3oknnpjHH388d9xxR9Zff/3suOOOSZKHH344M2fOzP7775/jjz++wTMvvvhivv/976dYLGb11VfPrbfemltvvbXRmq+//vrFbxwAAACAstbkoO6BBx5IoVDIkUce2exFvve97+WWW27JPffcs9SDulVWWSUjR47M//7v/+a2227LXXfdlU6dOmXnnXfO6aefnh122KHZc1ZUVOTWW2/N1VdfnWuuuSaPPPJIks928B111FE55phjUigUGjwzderU1J3j8e9//zv//ve/Fzi/oA4AAABg2dfkU1/79u2bcePG5dNPP21w5G1TzJo1K506dUrfvn3z/vvvl1QoLc+prwAAAABL1hI59XXSpEnp0qVLs0O6JOnQoUO6dOmSiRMnNvtZAAAAAFgeNDmoq6ioyNy5c0teaN68efMdpgAAAAAAfKbJyVn37t0za9asknbFTZw4MTNnzkz37t2b/SwAAAAALA+aHNRtuummSZL777+/2Yvcd999DeYAAAAAABpqclC32267pVgs5pe//GVmzZrV5AVmzZqVX/7ylykUCtltt91KKhIAAAAAlnVNDuoOOeSQ9OnTJ++8807233//TJs2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hjX2k08+8enzfqGWZP7whz/4jT158qQVEs6aNcun71xq3bt3r3E6nSYmJsYKgM62ZcsW43A4jMvlMiUlJfXe94UM6kJDQwO+DyNHjrSOMWDAAL/+48ePW2HXa6+95tPXmLU3NKiTZDZu3OjX/9RTT1n93bt3N1VVVT79Ho/HdOvWzUgyTz31lN/4pgrqmvra+89//mP96u7555+v9zGD9dksLi42TqfTSDKLFi3yG1teXm569OhRa1Dn/SXv1q1b611roLkT1AEAasMadQAANFNbtmxRfHy89XK73erVq5fy8vIkSQ8++KCGDRvmM+add95RaWmp+vXrZ61jd7auXbvqhhtukCSftbAiIyMlSSUlJec033vvvVfdunXza+/bt6/69esnSVqxYoXVfvToUa1fv16SNH36dLlcLr+x9913n5KSkiRJb731VsDjut1uTZo0ya89LCzMeiLurl27fPrOpdbly5erpqZGd911l6644oqA2/Tu3VtdunRRVVWVNmzYUO99X0j33HNPwPdh4MCB1n9Pnz7drz8iIsK6Ls5er8xOtffu3VsZGRl+7WfWN3XqVIWGhvr0O51Oay3A2tZjawpNfe0tX75cxhh16dIl4OckkGB+NleuXKmamhrFxsZq7NixAfc5derUWud+vv+OAQDwYwjqAABopqqqqnTw4EHr5V24PSQkRK+//rqWLFkih8PhM2bLli2SpK1bt/qEfGe/vNuduaj6LbfcIklavXq1br/9dq1YsUKHDx+u93y9C8cH4g1W8vPzrbb8/HwZYyRJN954Y61jvQHMjh07AvYnJycrIiIiYF/Hjh0lnQ4eznQutXrP2dtvv13nuf3mm28kKWgL1v/kJz8J2N6uXTvrv3v27Blwm7i4OEn+58tOtTdGfU2pqa+9rVu3SpIGDx4sp7N+Xy2C+dn07qtPnz4BA0JJPg9fOdutt94qSRo+fLiysrK0ZcsWVVZW1ro9AAANRVAHAEAzlZGRIXN6GQxVVlbqiy++0Lhx4+TxeDRx4kR9/vnnfmO8T708efKkT8h39sv71NeTJ0/6HO/pp59WaGio1q5dq3vvvVft2rVT9+7dNX78+IDHO5P3i3ddfYcOHbLavOGE2+1WmzZtah17+eWX+409U+vWrWsd63a7JZ0OPc90LrV6z21ZWVmd59Z7rDPPbVNq3759wPaQkJB6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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "\n", + "lss = [\"--\", \":\", \"-\"]\n", + "markers = ['o', 'v', '^']\n", + "\n", + "for idl, (key, label) in enumerate(labels.items()):\n", + " x_values = data[key].keys()\n", + " y_values = data[key].values()\n", + " new_x_values = [indices.index(x) for x in x_values]\n", + "\n", + " # plt.semilogx(x_values, y_values, label=label)\n", + " plt.plot(new_x_values, y_values, label=label, ls=lss[idl], marker=markers[idl], markeredgecolor='white', markersize=8)\n", + "plt.xlabel(\"Response time [milliseconds]\")\n", + "plt.ylabel(\"CDF of number of requests\")\n", + "plt.xticks(range(len(indices)), indices, rotation=90)\n", + "plt.legend(loc=6)\n", + "plt.grid(axis=\"both\", ls=\":\")\n", + "plt.xlim([1.5, 14.5])\n", + "plt.tight_layout()\n", + "plt.savefig(os.path.join(base_results_folder, latest_folder, \"figures\", f\"cdf_summary_response_time.pdf\"))\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.14" + }, + "vscode": { + "interpreter": { + "hash": "7ea5723b29014fc8d8bf1a065f5287f0787f54201758f2b5d4b4b0b2ddc48863" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/src/tests/scenario3/optical/jocn/run_experiment.py b/src/tests/scenario3/optical/jocn/run_experiment.py new file mode 100644 index 0000000000000000000000000000000000000000..4ebf5ea80baecc89a66fef5bcb0f240bd61f1f5a --- /dev/null +++ b/src/tests/scenario3/optical/jocn/run_experiment.py @@ -0,0 +1,334 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 datetime +import pickle +import uuid +import logging +import multiprocessing +import signal +import os +import threading +import yaml + +import requests +import redis +from kubernetes import client, config + +from common.Constants import ServiceNameEnum +from common.Settings import get_service_host, get_setting, wait_for_environment_variables + +from configs import base_results_folder, datetime_format, hpa_data + +LOGGER = None +SERVICE_LIST_KEY = get_setting( + "OPTICALATTACKMANAGER_SERVICE_LIST_KEY", default="opt-sec:active-services" +) + +# Configs can be set in Configuration class directly or using helper utility +config.load_kube_config() + +logging.getLogger("kubernetes").setLevel(logging.INFO) # avoid lengthy messages + +# setting up graceful shutdown +terminate = threading.Event() + + +def signal_handler(signal, frame): # pylint: disable=redefined-outer-name + LOGGER.warning("Terminate signal received") + terminate.set() + + +def manage_number_services(terminate, folder): + + # connecting with Redis + redis_host = get_service_host(ServiceNameEnum.CACHING) + redis_password = None + if redis_host is not None: + redis_port = int(get_setting("CACHINGSERVICE_SERVICE_PORT_REDIS")) + redis_password = get_setting("REDIS_PASSWORD") + else: + LOGGER.fatal("No environment variables set for Redis") + + cache = None + try: + cache = redis.Redis(host=redis_host, port=redis_port, password=redis_password) + except Exception as e: + LOGGER.exception(e) + + # clean the existing list that will be populated later on in this function + cache.delete(SERVICE_LIST_KEY) + + # make sure we have the correct loop time + cache.set("MONITORING_INTERVAL", 30) + + # connecting to the HPA API + autoscaling = client.AutoscalingV1Api() + + # connecting to the custom objects API + api = client.CustomObjectsApi() + + # open the file that will store the information + services_file = open(os.path.join(folder, "services.csv"), "wt", encoding="utf-8") + services_file.write("# file with number of services\n") + services_file.write("timestamp,number_services") + + hpa_file = open(os.path.join(folder, "hpas.csv"), "wt", encoding="utf-8") + + # writing headers for the HPA columns + hpas = autoscaling.list_namespaced_horizontal_pod_autoscaler(namespace="tfs") + + for hpa in hpas.items: + hpa_file.write(hpa.metadata.name + "\n") + for d in hpa_data: + services_file.write(f",{hpa.metadata.name}_{d}") + + # monitoring CPU and RAM usage of the single Pods + for s in ["cache", "manager"]: + for k in ["cpu", "ram"]: + services_file.write(f",{s}_{k}") + + services_file.write("\n") + services_file.flush() + + hpa_file.flush() + hpa_file.close() + + # define number of services + # 6 values followed by two zeros + number_services = [0, 10] + + loads = [120, 240, 480, 960, 1440, 1920, 1922] + for load in loads: + number_services.append(int(load/2)) + for _ in range(5): + number_services.append(load) + for _ in range(2): + number_services.append(0) + + ticks = 1 # defines how much to wait + set_to_60 = False + cur_tick = 0 + LOGGER.info("Starting load!") + while not terminate.wait(timeout=30): # timeout=300 + if cur_tick % ticks == 0: + LOGGER.debug("go load!") + + # getting data from autoscaler + hpas = autoscaling.list_namespaced_horizontal_pod_autoscaler(namespace="tfs") + # - "cur_utilization" + # - "target_utilization" + # - "cur_replicas" + # - "desired_replicas" + hpa_string = "" + for hpa in hpas.items: + hpa_string += f",{hpa.status.current_cpu_utilization_percentage}" + hpa_string += f",{hpa.spec.target_cpu_utilization_percentage}" + hpa_string += f",{hpa.status.current_replicas}" + hpa_string += f",{hpa.status.desired_replicas}" + + # monitoring resource usage + k8s_pods = api.list_cluster_custom_object( + "metrics.k8s.io", "v1beta1", "namespaces/tfs/pods" + ) + # - "cache_cpu" + # - "cache_ram" + # - "manager_cpu" + # - "manager_ram" + resource_string = "" + + # we use two loops to ensure the same order + for stats in k8s_pods["items"]: + if "caching" in stats['metadata']['name']: + resource_string += f",{stats['containers'][0]['usage']['cpu']}" + resource_string += f",{stats['containers'][0]['usage']['memory']}" + break + for stats in k8s_pods["items"]: + if "opticalattackmanager" in stats['metadata']['name']: + resource_string += f",{stats['containers'][0]['usage']['cpu']}" + resource_string += f",{stats['containers'][0]['usage']['memory']}" + break + + # calculate the difference between current and expected + cur_services = cache.llen(SERVICE_LIST_KEY) + diff_services = cur_services - number_services[cur_tick % len(number_services)] + + if not set_to_60 and number_services[cur_tick + 1 % len(number_services)] == 961: + cache.set("MONITORING_INTERVAL", 60) + LOGGER.info("Setting monitoring interval to 60") + set_to_60 = True + + # write current number with one second difference + cur_datetime = datetime.datetime.now() + reported_datetime = cur_datetime - datetime.timedelta(seconds=1) + reported_datetime_str = reported_datetime.strftime(datetime_format) + services_file.write(f"{reported_datetime_str},{cur_services}{hpa_string}\n") + + if diff_services < 0: # current is lower than expected + LOGGER.debug(f"inserting <{-diff_services}> services") + for _ in range(-diff_services): + cache.lpush( + SERVICE_LIST_KEY, + pickle.dumps( + { + "context": str(uuid.uuid4()), + "service": str(uuid.uuid4()), + "kpi": str(uuid.uuid4()), + } + ), + ) + elif diff_services > 0: # current is greater than expected + # delete services + LOGGER.debug(f"deleting <{diff_services}> services") + cache.lpop(SERVICE_LIST_KEY, diff_services) + + # writing the new number with the current time + services_file.write( + f"{datetime.datetime.now().strftime(datetime_format)}," + f"{number_services[cur_tick % len(number_services)]}" + f"{hpa_string}{resource_string}\n" + ) + + assert number_services[cur_tick % len(number_services)] == cache.llen(SERVICE_LIST_KEY) + + services_file.flush() + else: + LOGGER.debug("tick load!") + cur_tick += 1 + if cur_tick > len(number_services) + 1: + break + services_file.flush() + services_file.close() + # make sure we have the correct loop time + cache.set("MONITORING_INTERVAL", 30) + + LOGGER.info("Finished load!") + + +def monitor_endpoints(terminate): + LOGGER.info("starting experiment!") + v1 = client.CoreV1Api() + while not terminate.wait(timeout=30): + + # load base yaml + with open("/home/carda/projects/prometheus/prometheus.yml.backup", "rt") as file: + current_version = yaml.load(file, Loader=yaml.FullLoader) + + # checking endpoints + ret = v1.list_namespaced_endpoints(namespace="tfs", watch=False) + for item in ret.items: + found = False + + for subset in item.subsets: + for p, q in enumerate(subset.ports): + if q.name == "metrics": # endpoint is ready for being scraped + found = True + if not found: + continue # if no `metrics` port, jump! + + found = False # now look for existing configuration + for i in range(len(current_version["scrape_configs"])): + if current_version["scrape_configs"][i]["job_name"] == item.metadata.name: + found = True + break # found it! `i` will contain the correct index + + if not found: # write it from zero! + current_version["scrape_configs"].append({}) + current_version["scrape_configs"][-1]["job_name"] = item.metadata.name + + # set the correct `i` value + i = len(current_version["scrape_configs"]) - 1 + + if "static_configs" not in current_version["scrape_configs"][i]: + current_version["scrape_configs"][i]["static_configs"] = [{"targets": []}] + # reset IPs + current_version["scrape_configs"][i]["static_configs"][0]["targets"] = [] + for subset in item.subsets: + for p, q in enumerate(subset.ports): + if q.name == "metrics": + for c, a in enumerate(subset.addresses): + print(f"{item.metadata.name}\t{a.ip}:{q.port}") + current_version["scrape_configs"][i]["static_configs"][0]["targets"].append(f"{a.ip}:9192") + + # write yaml + with open("/home/carda/projects/prometheus/prometheus.yml", "wt") as file: + yaml.dump(current_version, file) + + # reloading configuration + # docs: https://www.robustperception.io/reloading-prometheus-configuration/ + requests.post("http://127.0.0.1:9090/-/reload") + + # resetting prometheus to the original state + # load base yaml + with open("/home/carda/projects/prometheus/prometheus.yml.backup", "rt") as file: + current_version = yaml.load(file, Loader=yaml.FullLoader) + + # write yaml + with open("/home/carda/projects/prometheus/prometheus.yml", "wt") as file: + yaml.dump(current_version, file) + # reloading configuration + # docs: https://www.robustperception.io/reloading-prometheus-configuration/ + requests.post("http://127.0.0.1:9090/-/reload") + + LOGGER.info("Finished experiment!") + + +if __name__ == "__main__": + # logging.basicConfig(level="DEBUG") + logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s.%(msecs)03d %(levelname)s - %(funcName)s: %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + ) + LOGGER = logging.getLogger(__name__) + + wait_for_environment_variables( + ["CACHINGSERVICE_SERVICE_PORT_REDIS", "REDIS_PASSWORD"] + ) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + # generate results folder + output_folder = os.path.join(base_results_folder, "jocn_" + datetime.datetime.now( + datetime.timezone.utc + ).strftime("%Y%m%dT%H%M%S.%fUTC")) + os.makedirs(output_folder) + + # start load handler + proc_load = multiprocessing.Process( + target=manage_number_services, + args=( + terminate, + output_folder, + ), + ) + proc_load.start() + + # start experiment monitoring + proc_experiment = multiprocessing.Process( + target=monitor_endpoints, args=(terminate,) + ) + proc_experiment.start() + + # Wait for Ctrl+C or termination signal + while not terminate.wait(timeout=0.1): + pass + + # waits for the processes to finish + proc_load.join() + proc_experiment.join() + + # exits + LOGGER.info("Bye!") diff --git a/src/tests/scenario3/optical/ofc23/README.md b/src/tests/scenario3/optical/ofc23/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f517ab728906fa7640143a7b27d76418c5ee7960 --- /dev/null +++ b/src/tests/scenario3/optical/ofc23/README.md @@ -0,0 +1,17 @@ +# Demonstration of a Scalable and Efficient Pipeline for ML-based Optical Network Monitoring + +__Authors__: [Carlos Natalino](https://www.chalmers.se/en/persons/carda/), Lluis Gifre Renom, Raul Muñoz, Ricard Vilalta, Marija Furdek and Paolo Monti + +## Executing + +```bash +source src/tests/scenario3/optical/deploy_specs.sh +``` + +```bash +source tfs_runtime_env_vars.sh +``` + +```bash +python src/tests/scenario3/optical/ofc23/run_experiment_demo.py +``` \ No newline at end of file diff --git a/src/tests/scenario3/optical/ofc23/dashboard.json b/src/tests/scenario3/optical/ofc23/dashboard.json new file mode 100644 index 0000000000000000000000000000000000000000..d62fe95a0407287168cd03195f3d48457d7ec288 --- /dev/null +++ b/src/tests/scenario3/optical/ofc23/dashboard.json @@ -0,0 +1,732 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 2, + "id": 27, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 16, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Pipeline-specific metrics", + "mode": "markdown" + }, + "pluginVersion": "9.2.4", + "title": "Panel Title", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 3 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "optical_security_active_services", + "legendFormat": "Active services", + "range": true, + "refId": "A" + } + ], + "title": "Optical active services", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 3 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le) (rate(optical_security_loop_seconds_bucket[$__rate_interval])))", + "legendFormat": "Measured", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "optical_security_desired_monitoring_interval", + "hide": false, + "legendFormat": "Desired", + "range": true, + "refId": "B" + } + ], + "title": "Loop time", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "optical_security_number_workers", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Number workers (Manager)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 30, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le) (rate(OPTICAL_ATTACK_DETECTOR_WORKER_RESPONSE_TIME_bucket[$__rate_interval])))", + "legendFormat": "Service Monitor", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le) (rate(OPTICAL_ATTACK_DETECTOR_INFERENCE_RESPONSE_TIME_bucket[$__rate_interval])))", + "hide": false, + "legendFormat": "ML Inference", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le) (rate(OPTICAL_ATTACK_DETECTOR_CACHE_RESPONSE_TIME_bucket[$__rate_interval])))", + "hide": false, + "legendFormat": "Cache", + "range": true, + "refId": "C" + } + ], + "title": "Response Times", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 18, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Resource consumption metrics", + "mode": "markdown" + }, + "pluginVersion": "9.2.4", + "title": "Panel Title", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "Number of replicas", + "axisPlacement": "auto", + "axisSoftMax": 6, + "axisSoftMin": 1, + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "kube_replicaset_status_replicas{namespace=\"tfs\", replicaset=~\"opticalattackdetector.+\"}", + "hide": false, + "legendFormat": "Service Monitor", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "kube_replicaset_status_replicas{namespace=\"tfs\", replicaset=~\"dbscanserving.+\"}", + "legendFormat": "ML Inference", + "range": true, + "refId": "A" + } + ], + "title": "Replicas", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "CPUs", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 17, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"tfs\", pod=~\"opticalattackmanager.+\"})", + "hide": false, + "interval": "", + "legendFormat": "Manager", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"tfs\", pod=~\"opticalattackdetector.+\"})", + "hide": false, + "interval": "", + "legendFormat": "Service Monitor", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"tfs\", pod=~\"dbscanservingservice.+\"})", + "hide": false, + "interval": "", + "legendFormat": "ML Inference", + "range": true, + "refId": "A" + } + ], + "title": "CPU Utilization", + "type": "timeseries" + } + ], + "refresh": "5s", + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Scalable and Efficient Pipeline for ML-based Optical Network Monitoring", + "uid": "IYQSZX0Vk", + "version": 4, + "weekStart": "" +} \ No newline at end of file diff --git a/src/tests/scenario3/optical/ofc23/run_experiment_demo.py b/src/tests/scenario3/optical/ofc23/run_experiment_demo.py new file mode 100644 index 0000000000000000000000000000000000000000..27151695b82426cc76c97971bbbb1749d4ebbbf5 --- /dev/null +++ b/src/tests/scenario3/optical/ofc23/run_experiment_demo.py @@ -0,0 +1,162 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 pickle +import uuid +import logging +import signal +import threading + +import redis +from kubernetes import client, config + +from common.Constants import ServiceNameEnum +from common.Settings import get_service_host, get_setting, wait_for_environment_variables + +# Configs can be set in Configuration class directly or using helper utility +namespace = get_setting("TFS_K8S_NAMESPACE", default="tfs") +config.load_kube_config() +v1 = client.CoreV1Api() + +caching_pod = None +pods = v1.list_namespaced_pod(namespace=namespace) +for pod in pods.items: + # print(pod.metadata) + if "app" in pod.metadata.labels and "caching" in pod.metadata.labels["app"]: + caching_pod = pod + +LOGGER = None +SERVICE_LIST_KEY = get_setting( + "OPTICALATTACKMANAGER_SERVICE_LIST_KEY", default="opt-sec:active-services" +) + +# setting up graceful shutdown +terminate = threading.Event() + + +def signal_handler(signal, frame): # pylint: disable=redefined-outer-name + LOGGER.warning("Terminate signal received") + terminate.set() + + +def manage_number_services(terminate): + + # connecting with Redis + redis_host = caching_pod.status.pod_ip + redis_password = None + if redis_host is not None: + redis_port = int(get_setting("CACHINGSERVICE_SERVICE_PORT_REDIS", default=6379)) + redis_password = get_setting("REDIS_PASSWORD") + LOGGER.info(f"Redis password: {redis_password}") + else: + LOGGER.fatal("No environment variables set for Redis") + + cache = None + try: + LOGGER.info(f"Connecting to Redis: host={redis_host}, port={redis_port}, password={redis_password}") + cache = redis.Redis(host=redis_host, port=redis_port, password=redis_password) + cache.ping() + LOGGER.info("Connected to Redis") + except Exception as e: + LOGGER.exception(e) + + # clean the existing list that will be populated later on in this function + cache.delete(SERVICE_LIST_KEY) + + # make sure we have the correct loop time + cache.set("MONITORING_INTERVAL", 30) + + # define number of services + + print("Starting load!") + while not terminate.wait(timeout=1): # timeout=300 + print("\no -> sets the number services currently monitored") + print("p -> sets the loop period") + print("m <1=SL / 2=UL> -> sets the ML model used") + print("q -> exit") + from_user = input("Command: ") + if from_user.strip() == "q": + return + try: + parts = from_user.split(" ") + assert len(parts) == 2, "Wrong number of values!" + number = int(parts[1]) + if parts[0].strip() == "o": + print(f"New number of services: {number}") + + cur_services = cache.llen(SERVICE_LIST_KEY) + diff_services = cur_services - number + + if diff_services < 0: # current is lower than expected + LOGGER.debug(f"\tinserting <{-diff_services}> services") + for _ in range(-diff_services): + cache.lpush( + SERVICE_LIST_KEY, + pickle.dumps( + { + "context": str(uuid.uuid4()), + "service": str(uuid.uuid4()), + "kpi": str(uuid.uuid4()), + } + ), + ) + elif diff_services > 0: # current is greater than expected + # delete services + LOGGER.debug(f"\tdeleting <{diff_services}> services") + cache.lpop(SERVICE_LIST_KEY, diff_services) + + elif parts[0].strip() == "p": + print(f"setting new period: {number} seconds") + cache.set("MONITORING_INTERVAL", number) + elif parts[0] == "m": + if "1" == parts[1].strip(): + print(f"setting new ML model: {parts[1]}") + cache.set("ATTACK_DETECTION_MODE", "SL") + elif "2" == parts[1].strip(): + print(f"setting new ML model: {parts[1]}") + cache.set("ATTACK_DETECTION_MODE", "UL") + else: + print(f"your input is not valid: `{from_user}`") + else: + print(f"Wrong command: {from_user}") + except: + print(f"Your input is not a number: `{from_user}`") + continue + + # make sure we have the correct loop time + cache.set("MONITORING_INTERVAL", 30) + + print("Finished load!") + + +if __name__ == "__main__": + # logging.basicConfig(level="DEBUG") + logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s.%(msecs)03d %(levelname)s - %(funcName)s: %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + ) + LOGGER = logging.getLogger(__name__) + + wait_for_environment_variables( + ["REDIS_PASSWORD"] + ) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + manage_number_services(terminate) + + # exits + LOGGER.info("Bye!") diff --git a/src/tests/scenario3/optical/scaphandre.yaml b/src/tests/scenario3/optical/scaphandre.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3b348cb8a91ee257eaa9aa73e96108d20931e2a2 --- /dev/null +++ b/src/tests/scenario3/optical/scaphandre.yaml @@ -0,0 +1,47 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +# this file deploys a tool that enables the monitoring of energy consumption +# per component. +# More info: https://github.com/hubblo-org/scaphandre + +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-scaph-metric + labels: + app.kubernetes.io/name: scaphandre + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app.kubernetes.io/name: scaphandre + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running \ No newline at end of file diff --git a/src/tests/tools/mock_ipm_sdn_ctrl/MockIPMSdnCtrl.py b/src/tests/tools/mock_ipm_sdn_ctrl/MockIPMSdnCtrl.py new file mode 100644 index 0000000000000000000000000000000000000000..ecac81be7e3bdff1dcbac458142ea15bf367a1a1 --- /dev/null +++ b/src/tests/tools/mock_ipm_sdn_ctrl/MockIPMSdnCtrl.py @@ -0,0 +1,192 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +# Mock IPM controller (implements minimal support) + +import functools, json, logging, sys, time, uuid +from typing import Any, Dict, Optional, Tuple +from flask import Flask, jsonify, make_response, request +from flask_restful import Api, Resource + +BIND_ADDRESS = '0.0.0.0' +BIND_PORT = 8444 +IPM_USERNAME = 'xr-user-1' +IPM_PASSWORD = 'xr-user-1' +STR_ENDPOINT = 'https://{:s}:{:s}'.format(str(BIND_ADDRESS), str(BIND_PORT)) +LOG_LEVEL = logging.DEBUG + +CONSTELLATION = { + 'id': 'ofc-constellation', + 'hubModule': {'state': { + 'module': {'moduleName': 'OFC HUB 1', 'trafficMode': 'L1Mode', 'capacity': 100}, + 'endpoints': [{'moduleIf': {'clientIfAid': 'XR-T1'}}, {'moduleIf': {'clientIfAid': 'XR-T4'}}] + }}, + 'leafModules': [ + {'state': { + 'module': {'moduleName': 'OFC LEAF 1', 'trafficMode': 'L1Mode', 'capacity': 100}, + 'endpoints': [{'moduleIf': {'clientIfAid': 'XR-T1'}}] + }}, + {'state': { + 'module': {'moduleName': 'OFC LEAF 2', 'trafficMode': 'L1Mode', 'capacity': 100}, + 'endpoints': [{'moduleIf': {'clientIfAid': 'XR-T1'}}] + }} + ] +} + +CONNECTIONS : Dict[str, Any] = dict() +STATE_NAME_TO_CONNECTION : Dict[str, str] = dict() + +def select_module_state(module_name : str) -> Optional[Dict]: + hub_module_state = CONSTELLATION.get('hubModule', {}).get('state', {}) + if module_name == hub_module_state.get('module', {}).get('moduleName'): return hub_module_state + for leaf_module in CONSTELLATION.get('leafModules', []): + leaf_module_state = leaf_module.get('state', {}) + if module_name == leaf_module_state.get('module', {}).get('moduleName'): return leaf_module_state + return None + +def select_endpoint(module_state : Dict, module_if : str) -> Optional[Dict]: + for endpoint in module_state.get('endpoints', []): + if module_if == endpoint.get('moduleIf', {}).get('clientIfAid'): return endpoint + return None + +def select_module_endpoint(selector : Dict) -> Optional[Tuple[Dict, Dict]]: + selected_module_name = selector['moduleIfSelectorByModuleName']['moduleName'] + selected_module_if = selector['moduleIfSelectorByModuleName']['moduleClientIfAid'] + module_state = select_module_state(selected_module_name) + if module_state is None: return None + return module_state, select_endpoint(module_state, selected_module_if) + +def compose_endpoint(endpoint_selector : Dict) -> Dict: + module, endpoint = select_module_endpoint(endpoint_selector['selector']) + return { + 'href': '/' + str(uuid.uuid4()), + 'state': { + 'moduleIf': { + 'moduleName': module['module']['moduleName'], + 'clientIfAid': endpoint['moduleIf']['clientIfAid'], + }, + 'capacity': module['module']['capacity'], + } + } + +logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") +LOGGER = logging.getLogger(__name__) + +logging.getLogger('werkzeug').setLevel(logging.WARNING) + +def log_request(logger : logging.Logger, response): + timestamp = time.strftime('[%Y-%b-%d %H:%M]') + logger.info('%s %s %s %s %s', timestamp, request.remote_addr, request.method, request.full_path, response.status) + return response + +class OpenIdConnect(Resource): + ACCESS_TOKENS = {} + + def post(self): + if request.content_type != 'application/x-www-form-urlencoded': return make_response('bad content type', 400) + if request.content_length == 0: return make_response('bad content length', 400) + request_form = request.form + if request_form.get('client_id') != 'xr-web-client': return make_response('bad client_id', 403) + if request_form.get('client_secret') != 'xr-web-client': return make_response('bad client_secret', 403) + if request_form.get('grant_type') != 'password': return make_response('bad grant_type', 403) + if request_form.get('username') != IPM_USERNAME: return make_response('bad username', 403) + if request_form.get('password') != IPM_PASSWORD: return make_response('bad password', 403) + access_token = OpenIdConnect.ACCESS_TOKENS.setdefault(IPM_USERNAME, uuid.uuid4()) + reply = {'access_token': access_token, 'expires_in': 86400} + return make_response(jsonify(reply), 200) + +class XrNetworks(Resource): + def get(self): + query = json.loads(request.args.get('q')) + hub_module_name = query.get('hubModule.state.module.moduleName') + if hub_module_name != 'OFC HUB 1': return make_response('unexpected hub module', 404) + return make_response(jsonify([CONSTELLATION]), 200) + +class XrNetworkConnections(Resource): + def get(self): + query = json.loads(request.args.get('q')) + state_name = query.get('state.name') + if state_name is None: + connections = [connection for connection in CONNECTIONS.values()] + else: + connection_uuid = STATE_NAME_TO_CONNECTION.get(state_name) + if connection_uuid is None: return make_response('state name not found', 404) + connection = CONNECTIONS.get(connection_uuid) + if connection is None: return make_response('connection for state name not found', 404) + connections = [connection] + return make_response(jsonify(connections), 200) + + def post(self): + if request.content_type != 'application/json': return make_response('bad content type', 400) + if request.content_length == 0: return make_response('bad content length', 400) + request_json = request.json + if not isinstance(request_json, list): return make_response('content is not list', 400) + reply = [] + for connection in request_json: + connection_uuid = str(uuid.uuid4()) + state_name = connection['name'] + + if state_name is not None: STATE_NAME_TO_CONNECTION[state_name] = connection_uuid + CONNECTIONS[connection_uuid] = { + 'href': '/network-connections/{:s}'.format(str(connection_uuid)), + 'config': { + 'implicitTransportCapacity': connection['implicitTransportCapacity'] + # 'mc': ?? + }, + 'state': { + 'name': state_name, + 'serviceMode': connection['serviceMode'] + # 'outerVID' : ?? + }, + 'endpoints': [ + compose_endpoint(endpoint) + for endpoint in connection['endpoints'] + ] + } + reply.append(CONNECTIONS[connection_uuid]) + return make_response(jsonify(reply), 202) + +class XrNetworkConnection(Resource): + def get(self, connection_uuid : str): + connection = CONNECTIONS.get(connection_uuid) + if connection is None: return make_response('unexpected connection id', 404) + return make_response(jsonify(connection), 200) + + def delete(self, connection_uuid : str): + connection = CONNECTIONS.pop(connection_uuid, None) + if connection is None: return make_response('unexpected connection id', 404) + state_name = connection['state']['name'] + STATE_NAME_TO_CONNECTION.pop(state_name, None) + return make_response(jsonify({}), 202) + +def main(): + LOGGER.info('Starting...') + + app = Flask(__name__) + app.after_request(functools.partial(log_request, LOGGER)) + + api = Api(app) + api.add_resource(OpenIdConnect, '/realms/xr-cm/protocol/openid-connect/token') + api.add_resource(XrNetworks, '/api/v1/xr-networks') + api.add_resource(XrNetworkConnections, '/api/v1/network-connections') + api.add_resource(XrNetworkConnection, '/api/v1/network-connections/') + + LOGGER.info('Listening on {:s}...'.format(str(STR_ENDPOINT))) + app.run(debug=True, host=BIND_ADDRESS, port=BIND_PORT, ssl_context='adhoc') + + LOGGER.info('Bye') + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/tests/tools/mock_ipm_sdn_ctrl/run.sh b/src/tests/tools/mock_ipm_sdn_ctrl/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..2aa78712c58d8cc255b60202d1576de683798d2e --- /dev/null +++ b/src/tests/tools/mock_ipm_sdn_ctrl/run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +python MockIPMSdnCtrl.py diff --git a/src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py b/src/tests/tools/mock_mw_sdn_ctrl/MockMWSdnCtrl.py similarity index 54% rename from src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py rename to src/tests/tools/mock_mw_sdn_ctrl/MockMWSdnCtrl.py index 63be214b671c2ee9b222d92e6f964a4203b8a587..c20dde1b9958fb92e4c6f026fbfe55f9ba348ba1 100644 --- a/src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py +++ b/src/tests/tools/mock_mw_sdn_ctrl/MockMWSdnCtrl.py @@ -25,8 +25,7 @@ # Ref: https://blog.miguelgrinberg.com/post/designing-a-restful-api-using-flask-restful import functools, logging, sys, time -from flask import Flask, abort, request -from flask.json import jsonify +from flask import Flask, abort, jsonify, make_response, request from flask_restful import Api, Resource BIND_ADDRESS = '0.0.0.0' @@ -36,31 +35,51 @@ STR_ENDPOINT = 'https://{:s}:{:s}{:s}'.format(str(BIND_ADDRESS), str(BIND_PORT), LOG_LEVEL = logging.DEBUG NETWORK_NODES = [ - {'node-id': '172.18.0.1', 'ietf-network-topology:termination-point': [ - {'tp-id': '172.18.0.1:1', 'ietf-te-topology:te': {'name': 'ethernet'}}, - {'tp-id': '172.18.0.1:2', 'ietf-te-topology:te': {'name': 'antena' }}, + {'node-id': '192.168.27.139', 'ietf-network-topology:termination-point': [ + {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, - {'node-id': '172.18.0.2', 'ietf-network-topology:termination-point': [ - {'tp-id': '172.18.0.2:1', 'ietf-te-topology:te': {'name': 'ethernet'}}, - {'tp-id': '172.18.0.2:2', 'ietf-te-topology:te': {'name': 'antena' }}, + {'node-id': '192.168.27.140', 'ietf-network-topology:termination-point': [ + {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, - {'node-id': '172.18.0.3', 'ietf-network-topology:termination-point': [ - {'tp-id': '172.18.0.3:1', 'ietf-te-topology:te': {'name': 'ethernet'}}, - {'tp-id': '172.18.0.3:2', 'ietf-te-topology:te': {'name': 'antena' }}, + {'node-id': '192.168.27.141', 'ietf-network-topology:termination-point': [ + {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]}, - {'node-id': '172.18.0.4', 'ietf-network-topology:termination-point': [ - {'tp-id': '172.18.0.4:1', 'ietf-te-topology:te': {'name': 'ethernet'}}, - {'tp-id': '172.18.0.4:2', 'ietf-te-topology:te': {'name': 'antena' }}, + {'node-id': '192.168.27.142', 'ietf-network-topology:termination-point': [ + {'tp-id': '1', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '2', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '3', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '4', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '5', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '6', 'ietf-te-topology:te': {'name': 'ethernet'}}, + {'tp-id': '10', 'ietf-te-topology:te': {'name': 'antena' }}, ]} ] NETWORK_LINKS = [ - { - 'source' : {'source-node': '172.18.0.1', 'source-tp': '172.18.0.1:2'}, - 'destination': {'dest-node' : '172.18.0.2', 'dest-tp' : '172.18.0.2:2'}, + { 'link-id' : '192.168.27.139:10--192.168.27.140:10', + 'source' : {'source-node': '192.168.27.139', 'source-tp': '10'}, + 'destination': {'dest-node' : '192.168.27.140', 'dest-tp' : '10'}, }, - { - 'source' : {'source-node': '172.18.0.3', 'source-tp': '172.18.0.3:2'}, - 'destination': {'dest-node' : '172.18.0.4', 'dest-tp' : '172.18.0.4:2'}, + { 'link-id' : '192.168.27.141:10--192.168.27.142:10', + 'source' : {'source-node': '192.168.27.141', 'source-tp': '10'}, + 'destination': {'dest-node' : '192.168.27.142', 'dest-tp' : '10'}, } ] NETWORK_SERVICES = {} @@ -77,21 +96,22 @@ def log_request(logger : logging.Logger, response): return response class Health(Resource): - def get(self): return jsonify({}) + def get(self): + return make_response(jsonify({}), 200) class Network(Resource): def get(self, network_uuid : str): if network_uuid != 'SIAE-ETH-TOPOLOGY': abort(400) network = {'node': NETWORK_NODES, 'ietf-network-topology:link': NETWORK_LINKS} - return jsonify({'ietf-network:network': network}) + return make_response(jsonify({'ietf-network:network': network}), 200) class Services(Resource): def get(self): services = [service for service in NETWORK_SERVICES.values()] - return jsonify({'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': services}}) + return make_response(jsonify({'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': services}}), 200) def post(self): - json_request = request.json + json_request = request.get_json() if not json_request: abort(400) if not isinstance(json_request, dict): abort(400) if 'etht-svc-instances' not in json_request: abort(400) @@ -101,12 +121,12 @@ class Services(Resource): svc_data = json_services[0] etht_svc_name = svc_data['etht-svc-name'] NETWORK_SERVICES[etht_svc_name] = svc_data - return jsonify({}), 201 + return make_response(jsonify({}), 201) class DelServices(Resource): def delete(self, service_uuid : str): NETWORK_SERVICES.pop(service_uuid, None) - return jsonify({}), 204 + return make_response(jsonify({}), 204) def main(): LOGGER.info('Starting...') diff --git a/src/tests/tools/mock_sdn_ctrl/README.md b/src/tests/tools/mock_mw_sdn_ctrl/README.md similarity index 94% rename from src/tests/tools/mock_sdn_ctrl/README.md rename to src/tests/tools/mock_mw_sdn_ctrl/README.md index d8a6fe6b279553e54f13792cbf12f15b2b380dc2..8568c89ed22e2010bc565e28dc42821181dd6e0a 100644 --- a/src/tests/tools/mock_sdn_ctrl/README.md +++ b/src/tests/tools/mock_mw_sdn_ctrl/README.md @@ -12,8 +12,8 @@ Follow the steps below to perform the test: ## 1. Deploy TeraFlowSDN controller and the scenario Deploy the test scenario "microwave_deploy.sh": ```bash -source src/tests/tools/microwave_deploy.sh -./deploy.sh +source src/tests/tools/mock_mw_sdn_ctrl/scenario/microwave_deploy.sh +./deploy/all.sh ``` ## 2. Install requirements and run the Mock MicroWave SDN controller @@ -27,7 +27,7 @@ pip install Flask==2.1.3 Flask-RESTful==0.3.9 Run the Mock MicroWave SDN Controller as follows: ```bash -python src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py +python src/tests/tools/mock_mw_sdn_ctrl/MockMWSdnCtrl.py ``` ## 3. Deploy the test descriptors diff --git a/src/tests/tools/mock_mw_sdn_ctrl/run.sh b/src/tests/tools/mock_mw_sdn_ctrl/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..415fc1751f132478889fba2e0ec1f5da742e23f1 --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +python MockMWSdnCtrl.py diff --git a/src/tests/tools/mock_sdn_ctrl/microwave_deploy.sh b/src/tests/tools/mock_mw_sdn_ctrl/scenario/microwave_deploy.sh similarity index 100% rename from src/tests/tools/mock_sdn_ctrl/microwave_deploy.sh rename to src/tests/tools/mock_mw_sdn_ctrl/scenario/microwave_deploy.sh diff --git a/src/tests/tools/mock_sdn_ctrl/network_descriptors.json b/src/tests/tools/mock_mw_sdn_ctrl/scenario/network_descriptors.json similarity index 100% rename from src/tests/tools/mock_sdn_ctrl/network_descriptors.json rename to src/tests/tools/mock_mw_sdn_ctrl/scenario/network_descriptors.json diff --git a/src/tests/tools/mock_sdn_ctrl/service_descriptor.json b/src/tests/tools/mock_mw_sdn_ctrl/scenario/service_descriptor.json similarity index 100% rename from src/tests/tools/mock_sdn_ctrl/service_descriptor.json rename to src/tests/tools/mock_mw_sdn_ctrl/scenario/service_descriptor.json diff --git a/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/Dockerfile b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..ad214b97c091bf82a8bfe5c0ce4183d0bae2766e --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/Dockerfile @@ -0,0 +1,35 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 + +# Set Python to show logs as they occur +ENV PYTHONUNBUFFERED=0 + +# 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 + +# Create component sub-folder, and copy content +RUN mkdir -p /var/teraflow/mock_mw_sdn_ctrl +WORKDIR /var/teraflow/mock_mw_sdn_ctrl +COPY . . + +# Get specific Python packages +RUN pip-compile --quiet --output-file=requirements.txt requirements.in +RUN python3 -m pip install -r requirements.txt + +# Start the service +ENTRYPOINT ["python", "MockMWSdnCtrl.py"] diff --git a/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/build.sh b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..4df315cec178cef13eaa059a739bc22efc011d4d --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +docker build -t mock-mw-sdn-ctrl:test -f Dockerfile . +docker tag mock-mw-sdn-ctrl:test localhost:32000/tfs/mock-mw-sdn-ctrl:test +docker push localhost:32000/tfs/mock-mw-sdn-ctrl:test diff --git a/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/deploy.sh b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/deploy.sh new file mode 100755 index 0000000000000000000000000000000000000000..ded232e5c50f8cd5ed448ec0193f58c43626f4ad --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/deploy.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +kubectl delete namespace mocks +kubectl --namespace mocks apply -f mock-mw-sdn-ctrl.yaml diff --git a/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/mock-mw-sdn-ctrl.yaml b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/mock-mw-sdn-ctrl.yaml new file mode 100644 index 0000000000000000000000000000000000000000..05b89f949e940ae55ad592b9cc0e82a6eea2e343 --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/mock-mw-sdn-ctrl.yaml @@ -0,0 +1,46 @@ +kind: Namespace +apiVersion: v1 +metadata: + name: mocks +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mock-mw-sdn-ctrl +spec: + selector: + matchLabels: + app: mock-mw-sdn-ctrl + replicas: 1 + template: + metadata: + labels: + app: mock-mw-sdn-ctrl + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: localhost:32000/tfs/mock-mw-sdn-ctrl:test + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8443 + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: 700m + memory: 1024Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: mock-mw-sdn-ctrl +spec: + type: ClusterIP + selector: + app: mock-mw-sdn-ctrl + ports: + - name: https + port: 8443 + targetPort: 8443 diff --git a/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/requirements.in b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/requirements.in new file mode 100644 index 0000000000000000000000000000000000000000..f4bc191062c8385b2eeb003832b284313305c795 --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/ssl_not_working/requirements.in @@ -0,0 +1,21 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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. + +cryptography==39.0.1 +pyopenssl==23.0.0 +Flask==2.1.3 +Flask-HTTPAuth==4.5.0 +Flask-RESTful==0.3.9 +jsonschema==4.4.0 +requests==2.27.1 diff --git a/src/tests/tools/mock_mw_sdn_ctrl/test_mw.py b/src/tests/tools/mock_mw_sdn_ctrl/test_mw.py new file mode 100644 index 0000000000000000000000000000000000000000..0329d30ad234398200c0fe29aac46f72f5a2e924 --- /dev/null +++ b/src/tests/tools/mock_mw_sdn_ctrl/test_mw.py @@ -0,0 +1,84 @@ +import json, logging, requests +from requests.auth import HTTPBasicAuth +from typing import Optional + +LOGGER = logging.getLogger(__name__) + +HTTP_OK_CODES = { + 200, # OK + 201, # Created + 202, # Accepted + 204, # No Content +} + +def create_connectivity_service( + root_url, uuid, node_id_src, tp_id_src, node_id_dst, tp_id_dst, vlan_id, + auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None +): + + url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc'.format(root_url) + headers = {'content-type': 'application/json'} + data = { + 'etht-svc-instances': [ + { + 'etht-svc-name': uuid, + 'etht-svc-type': 'ietf-eth-tran-types:p2p-svc', + 'etht-svc-end-points': [ + { + 'etht-svc-access-points': [ + {'access-node-id': node_id_src, 'access-ltp-id': tp_id_src, 'access-point-id': '1'} + ], + 'outer-tag': {'vlan-value': vlan_id, 'tag-type': 'ietf-eth-tran-types:classify-c-vlan'}, + 'etht-svc-end-point-name': '{:s}:{:s}'.format(str(node_id_src), str(tp_id_src)), + 'service-classification-type': 'ietf-eth-tran-types:vlan-classification' + }, + { + 'etht-svc-access-points': [ + {'access-node-id': node_id_dst, 'access-ltp-id': tp_id_dst, 'access-point-id': '2'} + ], + 'outer-tag': {'vlan-value': vlan_id, 'tag-type': 'ietf-eth-tran-types:classify-c-vlan'}, + 'etht-svc-end-point-name': '{:s}:{:s}'.format(str(node_id_dst), str(tp_id_dst)), + 'service-classification-type': 'ietf-eth-tran-types:vlan-classification' + } + ] + } + ] + } + results = [] + try: + LOGGER.info('Connectivity service {:s}: {:s}'.format(str(uuid), str(data))) + response = requests.post( + url=url, data=json.dumps(data), timeout=timeout, headers=headers, verify=False, auth=auth) + LOGGER.info('Microwave Driver response: {:s}'.format(str(response))) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Exception creating ConnectivityService(uuid={:s}, data={:s})'.format(str(uuid), str(data))) + results.append(e) + else: + if response.status_code not in HTTP_OK_CODES: + msg = 'Could not create ConnectivityService(uuid={:s}, data={:s}). status_code={:s} reply={:s}' + LOGGER.error(msg.format(str(uuid), str(data), str(response.status_code), str(response))) + results.append(response.status_code in HTTP_OK_CODES) + return results + +def delete_connectivity_service(root_url, uuid, auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None): + url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc/etht-svc-instances={:s}' + url = url.format(root_url, uuid) + results = [] + try: + response = requests.delete(url=url, timeout=timeout, verify=False, auth=auth) + except Exception as e: # pylint: disable=broad-except + LOGGER.exception('Exception deleting ConnectivityService(uuid={:s})'.format(str(uuid))) + results.append(e) + else: + if response.status_code not in HTTP_OK_CODES: + msg = 'Could not delete ConnectivityService(uuid={:s}). status_code={:s} reply={:s}' + LOGGER.error(msg.format(str(uuid), str(response.status_code), str(response))) + results.append(response.status_code in HTTP_OK_CODES) + return results + +if __name__ == '__main__': + ROOT_URL = 'https://127.0.0.1:8443' + SERVICE_UUID = 'my-service' + + create_connectivity_service(ROOT_URL, SERVICE_UUID, '172.18.0.1', '1', '172.18.0.2', '2', 300) + delete_connectivity_service(ROOT_URL, SERVICE_UUID) diff --git a/src/tests/tools/perf_plots/Component_RPC_Methods.py b/src/tests/tools/perf_plots/Component_RPC_Methods.py new file mode 100644 index 0000000000000000000000000000000000000000..7aa3ed304bc7d923a5ba634917fd95c28aea513b --- /dev/null +++ b/src/tests/tools/perf_plots/Component_RPC_Methods.py @@ -0,0 +1,123 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 datetime, re +from typing import Dict, List, Optional, Tuple +from .tools.FileSystem import create_folders +from .tools.HistogramData import HistogramData +from .tools.Plotter import plot_histogram +from .tools.Prometheus import get_prometheus_range, get_prometheus_series_names +from .tools.Histogram import results_to_histograms, save_histograms, unaccumulate_histograms + +##### EXPERIMENT SETTINGS ############################################################################################## + +EXPERIMENT_NAME = 'L2VPN with Emulated' +EXPERIMENT_ID = 'l2vpn-emu' +TIME_START = datetime.datetime(2023, 5, 4, 6, 45, 0, 0, tzinfo=datetime.timezone.utc) +TIME_END = datetime.datetime(2023, 5, 4, 10, 15, 0, 0, tzinfo=datetime.timezone.utc) +TIME_STEP = '1m' +LABEL_FILTERS = {} + +##### ENVIRONMENT SETTINGS ############################################################################################# + +PROM_ADDRESS = '127.0.0.1' +PROM_PORT = 9090 +OUT_FOLDER = 'data/perf/' + +##### PLOT-SPECIFIC CUSTOMIZATIONS ##################################################################################### + +EXPERIMENT_ID += '/component-rpcs' +SERIES_MATCH = 'tfs_.+_rpc_.+_histogram_duration_bucket' +RE_SERIES_NAME = re.compile(r'^tfs_(.+)_rpc_(.+)_histogram_duration_bucket$') +SERIES_LABELS = [] + +SUBSYSTEMS_MAPPING = { + 'context': { + 'context' : 'context', + 'topolog' : 'topology', + 'device' : 'device', + 'endpoint' : 'device', + 'link' : 'link', + 'service' : 'service', + 'slice' : 'slice', + 'policyrule': 'policyrule', + 'connection': 'connection', + } +} + +def get_subsystem(component : str, rpc_method : str) -> Optional[str]: + return next(iter([ + subsystem + for pattern,subsystem in SUBSYSTEMS_MAPPING.get(component, {}).items() + if pattern in rpc_method + ]), None) + +def update_keys(component : str, rpc_method : str) -> Tuple[Tuple, Tuple]: + subsystem = get_subsystem(component, rpc_method) + collection_keys = (component, subsystem) + histogram_keys = (rpc_method,) + return collection_keys, histogram_keys + +def get_plot_specs(folders : Dict[str, str], component : str, subsystem : Optional[str]) -> Tuple[str, str]: + if subsystem is None: + title = '{:s} - RPC Methods [{:s}]'.format(component.title(), EXPERIMENT_NAME) + filepath = '{:s}/{:s}.png'.format(folders['png'], component) + else: + title = '{:s} - RPC Methods - {:s} [{:s}]'.format(component.title(), subsystem.title(), EXPERIMENT_NAME) + filepath = '{:s}/{:s}-{:s}.png'.format(folders['png'], component, subsystem) + return title, filepath + +##### AUTOMATED CODE ################################################################################################### + +def get_series_names(folders : Dict[str, str]) -> List[str]: + series_names = get_prometheus_series_names( + PROM_ADDRESS, PROM_PORT, SERIES_MATCH, TIME_START, TIME_END, + raw_json_filepath='{:s}/_series.json'.format(folders['json']) + ) + return series_names + +def get_histogram_data(series_name : str, folders : Dict[str, str]) -> Dict[Tuple, HistogramData]: + m = RE_SERIES_NAME.match(series_name) + if m is None: + # pylint: disable=broad-exception-raised + raise Exception('Unparsable series name: {:s}'.format(str(series_name))) + extra_labels = m.groups() + results = get_prometheus_range( + PROM_ADDRESS, PROM_PORT, series_name, LABEL_FILTERS, TIME_START, TIME_END, TIME_STEP, + raw_json_filepath='{:s}/_raw_{:s}.json'.format(folders['json'], series_name) + ) + histograms = results_to_histograms(results, SERIES_LABELS, extra_labels=extra_labels) + unaccumulate_histograms(histograms, process_bins=True, process_timestamps=False) + save_histograms(histograms, folders['csv']) + return histograms + +def main() -> None: + histograms_collection : Dict[Tuple, Dict[Tuple, HistogramData]] = dict() + + folders = create_folders(OUT_FOLDER, EXPERIMENT_ID) + series_names = get_series_names(folders) + + for series_name in series_names: + histograms = get_histogram_data(series_name, folders) + for histogram_keys, histogram_data in histograms.items(): + collection_keys,histogram_keys = update_keys(*histogram_keys) + histograms = histograms_collection.setdefault(collection_keys, dict()) + histograms[histogram_keys] = histogram_data + + for histogram_keys,histograms in histograms_collection.items(): + title, filepath = get_plot_specs(folders, *histogram_keys) + plot_histogram(histograms, filepath, title=title) + +if __name__ == '__main__': + main() diff --git a/src/tests/tools/perf_plots/Device_Driver_Details.py b/src/tests/tools/perf_plots/Device_Driver_Details.py new file mode 100644 index 0000000000000000000000000000000000000000..24b287cc826872f48acc8c24c4f51ecd7ba8c676 --- /dev/null +++ b/src/tests/tools/perf_plots/Device_Driver_Details.py @@ -0,0 +1,101 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 datetime, re +from typing import Dict, List, Optional, Tuple +from .tools.FileSystem import create_folders +from .tools.HistogramData import HistogramData +from .tools.Plotter import plot_histogram +from .tools.Prometheus import get_prometheus_range, get_prometheus_series_names +from .tools.Histogram import results_to_histograms, save_histograms, unaccumulate_histograms + +##### EXPERIMENT SETTINGS ############################################################################################## + +EXPERIMENT_NAME = 'L2VPN with Emulated' +EXPERIMENT_ID = 'l2vpn-emu' +TIME_START = datetime.datetime(2023, 5, 4, 6, 45, 0, 0, tzinfo=datetime.timezone.utc) +TIME_END = datetime.datetime(2023, 5, 4, 10, 15, 0, 0, tzinfo=datetime.timezone.utc) +TIME_STEP = '1m' +LABEL_FILTERS = { + #'driver': 'emulated', + #'operation': 'configure_device', # add_device / configure_device + #'step': 'get_device', +} + +##### ENVIRONMENT SETTINGS ############################################################################################# + +PROM_ADDRESS = '127.0.0.1' +PROM_PORT = 9090 +OUT_FOLDER = 'data/perf/' + +##### PLOT-SPECIFIC CUSTOMIZATIONS ##################################################################################### + +EXPERIMENT_ID += '/dev-drv-details' +SERIES_MATCH = 'tfs_device_execution_details_histogram_duration_bucket' +RE_SERIES_NAME = re.compile(r'^tfs_device_execution_details_histogram_duration_bucket$') +SERIES_LABELS = ['driver', 'operation', 'step'] + +def update_keys(driver : str, operation : str, step : str) -> Tuple[Tuple, Tuple]: + collection_keys = (driver, operation) + histogram_keys = (step,) + return collection_keys, histogram_keys + +def get_plot_specs(folders : Dict[str, str], driver : str, operation : str) -> Tuple[str, str]: + title = 'Device Driver - {:s} - {:s}'.format(driver.title(), operation.replace('_', '').title()) + filepath = '{:s}/{:s}-{:s}.png'.format(folders['png'], driver, operation) + return title, filepath + +##### AUTOMATED CODE ################################################################################################### + +def get_series_names(folders : Dict[str, str]) -> List[str]: + series_names = get_prometheus_series_names( + PROM_ADDRESS, PROM_PORT, SERIES_MATCH, TIME_START, TIME_END, + raw_json_filepath='{:s}/_series.json'.format(folders['json']) + ) + return series_names + +def get_histogram_data(series_name : str, folders : Dict[str, str]) -> Dict[Tuple, HistogramData]: + m = RE_SERIES_NAME.match(series_name) + if m is None: + # pylint: disable=broad-exception-raised + raise Exception('Unparsable series name: {:s}'.format(str(series_name))) + extra_labels = m.groups() + results = get_prometheus_range( + PROM_ADDRESS, PROM_PORT, series_name, LABEL_FILTERS, TIME_START, TIME_END, TIME_STEP, + raw_json_filepath='{:s}/_raw_{:s}.json'.format(folders['json'], series_name) + ) + histograms = results_to_histograms(results, SERIES_LABELS, extra_labels=extra_labels) + unaccumulate_histograms(histograms, process_bins=True, process_timestamps=False) + save_histograms(histograms, folders['csv']) + return histograms + +def main() -> None: + histograms_collection : Dict[Tuple, Dict[Tuple, HistogramData]] = dict() + + folders = create_folders(OUT_FOLDER, EXPERIMENT_ID) + series_names = get_series_names(folders) + + for series_name in series_names: + histograms = get_histogram_data(series_name, folders) + for histogram_keys, histogram_data in histograms.items(): + collection_keys,histogram_keys = update_keys(*histogram_keys) + histograms = histograms_collection.setdefault(collection_keys, dict()) + histograms[histogram_keys] = histogram_data + + for histogram_keys,histograms in histograms_collection.items(): + title, filepath = get_plot_specs(folders, *histogram_keys) + plot_histogram(histograms, filepath, title=title) + +if __name__ == '__main__': + main() diff --git a/src/tests/tools/perf_plots/Device_Driver_Methods.py b/src/tests/tools/perf_plots/Device_Driver_Methods.py new file mode 100644 index 0000000000000000000000000000000000000000..a92bd13747f6c7c6aa861c989e9f1199ef3870d0 --- /dev/null +++ b/src/tests/tools/perf_plots/Device_Driver_Methods.py @@ -0,0 +1,99 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 datetime, re +from typing import Dict, List, Tuple +from .tools.FileSystem import create_folders +from .tools.HistogramData import HistogramData +from .tools.Plotter import plot_histogram +from .tools.Prometheus import get_prometheus_range, get_prometheus_series_names +from .tools.Histogram import results_to_histograms, save_histograms, unaccumulate_histograms + +##### EXPERIMENT SETTINGS ############################################################################################## + +EXPERIMENT_NAME = 'L2VPN with Emulated' +EXPERIMENT_ID = 'l2vpn-emu' +TIME_START = datetime.datetime(2023, 5, 4, 6, 45, 0, 0, tzinfo=datetime.timezone.utc) +TIME_END = datetime.datetime(2023, 5, 4, 10, 15, 0, 0, tzinfo=datetime.timezone.utc) +TIME_STEP = '1m' +LABEL_FILTERS = { + #'driver': 'emulated', +} + +##### ENVIRONMENT SETTINGS ############################################################################################# + +PROM_ADDRESS = '127.0.0.1' +PROM_PORT = 9090 +OUT_FOLDER = 'data/perf/' + +##### PLOT-SPECIFIC CUSTOMIZATIONS ##################################################################################### + +EXPERIMENT_ID += '/dev-drv-methods' +SERIES_MATCH = 'tfs_device_driver_.+_histogram_duration_bucket' +RE_SERIES_NAME = re.compile(r'^tfs_device_driver_(.+)_histogram_duration_bucket$') +SERIES_LABELS = ['driver'] + +def update_keys(driver : str, method : str) -> Tuple[Tuple, Tuple]: + collection_keys = (driver,) + histogram_keys = (method,) + return collection_keys, histogram_keys + +def get_plot_specs(folders : Dict[str, str], driver : str) -> Tuple[str, str]: + title = 'Device Driver - {:s}'.format(driver.title()) + filepath = '{:s}/{:s}.png'.format(folders['png'], driver) + return title, filepath + +##### AUTOMATED CODE ################################################################################################### + +def get_series_names(folders : Dict[str, str]) -> List[str]: + series_names = get_prometheus_series_names( + PROM_ADDRESS, PROM_PORT, SERIES_MATCH, TIME_START, TIME_END, + raw_json_filepath='{:s}/_series.json'.format(folders['json']) + ) + return series_names + +def get_histogram_data(series_name : str, folders : Dict[str, str]) -> Dict[Tuple, HistogramData]: + m = RE_SERIES_NAME.match(series_name) + if m is None: + # pylint: disable=broad-exception-raised + raise Exception('Unparsable series name: {:s}'.format(str(series_name))) + extra_labels = m.groups() + results = get_prometheus_range( + PROM_ADDRESS, PROM_PORT, series_name, LABEL_FILTERS, TIME_START, TIME_END, TIME_STEP, + raw_json_filepath='{:s}/_raw_{:s}.json'.format(folders['json'], series_name) + ) + histograms = results_to_histograms(results, SERIES_LABELS, extra_labels=extra_labels) + unaccumulate_histograms(histograms, process_bins=True, process_timestamps=False) + save_histograms(histograms, folders['csv']) + return histograms + +def main() -> None: + histograms_collection : Dict[Tuple, Dict[Tuple, HistogramData]] = dict() + + folders = create_folders(OUT_FOLDER, EXPERIMENT_ID) + series_names = get_series_names(folders) + + for series_name in series_names: + histograms = get_histogram_data(series_name, folders) + for histogram_keys, histogram_data in histograms.items(): + collection_keys,histogram_keys = update_keys(*histogram_keys) + histograms = histograms_collection.setdefault(collection_keys, dict()) + histograms[histogram_keys] = histogram_data + + for histogram_keys,histograms in histograms_collection.items(): + title, filepath = get_plot_specs(folders, *histogram_keys) + plot_histogram(histograms, filepath, title=title) + +if __name__ == '__main__': + main() diff --git a/src/tests/tools/perf_plots/README.md b/src/tests/tools/perf_plots/README.md new file mode 100644 index 0000000000000000000000000000000000000000..14dcb1c9508a1b63c62ae84aef4abe3e17589ef7 --- /dev/null +++ b/src/tests/tools/perf_plots/README.md @@ -0,0 +1,29 @@ +# Tool: Perf Plots Generator: + +Simple tool to gather performance data from Prometheus and produce histogram plots. + +## Example: + +- Ensure your MicroK8s includes the monitoring addon and your deployment specs the service monitors. + +- Deploy TeraFlowSDN controller with your specific settings: +```(bash) +cd ~/tfs-ctrl +source my_deploy.sh +./deploy.sh +``` + +- Execute the test you want to meter. + +- Select the appropriate script: + - Device_Driver_Methods : To report Device Driver Methods + - Device_Driver_Details : To report Device Add/Configure Details + - Service_Handler_Methods : To report Service Handler Methods + - Component_RPC_Methods : To report Component RPC Methods + +- Tune the experiment settings + +- Execute the report script: +```(bash) +PYTHONPATH=./src python -m tests.tools.perf_plots. --> - \ No newline at end of file + diff --git a/src/webui/service/templates/device/detail.html b/src/webui/service/templates/device/detail.html index 1b4b43f5ad12956ae8bb2b1a843ce5e57ef29a2c..4d33578e2532c26b4062565bd2cbb52106773a1a 100644 --- a/src/webui/service/templates/device/detail.html +++ b/src/webui/service/templates/device/detail.html @@ -47,6 +47,7 @@ UUID: {{ device.device_id.device_uuid.uuid }}
Name: {{ device.name }}
Type: {{ device.device_type }}
+ Controller: {{ device.controller_id.device_uuid.uuid }}
Status: {{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }}
Drivers:
    diff --git a/src/webui/service/templates/js/topology.js b/src/webui/service/templates/js/topology.js index 50486d2a6826fedace55f7a62592fa083e7256a6..1b34f2b2c737c96ef18e925bd76ef28451f4120f 100644 --- a/src/webui/service/templates/js/topology.js +++ b/src/webui/service/templates/js/topology.js @@ -31,8 +31,8 @@ const margin = {top: 5, right: 5, bottom: 5, left: 5}; const icon_width = 40; const icon_height = 40; -width = 1000 - margin.left - margin.right; -height = 600 - margin.top - margin.bottom; +width = 1400 - margin.left - margin.right; +height = 800 - margin.top - margin.bottom; //function handleZoom(e) { // console.dir(e); @@ -70,11 +70,21 @@ var simulation = d3.forceSimulation(); // 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 = svg.append("g").attr("class", "links")//.style('stroke', '#aaa') .selectAll("line") .data(data.links) .enter() - .append("line"); + .append("line") + .attr("opacity", 1) + .attr("stroke", function(l) { + return l.name.toLowerCase().includes('mgmt') ? '#AAAAAA' : '#555555'; + }) + .attr("stroke-width", function(l) { + return l.name.toLowerCase().includes('mgmt') ? 1 : 2; + }) + .attr("stroke-dasharray", function(l) { + return l.name.toLowerCase().includes('mgmt') ? "5,5" : "0"; + }); node = svg.append("g").attr("class", "devices").attr('r', 20).style('fill', '#69b3a2') .selectAll("circle") .data(data.devices) @@ -93,9 +103,9 @@ d3.json("{{ url_for('main.topology') }}", function(data) { link.append("title").text(function(l) { return l.name; }); // link style - link - .attr("stroke-width", forceProperties.link.enabled ? 2 : 1) - .attr("opacity", forceProperties.link.enabled ? 1 : 0); + //link + // .attr("stroke-width", forceProperties.link.enabled ? 2 : 1) + // .attr("opacity", forceProperties.link.enabled ? 1 : 0); // set up the simulation and event to update locations after each tick simulation.nodes(data.devices); diff --git a/src/webui/service/templates/link/detail.html b/src/webui/service/templates/link/detail.html index acac4a55392c2bf7f6261707ae1627a486affd10..8ca7faee3e1871d11b819c6ca95668e654041f8c 100644 --- a/src/webui/service/templates/link/detail.html +++ b/src/webui/service/templates/link/detail.html @@ -13,58 +13,92 @@ See the License for the specific language governing permissions and limitations under the License. --> - {% extends 'base.html' %} - - {% block content %} -

    Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})

    -
    -
    - -
    -
    -
    -
    -
    - UUID: {{ link.link_id.link_uuid.uuid }}
    - Name: {{ link.name }}
    -
    -
    - - - - - - - - - - {% for endpoint in link.link_endpoint_ids %} - - - - - - {% endfor %} - -
    Endpoint UUIDDeviceEndpoint Type
    - {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }} - - - {{ device_names.get(endpoint.device_id.device_uuid.uuid, endpoint.device_id.device_uuid.uuid) }} - - - - - - - {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, ('', '-'))[1] }} -
    +{% extends 'base.html' %} + +{% block content %} +

    Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})

    +
    +
    + +
    +
    + + +
    +
    + +
    +
    +
    + UUID: {{ link.link_id.link_uuid.uuid }}
    + Name: {{ link.name }}
    +
    +
    + + + + + + + + + + + {% for endpoint in link.link_endpoint_ids %} + + + + + + + {% endfor %} + +
    Endpoint UUIDNameDeviceEndpoint Type
    + {{ endpoint.endpoint_uuid.uuid }} + + {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }} + + + {{ device_names.get(endpoint.device_id.device_uuid.uuid, endpoint.device_id.device_uuid.uuid) }} + + + + + + + {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, ('', '-'))[1] }} +
    +
    +
    + + + + - {% endblock %} - \ No newline at end of file +{% endblock %} diff --git a/src/webui/service/templates/load_gen/home.html b/src/webui/service/templates/load_gen/home.html index d58f42601925ca438ab9d9f20b32f94960b5cada..cec0a38dba2b4b31d4d07d391e4ce211f0c7ac76 100644 --- a/src/webui/service/templates/load_gen/home.html +++ b/src/webui/service/templates/load_gen/home.html @@ -53,6 +53,21 @@

    +
    + {{ form.num_released.label(class="col-sm-2 col-form-label") }} +
    + {% if form.num_released.errors %} + {{ form.num_released(class="form-control is-invalid") }} +
    + {% for error in form.num_released.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.num_released(class="form-control") }} + {% endif %} +
    +
    +
    +
    Service Types:
    @@ -68,6 +83,36 @@

    +
    + {{ form.device_regex.label(class="col-sm-2 col-form-label") }} +
    + {% if form.device_regex.errors %} + {{ form.device_regex(class="form-control is-invalid") }} +
    + {% for error in form.device_regex.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.device_regex(class="form-control") }} + {% endif %} +
    +
    +
    + +
    + {{ form.endpoint_regex.label(class="col-sm-2 col-form-label") }} +
    + {% if form.endpoint_regex.errors %} + {{ form.endpoint_regex(class="form-control is-invalid") }} +
    + {% for error in form.endpoint_regex.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.endpoint_regex(class="form-control") }} + {% endif %} +
    +
    +
    +
    {{ form.offered_load.label(class="col-sm-2 col-form-label") }}
    @@ -113,6 +158,66 @@

    +
    + {{ form.availability.label(class="col-sm-2 col-form-label") }} +
    + {% if form.availability.errors %} + {{ form.availability(class="form-control is-invalid") }} +
    + {% for error in form.availability.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.availability(class="form-control") }} + {% endif %} +
    +
    +
    + +
    + {{ form.capacity_gbps.label(class="col-sm-2 col-form-label") }} +
    + {% if form.capacity_gbps.errors %} + {{ form.capacity_gbps(class="form-control is-invalid") }} +
    + {% for error in form.capacity_gbps.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.capacity_gbps(class="form-control") }} + {% endif %} +
    +
    +
    + +
    + {{ form.e2e_latency_ms.label(class="col-sm-2 col-form-label") }} +
    + {% if form.e2e_latency_ms.errors %} + {{ form.e2e_latency_ms(class="form-control is-invalid") }} +
    + {% for error in form.e2e_latency_ms.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.e2e_latency_ms(class="form-control") }} + {% endif %} +
    +
    +
    + +
    + {{ form.max_workers.label(class="col-sm-2 col-form-label") }} +
    + {% if form.max_workers.errors %} + {{ form.max_workers(class="form-control is-invalid") }} +
    + {% for error in form.max_workers.errors %}{{ error }}{% endfor %} +
    + {% else %} + {{ form.max_workers(class="form-control") }} + {% endif %} +
    +
    +
    +
    {{ form.do_teardown }} {{ form.do_teardown.label(class="col-sm-3 col-form-label") }}
    diff --git a/src/webui/service/templates/policy_rule/home.html b/src/webui/service/templates/policy_rule/home.html new file mode 100644 index 0000000000000000000000000000000000000000..c63807a6aad046d8312a07bbb412c541c5e06bc8 --- /dev/null +++ b/src/webui/service/templates/policy_rule/home.html @@ -0,0 +1,84 @@ + + +{% extends 'base.html' %} + +{% block content %} +

    Policy Rules

    + +
    +
    + {{ policy_rules | length }} policy rules found in context {{ session['context_uuid'] }} +
    +
    + + + + + + + + + + + + + + + + + + + + {% if policy_rules %} + {% for policy_rule in policy_rules %} + {% if policy_rule.WhichOneof('policy_rule') == 'device' %} + + + + + + + + + + + + + {% elif policy_rule.WhichOneof('policy_rule') == 'service' %} + + + + + + + + + + + + + {% else %} + + {% endif %} + {% endfor %} + {% else %} + + {% endif %} + +
    UUIDKindPriorityConditionOperatorActionServiceDevicesStateMessageExtra
    {{ policy_rule.device.policyRuleBasic.policyRuleId.uuid }}{{ policy_rule.WhichOneof('policy_rule') }}{{ policy_rule.device.policyRuleBasic.priority }}{{ policy_rule.device.policyRuleBasic.conditionList }}{{ policy_rule.device.policyRuleBasic.booleanOperator }}{{ policy_rule.device.policyRuleBasic.actionList }}-{{ policy_rule.device.deviceList }}{{ prse.Name(policy_rule.device.policyRuleBasic.policyRuleState.policyRuleState).replace('POLICY_', '') }}{{ policy_rule.device.policyRuleBasic.policyRuleState.policyRuleStateMessage }}
    {{ policy_rule.service.policyRuleBasic.policyRuleId.uuid }}{{ policy_rule.WhichOneof('policy_rule') }}{{ policy_rule.service.policyRuleBasic.priority }}{{ policy_rule.service.policyRuleBasic.conditionList }}{{ policy_rule.service.policyRuleBasic.booleanOperator }}{{ policy_rule.service.policyRuleBasic.actionList }}{{ policy_rule.service.serviceId }}{{ policy_rule.service.deviceList }}{{ prse.Name(policy_rule.service.policyRuleBasic.policyRuleState.policyRuleState).replace('POLICY_', '') }}{{ policy_rule.service.policyRuleBasic.policyRuleState.policyRuleStateMessage }}
    Unsupported policy rule type {{ policy_rule.WhichOneof('policy_rule') }}
    No policy rule found
    + +{% endblock %} diff --git a/src/webui/service/templates/service/add-xr.html b/src/webui/service/templates/service/add-xr.html new file mode 100644 index 0000000000000000000000000000000000000000..36fe132caa7df1e3c72fa09ff2c39e2a92a7a357 --- /dev/null +++ b/src/webui/service/templates/service/add-xr.html @@ -0,0 +1,105 @@ + + +{% extends 'base.html' %} + +{% block content %} + + +

    Add XR Service

    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + + +
    +{% endblock %} diff --git a/src/webui/service/templates/service/detail.html b/src/webui/service/templates/service/detail.html index 1c5335db36deb5f5aef0077106243b61e7935666..9e83f05c4a710b99646e026d7c5794c96aae3d3d 100644 --- a/src/webui/service/templates/service/detail.html +++ b/src/webui/service/templates/service/detail.html @@ -55,6 +55,7 @@ Endpoint UUID + Name Device Endpoint Type @@ -62,6 +63,9 @@ {% for endpoint in service.service_endpoint_ids %} + + {{ endpoint.endpoint_uuid.uuid }} + {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }} diff --git a/src/webui/service/templates/service/home.html b/src/webui/service/templates/service/home.html index 6633c977ea63752b916cb220feab80dbf510800b..4e4c1f82f33113402bdc3948b1073a579e2922a3 100644 --- a/src/webui/service/templates/service/home.html +++ b/src/webui/service/templates/service/home.html @@ -25,7 +25,19 @@ Add New Service -
    +
    --> + + + {% if "DEVICEDRIVER_XR" in active_drivers %} + + {% endif %} +
    {{ services | length }} services found in context {{ session['context_uuid'] }}
    diff --git a/src/webui/service/templates/slice/detail.html b/src/webui/service/templates/slice/detail.html index 8f223e44deda37b177a360a51b1e366f680fac27..13b69defeb95f66aba47a4aa78f98631ca8cc367 100644 --- a/src/webui/service/templates/slice/detail.html +++ b/src/webui/service/templates/slice/detail.html @@ -55,6 +55,7 @@ Endpoint UUID + Name Device Endpoint Type @@ -62,6 +63,9 @@ {% for endpoint in slice.slice_endpoint_ids %} + + {{ endpoint.endpoint_uuid.uuid }} + {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }}