diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dac76342a9fdb48247cc171cfdf37fd6b60600ba..713d893cffe4b88cb9b37d64a860f480c9669008 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,28 +14,26 @@ # stages of the cicd pipeline stages: - - dependencies + #- dependencies - build - - test - unit_test - - integ_test - - deploy - - funct_test + #- deploy + #- end2end_test # include the individual .gitlab-ci.yml of each micro-service include: - - local: '/manifests/.gitlab-ci.yml' + #- local: '/manifests/.gitlab-ci.yml' - local: '/src/monitoring/.gitlab-ci.yml' - local: '/src/compute/.gitlab-ci.yml' - local: '/src/context/.gitlab-ci.yml' - local: '/src/device/.gitlab-ci.yml' - local: '/src/service/.gitlab-ci.yml' - - local: '/src/dbscanserving/.gitlab-ci.yml' - - local: '/src/opticalattackmitigator/.gitlab-ci.yml' - - local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml' + #- local: '/src/dbscanserving/.gitlab-ci.yml' + #- local: '/src/opticalattackmitigator/.gitlab-ci.yml' + #- local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml' - local: '/src/automation/.gitlab-ci.yml' - local: '/src/policy/.gitlab-ci.yml' - - local: '/src/webui/.gitlab-ci.yml' + #- local: '/src/webui/.gitlab-ci.yml' #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml' #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml' #- local: '/src/l3_attackmitigator/.gitlab-ci.yml' @@ -43,3 +41,4 @@ include: #- local: '/src/interdomain/.gitlab-ci.yml' - local: '/src/pathcomp/.gitlab-ci.yml' #- local: '/src/dlt/.gitlab-ci.yml' + - local: '/src/load_generator/.gitlab-ci.yml' diff --git a/.gitlab/issue_templates/bug.md b/.gitlab/issue_templates/bug.md new file mode 100644 index 0000000000000000000000000000000000000000..3e9f22f83364fe8fac5d2c41e37b92c5453b06aa --- /dev/null +++ b/.gitlab/issue_templates/bug.md @@ -0,0 +1,39 @@ +# Reporters + +- name-of-proposer-1 (institution-of-proposer-1) +- name-of-proposer-2 (institution-of-proposer-2) +... + +# Description + +Describe the bug. +If needed, Attach logs and reports to your bug. +If needed, feel free to point external content as references (journal paper, Youtube video, etc.). + +## Deployment environment +- Operating System (include version): +- MicroK8s (include version and add-ons): +- TeraFlowSDN (include release/branch-name/commit-id): + + +## TFS deployment settings +- list of components deployed +- particular configurations you applied +- any other particularity you might find important + +## Sequence of actions that resulted in the bug +- be explicit and enumerate each step. +- if possible, include example calls, request files, descriptor files, etc. + +## Document the explicit error +- include the traceback of the error +- include the log files of the components / scheenshoots of WebUI (attached files) +- if known, include the list of TFS components affected by the bug + +## Expected behaviour +- describe the expected behavior (if you know it) + +# References + +1. [Reference name](https://reference-url) +2. Author1, Author2, Author3, et. al., “My demo using feature,” in Conference-Name Demo Track, 20XX. diff --git a/.gitlab/issue_templates/enhancement.md b/.gitlab/issue_templates/enhancement.md new file mode 100644 index 0000000000000000000000000000000000000000..06ea401cf9bee0a1c46fa7fb3a4fa1ac4372f57c --- /dev/null +++ b/.gitlab/issue_templates/enhancement.md @@ -0,0 +1,20 @@ +# Proposers + +- name-of-proposer-1 (institution-of-proposer-1) +- name-of-proposer-2 (institution-of-proposer-2) +... + +# Description + +Describe your proposal in ~1000 characters. +You can reference external content listed in section "References" as [Ref-1]. + +# Demo or definition of done + +Describe which high level conditions needs to be fulfilled to demonstrate this feature implementation is completed. +You can reference external content (example, demo paper) listed in section "References" as [Ref-2]. + +# References + +1. [Reference name](https://reference-url) +2. Author1, Author2, Author3, et. al., “My demo using feature,” in Conference-Name Demo Track, 20XX. diff --git a/.gitlab/issue_templates/new-feature-with-design.md b/.gitlab/issue_templates/new-feature-with-design.md new file mode 100644 index 0000000000000000000000000000000000000000..ec08771641bcf5193ea4db45581bc85eb1a0a5b9 --- /dev/null +++ b/.gitlab/issue_templates/new-feature-with-design.md @@ -0,0 +1,60 @@ +# Proposers + +- name-of-proposer-1 (institution-of-proposer-1) +- name-of-proposer-2 (institution-of-proposer-2) +... + +# Description + +Describe your proposal in ~1000 characters. +You can reference external content listed in section "References" as [Ref-1]. + +# Demo or definition of done + +Describe which high level conditions needs to be fulfilled to demonstrate this feature implementation is completed. +You can reference external content (example, demo paper) listed in section "References" as [Ref-2]. + +# References + +1. [Reference name](https://reference-url) +2. Author1, Author2, Author3, et. al., “My demo using feature,” in Conference-Name Demo Track, 20XX. + +# Feature Design (for New-Features) + +## Clarifications to Expected Behavior Changes + +Existing component logic and workflows between components that need to be altered to realize this feature. +Remember to justify these changes. +... + +## References + +List of relevant references for this feature. +... + +## Assumptions + +Enumerate the assumptions for this feature, e.g., fix XXX is implemented and merged, specific configurations, specific +components deployed. +... + +## Impacted Components + +List of impacted components: Context, Device, Service, PathComp, Slice, Monitoring, Automation, Policy, Compute, etc. +Just an enumeration, elaboration of impacts is done below. + +## Component1 Impact + +Describe impact (changes) on component1. +... + +## Component2 Impact + +Describe impact (changes) on component2. +... + +## Testing + +Describe test sets (unitary and integration) to be carried out. +This section can include/reference external experiments, demo papers, etc. +... diff --git a/.gitlab/issue_templates/new-feature.md b/.gitlab/issue_templates/new-feature.md new file mode 100644 index 0000000000000000000000000000000000000000..06ea401cf9bee0a1c46fa7fb3a4fa1ac4372f57c --- /dev/null +++ b/.gitlab/issue_templates/new-feature.md @@ -0,0 +1,20 @@ +# Proposers + +- name-of-proposer-1 (institution-of-proposer-1) +- name-of-proposer-2 (institution-of-proposer-2) +... + +# Description + +Describe your proposal in ~1000 characters. +You can reference external content listed in section "References" as [Ref-1]. + +# Demo or definition of done + +Describe which high level conditions needs to be fulfilled to demonstrate this feature implementation is completed. +You can reference external content (example, demo paper) listed in section "References" as [Ref-2]. + +# References + +1. [Reference name](https://reference-url) +2. Author1, Author2, Author3, et. al., “My demo using feature,” in Conference-Name Demo Track, 20XX. diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 670af487313498ad60f8c0fc89029218efe29405..0000000000000000000000000000000000000000 --- a/INSTALL.md +++ /dev/null @@ -1,4 +0,0 @@ -# TeraFlow OS SDN Controller Installation Instructions -Assuming you have a running Kubernetes deployment installed following the instructions provided in [Wiki: Installing Kubernetes on your Linux machine](https://gitlab.com/teraflow-h2020/controller/-/wikis/Installing-Kubernetes-on-your-Linux-machine), the following instructions will let you deploy TeraFlow OS SDN Controller in your local Kubernetes environment. - -Then, follow the instructions in [Wiki: Deploying a TeraFlow OS test instance](https://gitlab.com/teraflow-h2020/controller/-/wikis/Deploying-a-TeraFlow-OS-test-instance) to deploy your instance of TeraFlow OS. diff --git a/README.md b/README.md index 0336b9f6cdb9562ccff27d73f058d6293604de6b..5bfb6d70d947f631e8694b3dcf6c872cf1248ea4 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ -# TeraFlowSDN Controller +# ETSI TeraFlowSDN Controller -[Teraflow H2020 project](https://teraflow-h2020.eu/) - Secured autonomic traffic management for a Tera of SDN Flows +[ETSI OpenSource Group for TeraFlowSDN](https://tfs.etsi.org/) -Branch "master" : [![pipeline status](https://gitlab.com/teraflow-h2020/controller/badges/master/pipeline.svg)](https://gitlab.com/teraflow-h2020/controller/-/commits/master) [![coverage report](https://gitlab.com/teraflow-h2020/controller/badges/master/coverage.svg)](https://gitlab.com/teraflow-h2020/controller/-/commits/master) +Former, [Teraflow H2020 project](https://teraflow-h2020.eu/) - Secured autonomic traffic management for a Tera of SDN Flows -Branch "develop" : [![pipeline status](https://gitlab.com/teraflow-h2020/controller/badges/develop/pipeline.svg)](https://gitlab.com/teraflow-h2020/controller/-/commits/develop) [![coverage report](https://gitlab.com/teraflow-h2020/controller/badges/develop/coverage.svg)](https://gitlab.com/teraflow-h2020/controller/-/commits/develop) +Branch "master" : [![pipeline status](https://labs.etsi.org/rep/tfs/controller/badges/master/pipeline.svg)](https://labs.etsi.org/rep/tfs/controller/-/commits/master) [![coverage report](https://labs.etsi.org/rep/tfs/controller/badges/master/coverage.svg)](https://labs.etsi.org/rep/tfs/controller/-/commits/master) -# Installation Instructions -For devel and upcoming release 2.0, we have prepared the following tutorial: [TeraFlowSDN tutorial](https://gitlab.com/teraflow-h2020/controller/-/tree/develop/tutorial). +Branch "develop" : [![pipeline status](https://labs.etsi.org/rep/tfs/controller/badges/develop/pipeline.svg)](https://labs.etsi.org/rep/tfs/controller/-/commits/develop) [![coverage report](https://labs.etsi.org/rep/tfs/controller/badges/develop/coverage.svg)](https://labs.etsi.org/rep/tfs/controller/-/commits/develop) + +# Installation Instructions and Functional Tests +The [TeraFlowSDN Wiki](https://labs.etsi.org/rep/tfs/controller/-/wikis/home) pages include details on using the ETSI TeraFlowSDN release 2.0. + +The documentation, installation instructions, and description of the functional tests defined to enable experimentation with the ETSI TeraFlowSDN Controller can be found in the Wiki pages diff --git a/clean_testing_environment.sh b/clean_testing_environment.sh index 09bff95d82fe37a86d3a7c6569c6e3d0a00d64db..b9c502ade6f34e3a19ebeafa67c222b10ea3f99d 100755 --- a/clean_testing_environment.sh +++ b/clean_testing_environment.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/common_requirements.in b/common_requirements.in index 772c1115d857664ed113007b89a6f7f9d9c48b99..cb418f0197f1d18980654c8d00102efd191c67dd 100644 --- a/common_requirements.in +++ b/common_requirements.in @@ -1,9 +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. + coverage==6.3 grpcio==1.47.* grpcio-health-checking==1.47.* grpcio-tools==1.47.* +prettytable==3.5.0 prometheus-client==0.13.0 protobuf==3.20.* pytest==6.2.5 pytest-benchmark==3.4.1 python-dateutil==2.8.2 +pytest-depends==1.0.1 diff --git a/coverage/.coveragerc.template b/coverage/.coveragerc.template index e5e634c2c256103b1796d9309a3433ae9f248e70..4421399ca30027e3032001dae64e6fa0b7fa41cb 100644 --- a/coverage/.coveragerc.template +++ b/coverage/.coveragerc.template @@ -1,5 +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. + [run] -data_file = ~/teraflow/controller/coverage/.coverage +data_file = ~/tfs-ctrl/coverage/.coverage source = . omit = */proto/* @@ -12,7 +26,7 @@ exclude_lines = raise\ NotImplementedError [html] -directory = ~/teraflow/controller/coverage/html_report +directory = ~/tfs-ctrl/coverage/html_report [xml] output = ~/teraflow/controller/coverage/report.xml diff --git a/deploy/all.sh b/deploy/all.sh new file mode 100755 index 0000000000000000000000000000000000000000..a99607f5b907c2bd1e1b4b889bef881874a63967 --- /dev/null +++ b/deploy/all.sh @@ -0,0 +1,156 @@ +#!/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 +######################################################################################################################## + + +# ----- TeraFlowSDN ------------------------------------------------------------ + +# If not already set, set the URL of the Docker registry where the images will be uploaded to. +# By default, assume internal MicroK8s registry is used. +export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} + +# If not already set, set the list of components you want to build images for, and deploy. +# By default, only basic components are deployed +export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device monitoring service compute webui"} + +# If not already set, set the tag you want to use for your images. +export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"} + +# If not already set, set the name of the Kubernetes namespace to deploy to. +export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} + +# If not already set, set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS=${TFS_EXTRA_MANIFESTS:-""} + +# If not already set, set the new Grafana admin password +export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"} + +# If not already set, disable skip-build flag. +# If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used. +export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} + + +# ----- CockroachDB ------------------------------------------------------------ + +# If not already set, set the namespace where CockroackDB will be deployed. +export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} + +# If not already set, set the database username to be used by Context. +export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} + +# If not already set, set the database user's password to be used by Context. +export CRDB_PASSWORD=${CRDB_PASSWORD:-"tfs123"} + +# If not already set, set the database name to be used by Context. +export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"} + +# If not already set, set the name of the secret where CockroachDB data and credentials will be stored. +export CRDB_SECRET_NAME=${CRDB_SECRET_NAME:-"crdb-data"} + +# If not already set, set the namespace where the secret containing CockroachDB data and credentials will be stored. +export CRDB_SECRET_NAMESPACE=${CRDB_SECRET_NAMESPACE:-${TFS_K8S_NAMESPACE}} + +# If not already set, set CockroachDB installation mode. Accepted values are: 'single' and 'cluster'. +# "YES", the database pointed by variable CRDB_NAMESPACE will be dropped while +# checking/deploying CockroachDB. +# - If CRDB_DEPLOY_MODE is "single", CockroachDB is deployed in single node mode. It is convenient for +# development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. +# - If CRDB_DEPLOY_MODE is "cluster", CockroachDB is deployed in cluster mode, and an entire CockroachDB cluster +# with 3 replicas and version v22.2 (set by default) will be deployed. It is convenient for production and +# provides scalability features. If you are deploying for production, also read the following link providing +# details on deploying CockroachDB for production environments: +# Ref: https://www.cockroachlabs.com/docs/stable/recommended-production-settings.html +export CRDB_DEPLOY_MODE=${CRDB_DEPLOY_MODE:-"single"} + +# If not already set, disable flag for dropping database if exists. +# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! +# If CRDB_DROP_DATABASE_IF_EXISTS is "YES", the database pointed by variable CRDB_NAMESPACE will be dropped while +# checking/deploying CockroachDB. +export CRDB_DROP_DATABASE_IF_EXISTS=${CRDB_DROP_DATABASE_IF_EXISTS:-""} + +# If not already set, disable flag for re-deploying CockroachDB from scratch. +# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! +# WARNING: THE REDEPLOY MIGHT TAKE FEW MINUTES TO COMPLETE GRACEFULLY IN CLUSTER MODE +# If CRDB_REDEPLOY is "YES", the database will be dropped while checking/deploying CockroachDB. +export CRDB_REDEPLOY=${CRDB_REDEPLOY:-""} + + +# ----- NATS ------------------------------------------------------------------- + +# If not already set, set the namespace where NATS will be deployed. +export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} + +# If not already set, set the name of the secret where NATS data and credentials will be stored. +export NATS_SECRET_NAME=${NATS_SECRET_NAME:-"nats-data"} + +# If not already set, set the namespace where the secret containing NATS data and credentials will be stored. +export NATS_SECRET_NAMESPACE=${NATS_SECRET_NAMESPACE:-${TFS_K8S_NAMESPACE}} + +# 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. +export NATS_REDEPLOY=${NATS_REDEPLOY:-""} + + +# ----- 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 database username to be used by Monitoring. +export QDB_USERNAME=${QDB_USERNAME:-"admin"} + +# If not already set, set the database user's password to be used by Monitoring. +export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} + +# If not already set, set the table name to be used by Monitoring. +export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} + +## If not already set, disable flag for dropping table if exists. +## WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE TABLE INFORMATION! +## If QDB_DROP_TABLE_IF_EXISTS is "YES", the table pointed by variable QDB_TABLE will be dropped while +## checking/deploying QuestDB. +#export QDB_DROP_TABLE_IF_EXISTS=${QDB_DROP_TABLE_IF_EXISTS:-""} + +# If not already set, disable flag for re-deploying QuestDB from scratch. +# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! +# If QDB_REDEPLOY is "YES", the database will be dropped while checking/deploying QuestDB. +export QDB_REDEPLOY=${QDB_REDEPLOY:-""} + + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +# Deploy CockroachDB +./deploy/crdb.sh + +# Deploy NATS +./deploy/nats.sh + +# Deploy QuestDB +./deploy/qdb.sh + +# Deploy TeraFlowSDN +./deploy/tfs.sh + +# Show deploy summary +./deploy/show.sh + +echo "Done!" diff --git a/deploy_component.sh b/deploy/component.sh similarity index 92% rename from deploy_component.sh rename to deploy/component.sh index a4cf6184c83ef026562abe8e084430bba3ead9c8..922aa5e0ec77a2c6acd73db1195a9ec3d2b160fb 100755 --- a/deploy_component.sh +++ b/deploy/component.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -18,10 +18,9 @@ # Read deployment settings ######################################################################################################################## -# If not already set, set the URL of your local Docker registry where the images will be uploaded to. -# Leave it blank if you do not want to use any Docker registry. -export TFS_REGISTRY_IMAGE=${TFS_REGISTRY_IMAGE:-""} -#export TFS_REGISTRY_IMAGE="http://my-container-registry.local/" +# If not already set, set the URL of the Docker registry where the images will be uploaded to. +# By default, assume internal MicroK8s registry is used. +export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} TFS_COMPONENTS=$1 @@ -42,7 +41,7 @@ export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"} ######################################################################################################################## # Constants -GITLAB_REPO_URL="registry.gitlab.com/teraflow-h2020/controller" +GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller" TMP_FOLDER="./tmp" # Create a tmp folder for files modified during the deployment @@ -55,7 +54,7 @@ ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh for COMPONENT in $TFS_COMPONENTS; do echo "Processing '$COMPONENT' component..." IMAGE_NAME="$COMPONENT:$TFS_IMAGE_TAG" - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$IMAGE_NAME" | sed 's,//,/,g' | sed 's,http:/,,g') + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$IMAGE_NAME" | sed 's,//,/,g' | sed 's,http:/,,g') echo " Building Docker image..." BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log" @@ -74,8 +73,8 @@ for COMPONENT in $TFS_COMPONENTS; do docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG" fi - if [ -n "$TFS_REGISTRY_IMAGE" ]; then - echo " Pushing Docker image to '$TFS_REGISTRY_IMAGE'..." + if [ -n "$TFS_REGISTRY_IMAGES" ]; then + echo " Pushing Docker image to '$TFS_REGISTRY_IMAGES'..." if [ "$COMPONENT" == "pathcomp" ]; then TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log" @@ -102,7 +101,7 @@ for COMPONENT in $TFS_COMPONENTS; do MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml" cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST" - if [ -n "$TFS_REGISTRY_IMAGE" ]; then + if [ -n "$TFS_REGISTRY_IMAGES" ]; then # Registry is set if [ "$COMPONENT" == "pathcomp" ]; then VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3) diff --git a/deploy/crdb.sh b/deploy/crdb.sh new file mode 100755 index 0000000000000000000000000000000000000000..98d011f190196b803be27200b8bc348b30c87055 --- /dev/null +++ b/deploy/crdb.sh @@ -0,0 +1,361 @@ +#!/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 namespace where CockroackDB will be deployed. +export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} + +# If not already set, set the database username to be used by Context. +export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} + +# If not already set, set the database user's password to be used by Context. +export CRDB_PASSWORD=${CRDB_PASSWORD:-"tfs123"} + +# If not already set, set the database name to be used by Context. +export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"} + +# If not already set, set CockroachDB installation mode. Accepted values are: 'single' and 'cluster'. +# "YES", the database pointed by variable CRDB_NAMESPACE will be dropped while +# checking/deploying CockroachDB. +# - If CRDB_DEPLOY_MODE is "single", CockroachDB is deployed in single node mode. It is convenient for +# development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS. +# - If CRDB_DEPLOY_MODE is "cluster", CockroachDB is deployed in cluster mode, and an entire CockroachDB cluster +# with 3 replicas and version v22.2 (set by default) will be deployed. It is convenient for production and +# provides scalability features. If you are deploying for production, also read the following link providing +# details on deploying CockroachDB for production environments: +# Ref: https://www.cockroachlabs.com/docs/stable/recommended-production-settings.html +export CRDB_DEPLOY_MODE=${CRDB_DEPLOY_MODE:-"single"} + +# If not already set, disable flag for dropping database if exists. +# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! +# If CRDB_DROP_DATABASE_IF_EXISTS is "YES", the database pointed by variable CRDB_DATABASE will be dropped while +# checking/deploying CockroachDB. +export CRDB_DROP_DATABASE_IF_EXISTS=${CRDB_DROP_DATABASE_IF_EXISTS:-""} + +# If not already set, disable flag for re-deploying CockroachDB from scratch. +# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! +# WARNING: THE REDEPLOY MIGHT TAKE FEW MINUTES TO COMPLETE GRACEFULLY IN CLUSTER MODE +# If CRDB_REDEPLOY is "YES", the database will be dropped while checking/deploying CockroachDB. +export CRDB_REDEPLOY=${CRDB_REDEPLOY:-""} + + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +# Constants +TMP_FOLDER="./tmp" +CRDB_MANIFESTS_PATH="manifests/cockroachdb" + +# Create a tmp folder for files modified during the deployment +TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" +mkdir -p $TMP_MANIFESTS_FOLDER +TMP_LOGS_FOLDER="$TMP_FOLDER/logs" +mkdir -p $TMP_LOGS_FOLDER +CRDB_LOG_FILE="$TMP_LOGS_FOLDER/crdb_deploy.log" + +function crdb_deploy_single() { + echo "CockroachDB Namespace" + echo ">>> Create CockroachDB Namespace (if missing)" + kubectl create namespace ${CRDB_NAMESPACE} + echo + + echo "CockroachDB (single-node)" + echo ">>> Checking if CockroachDB is deployed..." + if kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; then + echo ">>> CockroachDB is present; skipping step." + else + echo ">>> Deploy CockroachDB" + cp "${CRDB_MANIFESTS_PATH}/single-node.yaml" "${TMP_MANIFESTS_FOLDER}/crdb_single_node.yaml" + sed -i "s/%CRDB_DATABASE%/${CRDB_DATABASE}/g" "${TMP_MANIFESTS_FOLDER}/crdb_single_node.yaml" + sed -i "s/%CRDB_USERNAME%/${CRDB_USERNAME}/g" "${TMP_MANIFESTS_FOLDER}/crdb_single_node.yaml" + sed -i "s/%CRDB_PASSWORD%/${CRDB_PASSWORD}/g" "${TMP_MANIFESTS_FOLDER}/crdb_single_node.yaml" + kubectl apply --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_single_node.yaml" + + echo ">>> Waiting CockroachDB statefulset to be created..." + while ! kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; do + printf "%c" "." + sleep 1 + done + + # Wait for statefulset condition "Available=True" does not work + # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: + # "error: readyReplicas is not found" + # Workaround: Check the pods are ready + #echo ">>> CockroachDB statefulset created. Waiting for readiness condition..." + #kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/cockroachdb + #kubectl wait --namespace ${CRDB_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ + # statefulset/cockroachdb + echo ">>> CockroachDB statefulset created. Waiting CockroachDB pods to be created..." + while ! kubectl get --namespace ${CRDB_NAMESPACE} pod/cockroachdb-0 &> /dev/null; do + printf "%c" "." + sleep 1 + done + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-0 + fi + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${CRDB_SQL_PORT}', "hostPort": '${CRDB_SQL_PORT}'}' + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${CRDB_GUI_PORT_EXT}', "hostPort": '${CRDB_GUI_PORT_EXT}'}' + 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 +} + +function crdb_undeploy_single() { + echo "CockroachDB" + echo ">>> Checking if CockroachDB is deployed..." + if kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; then + echo ">>> Undeploy CockroachDB" + kubectl delete --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_single_node.yaml" --ignore-not-found + else + echo ">>> CockroachDB is not present; skipping step." + fi + echo + + echo "CockroachDB Namespace" + echo ">>> Delete CockroachDB Namespace (if exists)" + echo "NOTE: this step might take few minutes to complete!" + kubectl delete namespace ${CRDB_NAMESPACE} --ignore-not-found + echo +} + +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" + 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};" + echo +} + +function crdb_deploy_cluster() { + 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" + kubectl apply -f "${TMP_MANIFESTS_FOLDER}/crdb_crds.yaml" + echo + + echo "Cockroach Operator" + echo ">>> Checking if Cockroach Operator is deployed..." + if kubectl get --namespace cockroach-operator-system deployment/cockroach-operator-manager &> /dev/null; then + echo ">>> Cockroach Operator is present; skipping step." + else + echo ">>> Deploy Cockroach Operator" + sed "s/%TFS_CRDB_NAMESPACE%/${CRDB_NAMESPACE}/g" "${CRDB_MANIFESTS_PATH}/operator.yaml" \ + > "${TMP_MANIFESTS_FOLDER}/crdb_operator.yaml" + kubectl apply -f "${TMP_MANIFESTS_FOLDER}/crdb_operator.yaml" + kubectl wait --namespace cockroach-operator-system --for=condition=Available=True --timeout=300s \ + deployment/cockroach-operator-manager + #kubectl wait --namespace cockroach-operator-system --for=jsonpath='{.status.readyReplicas}'=1 --timeout=300s \ + # deployment/cockroach-operator-manager + + echo ">>> Waiting for Cockroach Operator Webhock service..." + while ! kubectl get service cockroach-operator-webhook-service --namespace cockroach-operator-system &> /dev/null; do + printf "%c" "." + sleep 1 + done + WEBHOOK_SERVICE_DATA=$(kubectl get service cockroach-operator-webhook-service --namespace cockroach-operator-system -o json) + WEBHOOK_SERVICE_HOST=$(echo ${WEBHOOK_SERVICE_DATA} | jq -r '.spec.clusterIP') + WEBHOOK_SERVICE_PORT=$(echo ${WEBHOOK_SERVICE_DATA} | jq -r '.spec.ports[] | select(.targetPort==9443) | .port') + WEBHOOK_URL="https://${WEBHOOK_SERVICE_HOST}:${WEBHOOK_SERVICE_PORT}/mutate-crdb-cockroachlabs-com-v1alpha1-crdbcluster?timeout=10s" + while ! curl --insecure --header 'Content-Type: application/json' ${WEBHOOK_URL} &> /dev/null; do + printf "%c" "." + sleep 1 + done + fi + echo + + echo "CockroachDB Namespace" + echo ">>> Create CockroachDB Namespace (if missing)" + kubectl create namespace ${CRDB_NAMESPACE} + echo + + echo "CockroachDB" + echo ">>> Checking if CockroachDB is deployed..." + if kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; then + echo ">>> CockroachDB is present; skipping step." + else + echo ">>> Deploy CockroachDB" + cp "${CRDB_MANIFESTS_PATH}/cluster.yaml" "${TMP_MANIFESTS_FOLDER}/crdb_cluster.yaml" + kubectl apply --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_cluster.yaml" + + echo ">>> Waiting CockroachDB statefulset to be created..." + while ! kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; do + printf "%c" "." + sleep 1 + done + + # Wait for statefulset condition "Available=True" does not work + # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: + # "error: readyReplicas is not found" + # Workaround: Check the pods are ready + #echo ">>> CockroachDB statefulset created. Waiting for readiness condition..." + #kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/cockroachdb + #kubectl wait --namespace ${CRDB_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ + # statefulset/cockroachdb + echo ">>> CockroachDB statefulset created. Waiting CockroachDB pods to be created..." + while ! kubectl get --namespace ${CRDB_NAMESPACE} pod/cockroachdb-0 &> /dev/null; do + printf "%c" "." + sleep 1 + done + while ! kubectl get --namespace ${CRDB_NAMESPACE} pod/cockroachdb-1 &> /dev/null; do + printf "%c" "." + sleep 1 + done + while ! kubectl get --namespace ${CRDB_NAMESPACE} pod/cockroachdb-2 &> /dev/null; do + printf "%c" "." + sleep 1 + done + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-0 + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-1 + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-2 + fi + echo + + echo "CockroachDB Client" + echo ">>> Checking if CockroachDB Client is deployed..." + if kubectl get --namespace ${CRDB_NAMESPACE} pod/cockroachdb-client-secure &> /dev/null; then + echo ">>> CockroachDB Client is present; skipping step." + else + echo ">>> Deploy CockroachDB Client" + cp "${CRDB_MANIFESTS_PATH}/client-secure-operator.yaml" "${TMP_MANIFESTS_FOLDER}/crdb_client-secure-operator.yaml" + kubectl create --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_client-secure-operator.yaml" + kubectl wait --namespace ${CRDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/cockroachdb-client-secure + fi + echo + + echo "Add tfs user and grant admin rights" + kubectl exec -it cockroachdb-client-secure --namespace ${CRDB_NAMESPACE} -- \ + ./cockroach sql --certs-dir=/cockroach/cockroach-certs --host=cockroachdb-public --execute \ + "CREATE USER ${CRDB_USERNAME} WITH PASSWORD '${CRDB_PASSWORD}'; GRANT admin TO ${CRDB_USERNAME};" + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${CRDB_SQL_PORT}', "hostPort": '${CRDB_SQL_PORT}'}' + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${CRDB_GUI_PORT_EXT}', "hostPort": '${CRDB_GUI_PORT_EXT}'}' + 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 +} + +function crdb_undeploy_cluster() { + echo "CockroachDB Client" + echo ">>> Checking if CockroachDB Client is deployed..." + if kubectl get --namespace ${CRDB_NAMESPACE} pod/cockroachdb-client-secure &> /dev/null; then + echo ">>> Undeploy CockroachDB Client" + kubectl delete --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_client-secure-operator.yaml" \ + --ignore-not-found + else + echo ">>> CockroachDB Client is not present; skipping step." + fi + echo + + echo "CockroachDB" + echo ">>> Checking if CockroachDB is deployed..." + if kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; then + echo ">>> Undeploy CockroachDB" + kubectl delete --namespace ${CRDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/crdb_cluster.yaml" --ignore-not-found + else + echo ">>> CockroachDB is not present; skipping step." + fi + echo + + echo "CockroachDB Namespace" + echo ">>> Delete CockroachDB Namespace (if exists)" + echo "NOTE: this step might take few minutes to complete!" + kubectl delete namespace ${CRDB_NAMESPACE} --ignore-not-found + echo + + echo "CockroachDB Operator" + echo ">>> Checking if CockroachDB Operator is deployed..." + if kubectl get --namespace cockroach-operator-system deployment/cockroach-operator-manager &> /dev/null; then + echo ">>> Undeploy CockroachDB Operator" + kubectl delete -f "${TMP_MANIFESTS_FOLDER}/crdb_operator.yaml" --ignore-not-found + else + echo ">>> CockroachDB Operator is not present; skipping step." + fi + echo + + echo "CockroachDB Operator CRDs" + echo ">>> Delete CockroachDB Operator CRDs (if they exist)" + kubectl delete -f "${TMP_MANIFESTS_FOLDER}/crdb_crds.yaml" --ignore-not-found + echo +} + +function crdb_drop_database_cluster() { + echo "Drop database if exists" + kubectl exec -it --namespace ${CRDB_NAMESPACE} cockroachdb-client-secure -- \ + ./cockroach sql --certs-dir=/cockroach/cockroach-certs --host=cockroachdb-public --execute \ + "DROP DATABASE IF EXISTS ${CRDB_DATABASE};" + echo +} + +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 +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 +else + echo "Unsupported value: CRDB_DEPLOY_MODE=$CRDB_DEPLOY_MODE" +fi diff --git a/deploy_mock_blockchain.sh b/deploy/mock_blockchain.sh similarity index 97% rename from deploy_mock_blockchain.sh rename to deploy/mock_blockchain.sh index 066820fc0f9a1005823dd124798e4de122f206f8..ef7811c87eabdcb7cf95db2e4cf1a6eee52ef6ca 100755 --- a/deploy_mock_blockchain.sh +++ b/deploy/mock_blockchain.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -34,7 +34,7 @@ COMPONENT="mock_blockchain" ######################################################################################################################## # Constants -GITLAB_REPO_URL="registry.gitlab.com/teraflow-h2020/controller" +GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller" TMP_FOLDER="./tmp" # Create a tmp folder for files modified during the deployment diff --git a/deploy/nats.sh b/deploy/nats.sh new file mode 100755 index 0000000000000000000000000000000000000000..115a185302236b80db385212cd772100392329af --- /dev/null +++ b/deploy/nats.sh @@ -0,0 +1,128 @@ +#!/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 namespace where NATS will be deployed. +export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} + +# 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. +export NATS_REDEPLOY=${NATS_REDEPLOY:-""} + + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +# Constants +TMP_FOLDER="./tmp" +NATS_MANIFESTS_PATH="manifests/nats" + +# Create a tmp folder for files modified during the deployment +TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" +mkdir -p $TMP_MANIFESTS_FOLDER + +function nats_deploy_single() { + echo "NATS Namespace" + echo ">>> Create NATS Namespace (if missing)" + kubectl create namespace ${NATS_NAMESPACE} + echo + + echo "Add NATS Helm Chart" + helm3 repo add nats https://nats-io.github.io/k8s/helm/charts/ + echo + + echo "Install NATS (single-node)" + echo ">>> Checking if NATS is deployed..." + if kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /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 + + echo ">>> Waiting NATS statefulset to be created..." + while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; do + printf "%c" "." + sleep 1 + done + + # Wait for statefulset condition "Available=True" does not work + # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: + # "error: readyReplicas is not found" + # Workaround: Check the pods are ready + #echo ">>> NATS statefulset created. Waiting for readiness condition..." + #kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/nats + #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 + printf "%c" "." + sleep 1 + done + kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/nats-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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${NATS_CLIENT_PORT}', "hostPort": '${NATS_CLIENT_PORT}'}' + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${NATS_GUI_PORT}', "hostPort": '${NATS_GUI_PORT}'}' + 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 +} + +function nats_undeploy_single() { + echo "NATS" + echo ">>> Checking if NATS is deployed..." + if kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; then + echo ">>> Undeploy NATS" + helm3 uninstall --namespace ${NATS_NAMESPACE} nats + else + echo ">>> NATS is not present; skipping step." + fi + echo + + echo "NATS Namespace" + echo ">>> Delete NATS Namespace (if exists)" + kubectl delete namespace ${NATS_NAMESPACE} --ignore-not-found + echo +} + +if [ "$NATS_REDEPLOY" == "YES" ]; then + nats_undeploy_single +fi + +nats_deploy_single diff --git a/deploy/qdb.sh b/deploy/qdb.sh new file mode 100755 index 0000000000000000000000000000000000000000..d9a4de353b3309ef0a8a34310089e9bff31589fa --- /dev/null +++ b/deploy/qdb.sh @@ -0,0 +1,165 @@ +#!/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 namespace where QuestDB will be deployed. +export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} + +# If not already set, set the database username to be used by Monitoring. +export QDB_USERNAME=${QDB_USERNAME:-"admin"} + +# If not already set, set the database user's password to be used by Monitoring. +export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} + +# If not already set, set the table name to be used by Monitoring. +export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} + +## If not already set, disable flag for dropping table if exists. +## WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE TABLE INFORMATION! +## If QDB_DROP_TABLE_IF_EXISTS is "YES", the table pointed by variable QDB_TABLE will be dropped while +## checking/deploying QuestDB. +#export QDB_DROP_TABLE_IF_EXISTS=${QDB_DROP_TABLE_IF_EXISTS:-""} + +# If not already set, disable flag for re-deploying QuestDB from scratch. +# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! +# If QDB_REDEPLOY is "YES", the database will be dropped while checking/deploying QuestDB. +export QDB_REDEPLOY=${QDB_REDEPLOY:-""} + + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +# Constants +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_LOGS_FOLDER="$TMP_FOLDER/logs" +QDB_LOG_FILE="$TMP_LOGS_FOLDER/qdb_deploy.log" +mkdir -p $TMP_LOGS_FOLDER + +function qdb_deploy() { + echo "QuestDB Namespace" + echo ">>> Create QuestDB Namespace (if missing)" + kubectl create namespace ${QDB_NAMESPACE} + echo + + echo "QuestDB" + echo ">>> Checking if QuestDB is deployed..." + if kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; then + echo ">>> QuestDB is present; skipping step." + else + echo ">>> Deploy QuestDB" + cp "${QDB_MANIFESTS_PATH}/manifest.yaml" "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" + kubectl apply --namespace ${QDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" + + echo ">>> Waiting QuestDB statefulset to be created..." + while ! kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; do + printf "%c" "." + sleep 1 + done + + # Wait for statefulset condition "Available=True" does not work + # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: + # "error: readyReplicas is not found" + # Workaround: Check the pods are ready + #echo ">>> QuestDB statefulset created. Waiting for readiness condition..." + #kubectl wait --namespace ${QDB_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/questdb + #kubectl wait --namespace ${QDB_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ + # statefulset/questdb + echo ">>> QuestDB statefulset created. Waiting QuestDB pods to be created..." + while ! kubectl get --namespace ${QDB_NAMESPACE} pod/questdb-0 &> /dev/null; do + printf "%c" "." + sleep 1 + done + kubectl wait --namespace ${QDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/questdb-0 + fi + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${QDB_SQL_PORT}', "hostPort": '${QDB_SQL_PORT}'}' + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${QDB_ILP_PORT}', "hostPort": '${QDB_ILP_PORT}'}' + 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}'"}}' + kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + + PORT_MAP='{"containerPort": '${QDB_GUI_PORT}', "hostPort": '${QDB_GUI_PORT}'}' + 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 +} + +function qdb_undeploy() { + echo "QuestDB" + echo ">>> Checking if QuestDB is deployed..." + if kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; then + echo ">>> Undeploy QuestDB" + kubectl delete --namespace ${QDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" --ignore-not-found + else + echo ">>> QuestDB is not present; skipping step." + fi + echo + + echo "QuestDB Namespace" + echo ">>> Delete QuestDB Namespace (if exists)" + echo "NOTE: this step might take few minutes to complete!" + kubectl delete namespace ${QDB_NAMESPACE} --ignore-not-found + echo +} + +# TODO: implement method to drop table +#function qdb_drop_table() { +# echo "Drop table if exists" +# QDB_CLIENT_URL="postgresql://${QDB_USERNAME}:${QDB_PASSWORD}@questdb-0:${QDB_SQL_PORT}/defaultdb?sslmode=require" +# kubectl exec -it --namespace ${QDB_NAMESPACE} questdb-0 -- \ +# ./qdb sql --certs-dir=/qdb/qdb-certs --url=${QDB_CLIENT_URL} \ +# --execute "DROP TABLE IF EXISTS ${QDB_TABLE};" +# echo +#} + +if [ "$QDB_REDEPLOY" == "YES" ]; then + qdb_undeploy +#elif [ "$QDB_DROP_TABLE_IF_EXISTS" == "YES" ]; then +# qdb_drop_table +fi +qdb_deploy diff --git a/show_deploy.sh b/deploy/show.sh similarity index 95% rename from show_deploy.sh rename to deploy/show.sh index 68a5659aab529be5644015d6e6fbdf9885f7a1ec..a4084ac65402c7987504fbcacdf6aa5b44029fc4 100755 --- a/show_deploy.sh +++ b/deploy/show.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/deploy.sh b/deploy/tfs.sh similarity index 55% rename from deploy.sh rename to deploy/tfs.sh index c62778417f7e07a119c778b58fe9c44105d5b1a5..b9bcbab4d8084e30aae90be3cf669445d01c0dac 100755 --- a/deploy.sh +++ b/deploy/tfs.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -18,10 +18,9 @@ # Read deployment settings ######################################################################################################################## -# If not already set, set the URL of your local Docker registry where the images will be uploaded to. -# Leave it blank if you do not want to use any Docker registry. -export TFS_REGISTRY_IMAGE=${TFS_REGISTRY_IMAGE:-""} -#export TFS_REGISTRY_IMAGE="http://my-container-registry.local/" +# If not already set, set the URL of the Docker registry where the images will be uploaded to. +# By default, assume internal MicroK8s registry is used. +export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} # If not already set, set the list of components you want to build images for, and deploy. # By default, only basic components are deployed @@ -43,12 +42,40 @@ export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"} # If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used. 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 database username to be used by Context. +export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} + +# If not already set, set the database user's password to be used by Context. +export CRDB_PASSWORD=${CRDB_PASSWORD:-"tfs123"} + +# If not already set, set the database name to be used by Context. +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 namespace where QuestDB will be deployed. +export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} + +# If not already set, set the database username to be used by Monitoring. +export QDB_USERNAME=${QDB_USERNAME:-"admin"} + +# If not already set, set the database user's password to be used by Monitoring. +export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} + +# If not already set, set the table name to be used by Monitoring. +export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} + + ######################################################################################################################## # Automated steps start here ######################################################################################################################## # Constants -GITLAB_REPO_URL="registry.gitlab.com/teraflow-h2020/controller" +GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller" TMP_FOLDER="./tmp" # Create a tmp folder for files modified during the deployment @@ -62,6 +89,40 @@ kubectl delete namespace $TFS_K8S_NAMESPACE kubectl create namespace $TFS_K8S_NAMESPACE printf "\n" +echo "Create secret with CockroachDB data" +CRDB_SQL_PORT=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') +kubectl create secret generic crdb-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \ + --from-literal=CRDB_NAMESPACE=${CRDB_NAMESPACE} \ + --from-literal=CRDB_SQL_PORT=${CRDB_SQL_PORT} \ + --from-literal=CRDB_DATABASE=${CRDB_DATABASE} \ + --from-literal=CRDB_USERNAME=${CRDB_USERNAME} \ + --from-literal=CRDB_PASSWORD=${CRDB_PASSWORD} \ + --from-literal=CRDB_SSLMODE=require +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}') +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} +printf "\n" + +echo "Create secret with QuestDB data" +QDB_HTTP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') +QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') +QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') +METRICSDB_HOSTNAME="questdb-public.${QDB_NAMESPACE}.svc.cluster.local" +kubectl create secret generic qdb-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \ + --from-literal=QDB_NAMESPACE=${QDB_NAMESPACE} \ + --from-literal=METRICSDB_HOSTNAME=${METRICSDB_HOSTNAME} \ + --from-literal=METRICSDB_REST_PORT=${QDB_HTTP_PORT} \ + --from-literal=METRICSDB_ILP_PORT=${QDB_ILP_PORT} \ + --from-literal=METRICSDB_SQL_PORT=${QDB_SQL_PORT} \ + --from-literal=METRICSDB_TABLE=${QDB_TABLE} \ + --from-literal=METRICSDB_USERNAME=${QDB_USERNAME} \ + --from-literal=METRICSDB_PASSWORD=${QDB_PASSWORD} +printf "\n" + echo "Deploying components and collecting environment variables..." ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh echo "# Environment variables for TeraFlowSDN deployment" > $ENV_VARS_SCRIPT @@ -96,50 +157,48 @@ for COMPONENT in $TFS_COMPONENTS; do docker build -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG" fi - if [ -n "$TFS_REGISTRY_IMAGE" ]; then - echo " Pushing Docker image to '$TFS_REGISTRY_IMAGE'..." + echo " Pushing Docker image to '$TFS_REGISTRY_IMAGES'..." - if [ "$COMPONENT" == "pathcomp" ]; then - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + if [ "$COMPONENT" == "pathcomp" ]; then + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log" - docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" + TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log" + docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" - PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log" - docker push "$IMAGE_URL" > "$PUSH_LOG" + PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log" + docker push "$IMAGE_URL" > "$PUSH_LOG" - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log" - docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" + TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log" + docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" - PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log" - docker push "$IMAGE_URL" > "$PUSH_LOG" - elif [ "$COMPONENT" == "dlt" ]; then - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log" + docker push "$IMAGE_URL" > "$PUSH_LOG" + elif [ "$COMPONENT" == "dlt" ]; then + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-connector.log" - docker tag "$COMPONENT-connector:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" + TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-connector.log" + docker tag "$COMPONENT-connector:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" - PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-connector.log" - docker push "$IMAGE_URL" > "$PUSH_LOG" + PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-connector.log" + docker push "$IMAGE_URL" > "$PUSH_LOG" - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-gateway.log" - docker tag "$COMPONENT-gateway:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" + TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-gateway.log" + docker tag "$COMPONENT-gateway:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" - PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-gateway.log" - docker push "$IMAGE_URL" > "$PUSH_LOG" - else - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-gateway.log" + docker push "$IMAGE_URL" > "$PUSH_LOG" + else + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log" - docker tag "$COMPONENT:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" + TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log" + docker tag "$COMPONENT:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG" - PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log" - docker push "$IMAGE_URL" > "$PUSH_LOG" - fi + PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log" + docker push "$IMAGE_URL" > "$PUSH_LOG" fi fi @@ -147,53 +206,30 @@ for COMPONENT in $TFS_COMPONENTS; do MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml" cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST" - if [ -n "$TFS_REGISTRY_IMAGE" ]; then - # Registry is set - if [ "$COMPONENT" == "pathcomp" ]; then - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" - - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" - elif [ "$COMPONENT" == "dlt" ]; then - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-connector:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-connector:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" - - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-gateway:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-gateway:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" - else - IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" - fi - - sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST" + if [ "$COMPONENT" == "pathcomp" ]; then + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f4) + sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" + + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f4) + sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" + elif [ "$COMPONENT" == "dlt" ]; then + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-connector:" "$MANIFEST" | cut -d ":" -f4) + sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-connector:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" + + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-gateway:" "$MANIFEST" | cut -d ":" -f4) + sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-gateway:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" else - # Registry is not set - if [ "$COMPONENT" == "pathcomp" ]; then - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $COMPONENT-frontend:$TFS_IMAGE_TAG#g" "$MANIFEST" - - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $COMPONENT-backend:$TFS_IMAGE_TAG#g" "$MANIFEST" - elif [ "$COMPONENT" == "dlt" ]; then - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-connector:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-connector:${VERSION}#image: $COMPONENT-connector:$TFS_IMAGE_TAG#g" "$MANIFEST" - - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-gateway:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-gateway:${VERSION}#image: $COMPONENT-gateway:$TFS_IMAGE_TAG#g" "$MANIFEST" - else - VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3) - sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $COMPONENT:$TFS_IMAGE_TAG#g" "$MANIFEST" - fi - - sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" "$MANIFEST" + IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') + VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f4) + sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST" fi + sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST" + # TODO: harmonize names of the monitoring component echo " Deploying '$COMPONENT' component to Kubernetes..." @@ -243,17 +279,6 @@ for EXTRA_MANIFEST in $TFS_EXTRA_MANIFESTS; do done printf "\n" -# By now, leave these controls here. Some component dependencies are not well handled. - -if [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then - echo "Waiting for 'MonitoringDB' component..." - # Kubernetes does not implement --for='condition=available' for statefulsets. - # By now, we assume a single replica of monitoringdb. To be updated in future releases. - kubectl wait --namespace $TFS_K8S_NAMESPACE \ - --for=jsonpath='{.status.readyReplicas}'=1 --timeout=300s statefulset/monitoringdb - printf "\n" -fi - for COMPONENT in $TFS_COMPONENTS; do echo "Waiting for '$COMPONENT' component..." COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") @@ -264,36 +289,19 @@ done if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then echo "Configuring WebUI DataStores and Dashboards..." - sleep 3 - - # INFLUXDB_HOST="monitoringservice" - # INFLUXDB_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service/monitoringservice -o jsonpath='{.spec.ports[?(@.name=="influxdb")].port}') - # INFLUXDB_URL="http://${INFLUXDB_HOST}:${INFLUXDB_PORT}" - # INFLUXDB_USER=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode) - # INFLUXDB_PASSWORD=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode) - # INFLUXDB_DATABASE=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode) + sleep 5 # Exposed through the ingress controller "tfs-ingress" - GRAFANA_HOSTNAME="127.0.0.1" - GRAFANA_PORT="80" - GRAFANA_BASEURL="/grafana" + GRAFANA_URL="127.0.0.1:80/grafana" # Default Grafana credentials GRAFANA_USERNAME="admin" GRAFANA_PASSWORD="admin" - # Default Grafana API URL - GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}" - - # Updated Grafana API URL - GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}" - - echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT - - echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..." - # Configure Grafana Admin Password # Ref: https://grafana.com/docs/grafana/latest/http_api/user/#change-password + GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_URL}" + echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..." curl -X PUT -H "Content-Type: application/json" -d '{ "oldPassword": "'${GRAFANA_PASSWORD}'", "newPassword": "'${TFS_GRAFANA_PASSWORD}'", @@ -301,16 +309,21 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" }' ${GRAFANA_URL_DEFAULT}/api/user/password echo + # Updated Grafana API URL + GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_URL}" + echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT + # Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/ # TODO: replace user, password and database by variables to be saved + QDB_HOST_PORT="${METRICSDB_HOSTNAME}:${QDB_SQL_PORT}" echo "Creating a datasource..." curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{ "access" : "proxy", "type" : "postgres", - "name" : "monitoringdb", - "url" : "monitoringservice:8812", - "database" : "monitoring", - "user" : "admin", + "name" : "questdb", + "url" : "'${QDB_HOST_PORT}'", + "database" : "'${QDB_TABLE}'", + "user" : "'${QDB_USERNAME}'", "basicAuth": false, "isDefault": true, "jsonData" : { @@ -325,9 +338,7 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" "tlsConfigurationMethod": "file-path", "tlsSkipVerify" : true }, - "secureJsonData": { - "password": "quest" - } + "secureJsonData": {"password": "'${QDB_PASSWORD}'"} }' ${GRAFANA_URL_UPDATED}/api/datasources echo @@ -344,7 +355,3 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" printf "\n\n" fi - -./show_deploy.sh - -echo "Done!" diff --git a/expose_ingress_grpc.sh b/expose_ingress_grpc.sh index e2667247afdf72cc2f48317ace24275408eb11aa..945641c1f3b6ae981685a2a257260b14ceb927b2 100755 --- a/expose_ingress_grpc.sh +++ b/expose_ingress_grpc.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/commands.txt b/hackfest/commands.txt index c34c6acc112e3d5dee47752967b60bab32556c94..31558364d74aa1fec729c80c9fab50aa7e0c2313 100644 --- a/hackfest/commands.txt +++ b/hackfest/commands.txt @@ -262,5 +262,43 @@ Service b8c99e2c-39d8-424d-9833-554634269555 deleted (mock-osm) exit Bye! +############ +# gNMI +############ + +## Download and install the latest release +$ sudo bash -c "$(curl -sL https://get.containerlab.dev)“ + +## Deploy proposed two SR node scenario +$ cd tfs-ctrl/hackfest/gnmi +$ sudo containerlab deploy -t srlinux.clab.yml + +## Access SR Bash +$ docker exec -it clab-srlinux-srl1 bash + +## Acess SR CLI +$ docker exec -it clab-srlinux-srl1 sr_cli + +## Destroy scenario +$ sudo containerlab destroy --topo srlinux.clab.yml + +## Install gNMIc +$ sudo bash -c "$(curl -sL https://get-gnmic.kmrd.dev)" + +## gNMI Capabilities request +$ gnmic -a clab-srlinux-srl1 -u admin -p NokiaSrl1! --skip-verify capabilities + +## gNMI Get request +$ gnmic -a clab-srlinux-srl1 -u admin -p NokiaSrl1! --skip-verify -e json_ietf get --path /system/name/host-name +$ gnmic -a clab-srlinux-srl1 -u admin -p NokiaSrl1! --skip-verify -e json_ietf get --path /interface[name=mgmt0] + +## gNMI Set request +$ gnmic -a clab-srlinux-srl1 -u admin -p NokiaSrl1! --skip-verify -e json_ietf set --update-path /system/name/host-name --update-value slr11 +(we check the changed value) +$ gnmic -a clab-srlinux-srl1 -u admin -p NokiaSrl1! --skip-verify -e json_ietf get --path /system/name/host-name +## Subscribe request +$ gnmic -a clab-srlinux-srl1 -u admin -p NokiaSrl1! --skip-verify -e json_ietf subscribe --path /interface[name=mgmt0]/statistics +(In another terminal, you can generate traffic) +$ssh admin@clab-srlinux-srl1 diff --git a/src/tests/ecoc22/tests/Credentials.py b/hackfest/gnmi/.gitkeep similarity index 100% rename from src/tests/ecoc22/tests/Credentials.py rename to hackfest/gnmi/.gitkeep diff --git a/hackfest/gnmi/commands.txt b/hackfest/gnmi/commands.txt deleted file mode 100644 index 6fae7f9a8fc8b9b69d364b1d279aca80759c90ef..0000000000000000000000000000000000000000 --- a/hackfest/gnmi/commands.txt +++ /dev/null @@ -1,17 +0,0 @@ -== GNMI -$ cd /usr/share/gocode/src/ -$ export GOPATH=/usr/share/gocode/ -$ go run github.com/openconfig/ygot/generator/generator.go -generate_fakeroot -output_file github.com/google/gnxi/gnmi/modeldata/gostruct/generated.go -package_name gostruct github.com/rvilalta/OFC_SC472/yang/topology.yang -$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_target -$ go run gnmi_target.go -bind_address :10161 -config ~/tfs-ctrl/hackfest/gnmi/topology.json --notls -alsologtostderr - -RUN CLIENT (in another window) -$ export GOPATH=/usr/share/gocode/ -$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_get -$ go run gnmi_get.go -notls -xpath "/topology/" -target_addr localhost:10161 -alsologtostderr -$ go run gnmi_get.go -notls -xpath "/topology/node[node-id=A]" -target_addr localhost:10161 -alsologtostderr - -USE PYTHON CLIENT -$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_cli_py -$ python py_gnmicli.py -n -m get -t localhost -p 10161 -x /topology -u foo -pass bar - diff --git a/hackfest/gnmi/sonic.clab.yml b/hackfest/gnmi/sonic.clab.yml new file mode 100644 index 0000000000000000000000000000000000000000..47c1e64643a70e3e0caff12aff8a6796598cea1f --- /dev/null +++ b/hackfest/gnmi/sonic.clab.yml @@ -0,0 +1,29 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# file: sonic.clab.yml +name: sonic-vs + +topology: + nodes: + srl1: + kind: sonic-vs + image: docker-sonic-vs + srl2: + kind: sonic-vs + image: docker-sonic-vs + + links: + - endpoints: ["srl1:e1-1", "srl2:e1-1"] + diff --git a/hackfest/gnmi/topology.json b/hackfest/gnmi/topology.json deleted file mode 100644 index 9b64536a7992fbbde22f95c9cd9275354a9f7d81..0000000000000000000000000000000000000000 --- a/hackfest/gnmi/topology.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "topology" : { - "node" : [ - { "node-id" : "A" , "port" : [ { "port-id" : "portA1" } ] }, - { "node-id" : "B" , "port" : [ { "port-id" : "portB1" } ] } - ] - } -} diff --git a/hackfest/grpc/connection.proto b/hackfest/grpc/connection.proto index 42661cd5bcc0218d5daf4ffad31b22d6234fcc33..0e8522768614ec4c698b87647118101ae0479aaa 100644 --- a/hackfest/grpc/connection.proto +++ b/hackfest/grpc/connection.proto @@ -1,3 +1,17 @@ +// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //Example of connection syntax = "proto3"; package connection; diff --git a/hackfest/grpc/connection/create.py b/hackfest/grpc/connection/create.py old mode 100755 new mode 100644 index df5df77d631f25e0ce5368d537f4cb0f99297669..7d134105d04b155abc2d3d4ad3e4efeef085c81a --- a/hackfest/grpc/connection/create.py +++ b/hackfest/grpc/connection/create.py @@ -1,4 +1,18 @@ #! /usr/bin/env python3 +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 connection_pb2 import sys diff --git a/hackfest/grpc/connection/list.py b/hackfest/grpc/connection/list.py old mode 100755 new mode 100644 index 47b92cc4aa2e64cb121eddbcf4a0d10f87800fb2..5b1926d3cac8dbdf00d889726b1638e0a70ad6b2 --- a/hackfest/grpc/connection/list.py +++ b/hackfest/grpc/connection/list.py @@ -1,4 +1,18 @@ #! /usr/bin/env python3 +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 connection_pb2 import sys diff --git a/hackfest/grpc/connectionService.proto b/hackfest/grpc/connectionService.proto index aa3bcb4ef68ef8d3185d1b7da21ac0867b9cf59d..8f6b5a6e781ba074239bfdbc2d05bea638b153a3 100644 --- a/hackfest/grpc/connectionService.proto +++ b/hackfest/grpc/connectionService.proto @@ -1,3 +1,17 @@ +// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //Example of connection syntax = "proto3"; package connection; diff --git a/hackfest/grpc/connectionService/connectionService_client.py b/hackfest/grpc/connectionService/connectionService_client.py index c0f45f7a90efc85bb718a25c2353595c4a12a042..e5c1bf48186b4c5e7e3425e3601e32642e7d2fcc 100644 --- a/hackfest/grpc/connectionService/connectionService_client.py +++ b/hackfest/grpc/connectionService/connectionService_client.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grpc diff --git a/hackfest/grpc/connectionService/connectionService_server.py b/hackfest/grpc/connectionService/connectionService_server.py index 6fbd195cdeaf22ddeab86ca0a4860f85a194448f..f1632db90cd6d7dbfd186fe3c4bad9da32195b28 100644 --- a/hackfest/grpc/connectionService/connectionService_server.py +++ b/hackfest/grpc/connectionService/connectionService_server.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from concurrent import futures import time import logging diff --git a/hackfest/grpc/connectionServiceWithNotif.proto b/hackfest/grpc/connectionServiceWithNotif.proto index 8430479c525894e0e13140ad07d5691eb8601aca..f2f5b17e317cd5c15461979cf2cf20462d3d72de 100644 --- a/hackfest/grpc/connectionServiceWithNotif.proto +++ b/hackfest/grpc/connectionServiceWithNotif.proto @@ -1,3 +1,17 @@ +// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //Example of connection syntax = "proto3"; package connection; diff --git a/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_client.py b/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_client.py index e40e0a5fa53e75a3a1ad940c9516d75ada1f180f..9518bf743221c0a2e2c1191be063aafff8eaccb5 100644 --- a/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_client.py +++ b/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_client.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grpc diff --git a/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_server.py b/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_server.py index a9970056dbd6308e1191f4e57b7be7d20a94c43e..922f91837bc013f038985cbb0ef44aa234556696 100644 --- a/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_server.py +++ b/hackfest/grpc/connectionServiceWithNotif/connectionServiceWithNotif_server.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from concurrent import futures import time import logging diff --git a/hackfest/grpc/topologyService.proto b/hackfest/grpc/topologyService.proto index cf9601a4bf4c07a5f0bf73f9feb9f1e89d50ba63..775e45addedd8fd30c888ddcd7f3de92a9b66a4b 100644 --- a/hackfest/grpc/topologyService.proto +++ b/hackfest/grpc/topologyService.proto @@ -1,3 +1,17 @@ +// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //Example of topology syntax = "proto3"; package topology; diff --git a/hackfest/grpc/topologyService/topologyService_client.py b/hackfest/grpc/topologyService/topologyService_client.py index 24ce803b0348110acda02237058db4101d605acc..ef628183bed45452f191fc3be07a87db97ed6650 100644 --- a/hackfest/grpc/topologyService/topologyService_client.py +++ b/hackfest/grpc/topologyService/topologyService_client.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grpc diff --git a/hackfest/grpc/topologyService/topologyService_server.py b/hackfest/grpc/topologyService/topologyService_server.py index bb72e224239297226b2cf03bca2a72f4b0086ba2..ff1c80e82a9bf3404c6e9da9b3c0f7c534d01889 100644 --- a/hackfest/grpc/topologyService/topologyService_server.py +++ b/hackfest/grpc/topologyService/topologyService_server.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from concurrent import futures import time import logging diff --git a/hackfest/kafka/pub.py b/hackfest/kafka/pub.py index 12d3dc2ddef1a9da4396893b72d99d6afc322076..e80dd5db82632b9ef17e7fdf017b8964ab357623 100644 --- a/hackfest/kafka/pub.py +++ b/hackfest/kafka/pub.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from time import sleep from json import dumps from kafka import KafkaProducer diff --git a/hackfest/kafka/sub.py b/hackfest/kafka/sub.py index f61ab4d47c157f957f670380a5bea2d2684940f8..233b9f9d0c8b4a4a744859beeaff0141c04e0560 100644 --- a/hackfest/kafka/sub.py +++ b/hackfest/kafka/sub.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from kafka import KafkaConsumer from json import loads diff --git a/hackfest/mock_osm/MockOSM.py b/hackfest/mock_osm/MockOSM.py index b4e629d5845fd7115fa0fa2c0887eca1c7c816c4..338db0e19becc8a9dd277beec7f3b4ceb2e765a3 100644 --- a/hackfest/mock_osm/MockOSM.py +++ b/hackfest/mock_osm/MockOSM.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/mock_osm/WimconnectorIETFL2VPN.py b/hackfest/mock_osm/WimconnectorIETFL2VPN.py index e1273b4e483a06df23d94bdf107005ce7585fb5e..aa4ca045f41ffdc69d2ebf2fcd9b5db99ce45dbe 100644 --- a/hackfest/mock_osm/WimconnectorIETFL2VPN.py +++ b/hackfest/mock_osm/WimconnectorIETFL2VPN.py @@ -73,7 +73,7 @@ class WimconnectorIETFL2VPN(SdnConnectorBase): response = requests.get(endpoint, auth=self.auth) http_code = response.status_code except requests.exceptions.RequestException as e: - raise SdnConnectorError(e.message, http_code=503) + raise SdnConnectorError(e.response, http_code=503) if http_code != 200: raise SdnConnectorError("Failed while authenticating", http_code=http_code) diff --git a/hackfest/mock_osm/__init__.py b/hackfest/mock_osm/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/hackfest/mock_osm/__init__.py +++ b/hackfest/mock_osm/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/mock_osm/__main__.py b/hackfest/mock_osm/__main__.py index e76616eab38cc072f959231e08743e312cf6b0b2..669da2b5e6a1729f35d2958f2d7aa68c0413287d 100644 --- a/hackfest/mock_osm/__main__.py +++ b/hackfest/mock_osm/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -18,7 +18,7 @@ from .MockOSM import MockOSM LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -WIM_URL = 'http://10.0.2.15:80' +WIM_URL = 'http://10.0.2.10:80' WIM_USERNAME = 'admin' WIM_PASSWORD = 'admin' diff --git a/hackfest/netconf-oc/device_definition.py b/hackfest/netconf-oc/device_definition.py index 15efdee42794ebba474ed4a1c5573e6ed5b688a1..6e737f55675e811ebdd96a4d7471f1b4438c8e52 100644 --- a/hackfest/netconf-oc/device_definition.py +++ b/hackfest/netconf-oc/device_definition.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from lxml import etree from netconf import util from pyangbind.lib.serialise import pybindIETFXMLEncoder diff --git a/hackfest/netconf-oc/interfaces.xml b/hackfest/netconf-oc/interfaces.xml index 8358a0595573953b61c28f0deeca2e99d554f4ce..c47fc44e3ba9ea0290823eb42feaa444d6179526 100644 --- a/hackfest/netconf-oc/interfaces.xml +++ b/hackfest/netconf-oc/interfaces.xml @@ -1,4 +1,20 @@ + + diff --git a/hackfest/netconf-oc/platform.xml b/hackfest/netconf-oc/platform.xml index 434dc4c9bad3ecea4da9c8ad776c946eb5045f3a..04c53f559b12bb6dd4364089fb3ed43ba9967059 100644 --- a/hackfest/netconf-oc/platform.xml +++ b/hackfest/netconf-oc/platform.xml @@ -1,4 +1,20 @@ + + diff --git a/hackfest/netconf-oc/server_openconfig.py b/hackfest/netconf-oc/server_openconfig.py index 08a68d42f8aab89349793bfd182f2360ef389bd9..fe4085e3999c3fa4a8ee15fc627cf1656f855b96 100644 --- a/hackfest/netconf-oc/server_openconfig.py +++ b/hackfest/netconf-oc/server_openconfig.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, os, sys, time from pyangbind.lib.serialise import pybindIETFXMLEncoder, pybindIETFXMLDecoder from lxml import etree diff --git a/hackfest/netconf/client_topology.py b/hackfest/netconf/client_topology.py index 5b1dd9a3e444034a5f6251e3be333847030a42d5..138468e20780b4d143a18703c5256adf821e5e80 100644 --- a/hackfest/netconf/client_topology.py +++ b/hackfest/netconf/client_topology.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from lxml import etree from netconf.client import NetconfSSHSession diff --git a/hackfest/netconf/connection/client_connection.py b/hackfest/netconf/connection/client_connection.py index 08c0eaae03fdad0f6dc6f56ceef5b8f9af38acf7..bba5e0ae95a14bed046f37d3e03ea9196152e5b3 100644 --- a/hackfest/netconf/connection/client_connection.py +++ b/hackfest/netconf/connection/client_connection.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from lxml import etree from netconf.client import NetconfSSHSession diff --git a/hackfest/netconf/connection/server_topology_connection.py b/hackfest/netconf/connection/server_topology_connection.py index 928edfb87c2ab52e9d762eee42e3d7e2cdd78529..67953e7ed74c76c481730a4445752b2a23fd8f56 100644 --- a/hackfest/netconf/connection/server_topology_connection.py +++ b/hackfest/netconf/connection/server_topology_connection.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 sys import time import logging diff --git a/hackfest/netconf/connection/topology.xml b/hackfest/netconf/connection/topology.xml index 93af480850b540669f133a76b12519f5554b8850..9baab0342e4020bbe5cb2cb0d549d73c66e7706f 100644 --- a/hackfest/netconf/connection/topology.xml +++ b/hackfest/netconf/connection/topology.xml @@ -1,3 +1,19 @@ + + diff --git a/hackfest/netconf/server_topology.py b/hackfest/netconf/server_topology.py index 84460c84b6d10ba580e1a93fd7f30a5b9ea87cb6..1320a7b00b2fe50f392e3a340579b6038f9f5cd9 100644 --- a/hackfest/netconf/server_topology.py +++ b/hackfest/netconf/server_topology.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 sys import time import logging diff --git a/hackfest/netconf/topology.xml b/hackfest/netconf/topology.xml index 93af480850b540669f133a76b12519f5554b8850..9baab0342e4020bbe5cb2cb0d549d73c66e7706f 100644 --- a/hackfest/netconf/topology.xml +++ b/hackfest/netconf/topology.xml @@ -1,3 +1,19 @@ + + diff --git a/hackfest/onos_api/onos_flows.py b/hackfest/onos_api/onos_flows.py index b2df4b5a22a7b419b4331792adf9078b0bd363a3..da57506a105116b0afa2d991df9e62ff49b6c576 100644 --- a/hackfest/onos_api/onos_flows.py +++ b/hackfest/onos_api/onos_flows.py @@ -1,4 +1,18 @@ #!/usr/bin/python +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # -*- coding: utf-8 -*- import requests diff --git a/hackfest/onos_api/onos_topology.py b/hackfest/onos_api/onos_topology.py index c008263d2a4af9bde226e564884ff5a3c800b52b..eca3285bd99468e3ca10fa611bee682c6449ebdb 100644 --- a/hackfest/onos_api/onos_topology.py +++ b/hackfest/onos_api/onos_topology.py @@ -1,4 +1,18 @@ #!/usr/bin/python +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # -*- coding: utf-8 -*- import requests diff --git a/hackfest/openconfig/generated.go b/hackfest/openconfig/generated.go index f4ab51ad2c76ba9c41601335881afce4da316868..51c51d41a8e32fa6fec395b88872479e87890da8 100644 --- a/hackfest/openconfig/generated.go +++ b/hackfest/openconfig/generated.go @@ -1,3 +1,17 @@ +// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + /* Package gostruct is a generated package which contains definitions of structs which represent a YANG schema. The generated schema can be diff --git a/hackfest/p4/__init__.py b/hackfest/p4/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/hackfest/p4/__init__.py +++ b/hackfest/p4/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/deploy_specs.sh b/hackfest/p4/deploy_specs.sh old mode 100644 new mode 100755 index b486474e2afad7305409bf410c7b8885b0afe2a8..b988123d5564684bd1bfcb776bab7f187fc628ca --- a/hackfest/p4/deploy_specs.sh +++ b/hackfest/p4/deploy_specs.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/hackfest/p4/mininet/topo-simple.py b/hackfest/p4/mininet/topo-simple.py old mode 100755 new mode 100644 diff --git a/hackfest/p4/run_test_01_bootstrap.sh b/hackfest/p4/run_test_01_bootstrap.sh index 42e647be17b0e1731a8c69fb68c2cb414fdb542c..af35fa3dc6cbd4c8ca444e1b9a9a6edc9a16578f 100755 --- a/hackfest/p4/run_test_01_bootstrap.sh +++ b/hackfest/p4/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/run_test_02_create_service.sh b/hackfest/p4/run_test_02_create_service.sh index 8fb9038d8abaff5abd36b18a316af267186f7fcc..1b5c55994534fda87e263c48c7669e2e4cd78108 100755 --- a/hackfest/p4/run_test_02_create_service.sh +++ b/hackfest/p4/run_test_02_create_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/run_test_03_delete_service.sh b/hackfest/p4/run_test_03_delete_service.sh index 96f79c0714b65f7ebfd125b7d429e23d7213549d..d641d8c4f46f83eb6ee6d20bfb90e6efd8d6f34c 100755 --- a/hackfest/p4/run_test_03_delete_service.sh +++ b/hackfest/p4/run_test_03_delete_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/run_test_04_cleanup.sh b/hackfest/p4/run_test_04_cleanup.sh index 5cb265f6f647516e0ec4da9484bff5ec7d6e488a..d87ef1a0071283b7e2e2388c8cf097335d808698 100755 --- a/hackfest/p4/run_test_04_cleanup.sh +++ b/hackfest/p4/run_test_04_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/setup.sh b/hackfest/p4/setup.sh index 195327a03fedafdc64a2d0dc34577766eda72a4f..3ab0faf9ed72c202b97eb6506c46de6d7bf5c3de 100755 --- a/hackfest/p4/setup.sh +++ b/hackfest/p4/setup.sh @@ -1,4 +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. + export POD_NAME=$(kubectl get pods -n=tfs | grep device | awk '{print $1}') diff --git a/hackfest/p4/tests/BuildDescriptors.py b/hackfest/p4/tests/BuildDescriptors.py index 5c5419190487eb5089e4a30f523dca43fa3870f2..98b78863318a7ad682fc5f970d44d02240b45a26 100644 --- a/hackfest/p4/tests/BuildDescriptors.py +++ b/hackfest/p4/tests/BuildDescriptors.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/tests/LoadDescriptors.py b/hackfest/p4/tests/LoadDescriptors.py index 33bc699af933601e4c6d4b8dbc7b0c51206241ef..b232935f4675d718d55e67fe3a76012a39398dda 100644 --- a/hackfest/p4/tests/LoadDescriptors.py +++ b/hackfest/p4/tests/LoadDescriptors.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/tests/Objects.py b/hackfest/p4/tests/Objects.py index c8b172244d714cd699ccc587e54c3751485a9a2e..97557d7394248cccaede6ccee14728d9c17dd397 100644 --- a/hackfest/p4/tests/Objects.py +++ b/hackfest/p4/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import os from typing import Dict, List, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_connect_rules, json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, @@ -28,12 +28,12 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from common.proto.kpi_sample_types_pb2 import KpiSampleType # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- Monitoring Samples --------------------------------------------------------------------------------------------- PACKET_PORT_SAMPLE_TYPES = [ diff --git a/hackfest/p4/tests/__init__.py b/hackfest/p4/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/hackfest/p4/tests/__init__.py +++ b/hackfest/p4/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/tests/test_functional_bootstrap.py b/hackfest/p4/tests/test_functional_bootstrap.py index 0254ffd2602bd8dfc0766db0b9e766f7e7e79b32..8ad3c8a9cc0b77c3276d0debcbcf6dfdcad4fdc8 100644 --- a/hackfest/p4/tests/test_functional_bootstrap.py +++ b/hackfest/p4/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/tests/test_functional_cleanup.py b/hackfest/p4/tests/test_functional_cleanup.py index ccbcb9843a03bbf095743af0753da3fe8af3bfce..5e84f47e203fb1048cf01e61c1ca089c3a5b0dd9 100644 --- a/hackfest/p4/tests/test_functional_cleanup.py +++ b/hackfest/p4/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/tests/test_functional_create_service.py b/hackfest/p4/tests/test_functional_create_service.py index 501536bdb6299091cf791438f60f7e48cb0b0626..73200b893c197fa3d4d98aeb368679f96c59641f 100644 --- a/hackfest/p4/tests/test_functional_create_service.py +++ b/hackfest/p4/tests/test_functional_create_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/p4/tests/test_functional_delete_service.py b/hackfest/p4/tests/test_functional_delete_service.py index 1be7e324080befe8c7e4719f364201ef16772fc8..4a03ed1589909d78025a87a5929bfd174f704767 100644 --- a/hackfest/p4/tests/test_functional_delete_service.py +++ b/hackfest/p4/tests/test_functional_delete_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/hackfest/restconf/connection.yaml b/hackfest/restconf/connection.yaml index abc119f26cee8be17d91cb036f5b5dcf37a8331d..c704ed742d475b609af9f20ba2adf76a50624f14 100644 --- a/hackfest/restconf/connection.yaml +++ b/hackfest/restconf/connection.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- swagger: "2.0" info: diff --git a/hackfest/restconf/connectionserver/git_push.sh b/hackfest/restconf/connectionserver/git_push.sh old mode 100644 new mode 100755 diff --git a/hackfest/restconf/connectionserver/swagger_server/database.py b/hackfest/restconf/connectionserver/swagger_server/database.py index 9a5ea9fb27287e734eb72af4e9c8958b854801c7..8794f873f7b810ce45e4e04698eed3f3f92d6a8c 100644 --- a/hackfest/restconf/connectionserver/swagger_server/database.py +++ b/hackfest/restconf/connectionserver/swagger_server/database.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from swagger_server.models.connection_connection import ConnectionConnection diff --git a/hackfest/restconf/connectionserver/swagger_server/swagger/swagger.yaml b/hackfest/restconf/connectionserver/swagger_server/swagger/swagger.yaml index 85af552040a86c147fdc96fc0f602f33046686a0..0dc82659c4bc88794451dd262a45c9b4ef209c2d 100644 --- a/hackfest/restconf/connectionserver/swagger_server/swagger/swagger.yaml +++ b/hackfest/restconf/connectionserver/swagger_server/swagger/swagger.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + openapi: 3.0.1 info: title: connection API diff --git a/hackfest/restconf/topology.yaml b/hackfest/restconf/topology.yaml index ebb0b7e3ca91597809aabddf0baea422d843db71..71f1067445fa5037569f2a5bfce49365b29a6303 100644 --- a/hackfest/restconf/topology.yaml +++ b/hackfest/restconf/topology.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- swagger: "2.0" info: diff --git a/hackfest/restconf/topologyserver/git_push.sh b/hackfest/restconf/topologyserver/git_push.sh old mode 100644 new mode 100755 diff --git a/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml b/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml index c359192088f24b3ec2fbde3a433519b7fbf1cfa7..f8ed88ea8ec21ce3d1e780285b0dd8a34f822c0d 100644 --- a/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml +++ b/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + openapi: 3.0.1 info: title: topology API diff --git a/hackfest/tapi/client/tapi-client.sh b/hackfest/tapi/client/tapi-client.sh index a591a2006b06e9dcc6f13b85d9ff870bdca0c359..084d63dee8cb0ef7653bf2d615e50d3e63d8c73e 100755 --- a/hackfest/tapi/client/tapi-client.sh +++ b/hackfest/tapi/client/tapi-client.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + #Example CURL for TAPI 2.0 #Get Context diff --git a/hackfest/tapi/server/git_push.sh b/hackfest/tapi/server/git_push.sh old mode 100644 new mode 100755 diff --git a/hackfest/tapi/server/run.sh b/hackfest/tapi/server/run.sh index 6b69692172b14f2fec299f88fa914be2eb811c01..9beaec828efcf9fefec935b35f573ee1e3aa5007 100755 --- a/hackfest/tapi/server/run.sh +++ b/hackfest/tapi/server/run.sh @@ -1,3 +1,17 @@ #!/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. + python3 -m tapi_server 8080 database/mini-ols-context.json diff --git a/hackfest/tapi/server/tapi_server/__main__.py b/hackfest/tapi/server/tapi_server/__main__.py index 580c6f80f08d0d9d08d64c14ab8296165bfdb0bb..14a73dae3984d35a9750e998c718a14f01e64261 100644 --- a/hackfest/tapi/server/tapi_server/__main__.py +++ b/hackfest/tapi/server/tapi_server/__main__.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 connexion import json diff --git a/hackfest/tapi/server/tapi_server/controllers/tapi_connectivity_controller.py b/hackfest/tapi/server/tapi_server/controllers/tapi_connectivity_controller.py index 640f5a72dacea883d145bca664810812e1d37f58..dc0118b7ac437c6fb151ff7326bda7b29a2ec26b 100644 --- a/hackfest/tapi/server/tapi_server/controllers/tapi_connectivity_controller.py +++ b/hackfest/tapi/server/tapi_server/controllers/tapi_connectivity_controller.py @@ -2559,8 +2559,42 @@ def data_tapi_commoncontext_tapi_connectivityconnectivity_context_post(body=None :rtype: None """ if connexion.request.is_json: - body = TapiConnectivityConnectivityContextWrapper.from_dict(connexion.request.get_json()) # noqa: E501 - return 'do some magic!' + #body = TapiConnectivityConnectivityContextWrapper.from_dict(connexion.request.get_json()) # noqa: E501 + raw_body = connexion.request.get_json() + if "tapi-connectivity:connectivity-service" in raw_body: + raw_body["connectivity-service"] = raw_body.pop("tapi-connectivity:connectivity-service") + if isinstance(raw_body["connectivity-service"], list) and len(raw_body["connectivity-service"]) > 0: + raw_body["connectivity-service"] = raw_body["connectivity-service"][0] + + connectivity_service = raw_body["connectivity-service"] + if "connectivity-constraint" in connectivity_service: + connectivity_constraint = connectivity_service.pop("connectivity-constraint") + if "requested-capacity" in connectivity_constraint: + connectivity_service["requested-capacity"] = connectivity_constraint.pop("requested-capacity") + if "connectivity-direction" in connectivity_constraint: + connectivity_service["connectivity-direction"] = connectivity_constraint.pop("connectivity-direction") + + body = TapiConnectivityConnectivityServiceWrapper.from_dict(raw_body) # noqa: E501 + + connection = TapiConnectivityConnection( + uuid=body.connectivity_service.uuid, + connection_end_point=[ + TapiConnectivityConnectionEndPointRef( + node_edge_point_uuid="node-1-port-3", connection_end_point_uuid="cep13"), + TapiConnectivityConnectionEndPointRef( + node_edge_point_uuid="node-3-port-2", connection_end_point_uuid="cep32"), + ] + ) + connection_ref = TapiConnectivityConnectionRef(connection.uuid) + body.connectivity_service.connection = [ connection_ref ] + + if database.context.connectivity_context is None: + database.context.connectivity_context = TapiConnectivityConnectivityContext( + connectivity_service=[], connection=[] + ) + + database.context.connectivity_context.connection.append(connection) + database.context.connectivity_context.connectivity_service.append(body.connectivity_service) def data_tapi_commoncontext_tapi_connectivityconnectivity_context_put(body=None): # noqa: E501 diff --git a/hackfest/tapi/server/tapi_server/database.py b/hackfest/tapi/server/tapi_server/database.py index 1e3e3da6a6398f1f4114fcdaaf144bb493e6486b..f1450ab5a56658933a1f001dcf5fbb6a0b7754da 100644 --- a/hackfest/tapi/server/tapi_server/database.py +++ b/hackfest/tapi/server/tapi_server/database.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from tapi_server.models.tapi_common_context import TapiCommonContext from tapi_server.models.tapi_connectivity_cep_list import TapiConnectivityCepList diff --git a/hackfest/tapi/server/tapi_server/swagger/swagger.yaml b/hackfest/tapi/server/tapi_server/swagger/swagger.yaml index abb88f1d1d4472c3725e3744fc5841dff1b3be0b..99928b9dcc5a48def3df98c02cf1cf936fdc8543 100644 --- a/hackfest/tapi/server/tapi_server/swagger/swagger.yaml +++ b/hackfest/tapi/server/tapi_server/swagger/swagger.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + openapi: 3.0.1 info: title: "tapi-notification,tapi-connectivity,tapi-topology,tapi-common,tapi-path-computation\ diff --git a/hackfest/tapi/tapi-connectivity.yaml b/hackfest/tapi/tapi-connectivity.yaml index 6cc5d39037ef0fca8ba6f6029344eade09ec7364..f70ccbdc31cd141f939006de3d449d8c951c5368 100644 --- a/hackfest/tapi/tapi-connectivity.yaml +++ b/hackfest/tapi/tapi-connectivity.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- swagger: "2.0" info: diff --git a/hackfest/tapi/tapi_app/requirements.sh b/hackfest/tapi/tapi_app/requirements.sh old mode 100644 new mode 100755 index 95832bb6628447bb1d5d6e7cd8a477468ebe5ef6..56a5b20b4efe1b109144b61c0360dd9c042db141 --- a/hackfest/tapi/tapi_app/requirements.sh +++ b/hackfest/tapi/tapi_app/requirements.sh @@ -1,4 +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. + sudo apt install graphviz pip install -r requirements.txt diff --git a/hackfest/tapi/tapi_app/tapi_app.py b/hackfest/tapi/tapi_app/tapi_app.py index 195306c7b1e0f586f03b1c625846550a2cc06c57..d0306028cd28b9cf550b8221b656dc7e1ca9f9c6 100644 --- a/hackfest/tapi/tapi_app/tapi_app.py +++ b/hackfest/tapi/tapi_app/tapi_app.py @@ -1,4 +1,18 @@ #!/usr/bin/python +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # -*- coding: utf-8 -*- import json, requests, networkx as nx diff --git a/hackfest/yang/connection/connection.py b/hackfest/yang/connection/connection.py index c404d2f5c06508a5b23d733b618dc16dc0b20a9f..1b5effbd8db66dc2284a24c53ce41023378859c8 100644 --- a/hackfest/yang/connection/connection.py +++ b/hackfest/yang/connection/connection.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from binding_connection import connection from pyangbind.lib.serialise import pybindIETFXMLEncoder import pyangbind.lib.pybindJSON as pybindJSON diff --git a/hackfest/yang/topology.py b/hackfest/yang/topology.py index 441300fb5ca91243e55bbd1995b6610109b52d7e..24f8f0d97da0daa989f1336bca9a9c609e7398b8 100644 --- a/hackfest/yang/topology.py +++ b/hackfest/yang/topology.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from binding_topology import topology from pyangbind.lib.serialise import pybindIETFXMLEncoder import pyangbind.lib.pybindJSON as pybindJSON diff --git a/hackfest/yang/topology.xml b/hackfest/yang/topology.xml index 93af480850b540669f133a76b12519f5554b8850..9baab0342e4020bbe5cb2cb0d549d73c66e7706f 100644 --- a/hackfest/yang/topology.xml +++ b/hackfest/yang/topology.xml @@ -1,3 +1,19 @@ + + diff --git a/install_requirements.sh b/install_requirements.sh index ea9385729a6199be29926e4c13b6a05152446155..f2013d275e95feb59235837dd166330288aac458 100755 --- a/install_requirements.sh +++ b/install_requirements.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/manifests/.gitlab-ci.yml b/manifests/.gitlab-ci.yml index d20b67e531c33bfeae9c796ed95488b4c81d0fe4..9444afea5e38ad05b777d0c850ac71c38d219421 100644 --- a/manifests/.gitlab-ci.yml +++ b/manifests/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,10 +14,10 @@ # Deployment of the dependency services in Kubernetes Cluster -dependencies all: - stage: dependencies - script: - - kubectl version - - kubectl get all - - kubectl apply -f "manifests/prometheus.yaml" - - kubectl get all +#dependencies all: +# stage: dependencies +# script: +# - kubectl version +# - kubectl get all +# - kubectl apply -f "manifests/prometheus.yaml" +# - kubectl get all diff --git a/manifests/cockroachdb/README.md b/manifests/cockroachdb/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bfd774f0f85ca567986ae452c30b4305b336c57e --- /dev/null +++ b/manifests/cockroachdb/README.md @@ -0,0 +1,62 @@ +# CockroachDB configuration preparation + +These steps reproduce how to generate Cockroach manifest files used in TeraFlowSDN and apply them to MicroK8s. +For stability reasons, we fix the versions providing the manifest files. +In future releases of TeraFlowSDN, we might consider dynamically downloading and modifying the files. + +- Ref: https://www.cockroachlabs.com/docs/stable/configure-cockroachdb-kubernetes.html + +## Steps: + +DEPLOY_PATH="manifests/cockroachdb" +OPERATOR_BASE_URL="https://raw.githubusercontent.com/cockroachdb/cockroach-operator/master" + +mkdir -p ${DEPLOY_PATH} + +# Apply Custom Resource Definition for the CockroachDB Operator +curl -o "${DEPLOY_PATH}/crds.yaml" "${OPERATOR_BASE_URL}/install/crds.yaml" +kubectl apply -f "${DEPLOY_PATH}/crds.yaml" + +# Deploy CockroachDB Operator +curl -o "${DEPLOY_PATH}/operator.yaml" "${OPERATOR_BASE_URL}/install/operator.yaml" +nano "${DEPLOY_PATH}/operator.yaml" +# - add env var: WATCH_NAMESPACE=%TFS_CRDB_NAMESPACE% +sed s/%TFS_CRDB_NAMESPACE%/crdb/g ${DEPLOY_PATH}/operator.yaml > ${DEPLOY_PATH}/tfs_crdb_operator.yaml +kubectl apply -f "${DEPLOY_PATH}/tfs_crdb_operator.yaml" + +# Deploy CockroachDB +curl -o "${DEPLOY_PATH}/cluster.yaml" "${OPERATOR_BASE_URL}/examples/example.yaml" +nano "${DEPLOY_PATH}/cluster.yaml" +# - set version +# - set number of replicas +kubectl create namespace crdb +kubectl apply --namespace crdb -f "${DEPLOY_PATH}/cluster.yaml" + +# Deploy CockroachDB Client +curl -o "${DEPLOY_PATH}/client-secure-operator.yaml" "${OPERATOR_BASE_URL}/examples/client-secure-operator.yaml" +kubectl create --namespace crdb -f "${DEPLOY_PATH}/client-secure-operator.yaml" + +# Add tfs user with admin rights +kubectl exec -it cockroachdb-client-secure --namespace crdb -- ./cockroach sql --certs-dir=/cockroach/cockroach-certs --host=cockroachdb-public + CREATE USER tfs WITH PASSWORD 'tfs123'; + GRANT admin TO tfs; + +# Expose CockroachDB SQL port (26257) +PORT=$(kubectl --namespace crdb get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') +PATCH='{"data": {"'${PORT}'": "crdb/cockroachdb-public:'${PORT}'"}}' +kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + +PORT_MAP='{"containerPort": '${PORT}', "hostPort": '${PORT}'}' +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}" + +# Expose CockroachDB Console port (8080) +PORT=$(kubectl --namespace crdb get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') +PATCH='{"data": {"'${PORT}'": "crdb/cockroachdb-public:'${PORT}'"}}' +kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + +PORT_MAP='{"containerPort": '${PORT}', "hostPort": '${PORT}'}' +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}" diff --git a/manifests/cockroachdb/client-secure-operator.yaml b/manifests/cockroachdb/client-secure-operator.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f7f81c8339d4ba47722a0ef2a2236178f1b9e1b0 --- /dev/null +++ b/manifests/cockroachdb/client-secure-operator.yaml @@ -0,0 +1,51 @@ +# 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. +# +# Generated, do not edit. Please edit this file instead: config/templates/client-secure-operator.yaml.in +# + +apiVersion: v1 +kind: Pod +metadata: + name: cockroachdb-client-secure +spec: + serviceAccountName: cockroachdb-sa + containers: + - name: cockroachdb-client-secure + image: cockroachdb/cockroach:v22.2.0 + imagePullPolicy: IfNotPresent + volumeMounts: + - name: client-certs + mountPath: /cockroach/cockroach-certs/ + command: + - sleep + - "2147483648" # 2^31 + terminationGracePeriodSeconds: 0 + volumes: + - name: client-certs + projected: + sources: + - secret: + name: cockroachdb-node + items: + - key: ca.crt + path: ca.crt + - secret: + name: cockroachdb-root + items: + - key: tls.crt + path: client.root.crt + - key: tls.key + path: client.root.key + defaultMode: 256 diff --git a/manifests/cockroachdb/cluster.yaml b/manifests/cockroachdb/cluster.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f7444c0067cc9c2c07b53c85d765bb81d1c20c05 --- /dev/null +++ b/manifests/cockroachdb/cluster.yaml @@ -0,0 +1,70 @@ +# 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. +# +# Generated, do not edit. Please edit this file instead: config/templates/example.yaml.in +# + +apiVersion: crdb.cockroachlabs.com/v1alpha1 +kind: CrdbCluster +metadata: + # this translates to the name of the statefulset that is created + name: cockroachdb +spec: + dataStore: + pvc: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "60Gi" + volumeMode: Filesystem + resources: + requests: + # This is intentionally low to make it work on local k3d clusters. + cpu: 100m + memory: 1Gi + limits: + cpu: 1 + memory: 4Gi + tlsEnabled: true +# You can set either a version of the db or a specific image name +# cockroachDBVersion: v22.2.0 + image: + name: cockroachdb/cockroach:v22.2.0 + # nodes refers to the number of crdb pods that are created + # via the statefulset + nodes: 3 + additionalLabels: + crdb: is-cool + # affinity is a new API field that is behind a feature gate that is + # disabled by default. To enable please see the operator.yaml file. + + # The affinity field will accept any podSpec affinity rule. + # affinity: + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 100 + # podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - cockroachdb + # topologyKey: kubernetes.io/hostname + + # nodeSelectors used to match against + # nodeSelector: + # worker-pool-name: crdb-workers diff --git a/manifests/cockroachdb/crds.yaml b/manifests/cockroachdb/crds.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1b5cd89ae7001b3e200c0de7da240b660c461f3b --- /dev/null +++ b/manifests/cockroachdb/crds.yaml @@ -0,0 +1,1385 @@ +# 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: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (unknown) + creationTimestamp: null + name: crdbclusters.crdb.cockroachlabs.com +spec: + group: crdb.cockroachlabs.com + names: + categories: + - all + - cockroachdb + kind: CrdbCluster + listKind: CrdbClusterList + plural: crdbclusters + shortNames: + - crdb + singular: crdbcluster + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: CrdbCluster is the CRD for the cockroachDB clusters API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CrdbClusterSpec defines the desired state of a CockroachDB + Cluster that the operator maintains. + properties: + additionalAnnotations: + additionalProperties: + type: string + description: (Optional) Additional custom resource annotations that + are added to all resources. Changing `AdditionalAnnotations` field + will result in cockroachDB cluster restart. + type: object + additionalArgs: + description: '(Optional) Additional command line arguments for the + `cockroach` binary Default: ""' + items: + type: string + type: array + additionalLabels: + additionalProperties: + type: string + description: (Optional) Additional custom resource labels that are + added to all resources + type: object + affinity: + description: (Optional) If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: '(Optional) AutomountServiceAccountToken determines whether + or not the stateful set pods should automount the service account + token. This is the default behavior in Kubernetes. For backward + compatibility reasons, this value defaults to `false` here. Default: + false' + type: boolean + cache: + description: '(Optional) The total size for caches (`--cache` command + line parameter) Default: "25%"' + type: string + clientTLSSecret: + description: '(Optional) The secret with a certificate and a private + key for root database user Default: ""' + type: string + cockroachDBVersion: + description: '(Optional) CockroachDBVersion sets the explicit version + of the cockroachDB image Default: ""' + type: string + dataStore: + description: Database disk storage configuration + properties: + hostPath: + description: (Optional) Directory from the host node's filesystem + properties: + path: + description: 'Path of the directory on the host. If the path + is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults to "" More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + pvc: + description: (Optional) Persistent volume to use + properties: + source: + description: (Optional) Existing PVC in the same namespace + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + spec: + description: (Optional) PVC to request a new persistent volume + properties: + accessModes: + description: 'AccessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) * An existing + custom resource that implements data population (Alpha) + In order to use custom resource types that implement + data population, the AnyVolumeDataSource feature gate + must be enabled. If the provisioner or an external controller + can support the specified data source, it will create + a new volume based on the contents of the specified + data source.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum resources + the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + 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/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + 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/' + type: object + type: object + selector: + description: A label query over volumes to consider for + binding. + 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 + storageClassName: + description: 'Name of the StorageClass required by the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: VolumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + type: object + supportsAutoResize: + description: '(Optional) SupportsAutoResize marks that a PVC will + resize without restarting the entire cluster Default: false' + type: boolean + type: object + grpcPort: + description: '(Optional) The database port (`--port` CLI parameter + when starting the service) Default: 26258' + format: int32 + type: integer + httpPort: + description: '(Optional) The web UI port (`--http-port` CLI parameter + when starting the service) Default: 8080' + format: int32 + type: integer + image: + description: (Optional) Container image information + properties: + name: + description: 'Container image with supported CockroachDB version. + This defaults to the version pinned to the operator and requires + a full container and tag/sha name. For instance: cockroachdb/cockroachdb:v20.1' + type: string + pullPolicy: + description: '(Optional) PullPolicy for the image, which defaults + to IfNotPresent. Default: IfNotPresent' + type: string + pullSecret: + description: (Optional) Secret name containing the dockerconfig + to use for a registry that requires authentication. The secret + must be configured first by the user. + type: string + required: + - name + type: object + ingress: + description: (Optional) Ingress defines the Ingress configuration + used to expose the services using Ingress + properties: + sql: + description: (Optional) Ingress options for SQL connections Adding/changing + the SQL host will result in rolling update of the crdb cluster + nodes + properties: + annotations: + additionalProperties: + type: string + description: (Optional) Annotations related to ingress resource + type: object + host: + description: host is host to be used for exposing service + type: string + ingressClassName: + description: (Optional) IngressClassName to be used by ingress + resource + type: string + tls: + description: (Optional) TLS describes the TLS certificate + info + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - host + type: object + ui: + description: (Optional) Ingress options for UI (HTTP) connections + properties: + annotations: + additionalProperties: + type: string + description: (Optional) Annotations related to ingress resource + type: object + host: + description: host is host to be used for exposing service + type: string + ingressClassName: + description: (Optional) IngressClassName to be used by ingress + resource + type: string + tls: + description: (Optional) TLS describes the TLS certificate + info + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - host + type: object + type: object + logConfigMap: + description: '(Optional) LogConfigMap define the config map which + contains log configuration used to send the logs through the proper + channels in the cockroachdb. Logging configuration is available + for cockroach version v21.1.0 onwards. The logging configuration + is taken in format of yaml file, you can check the logging configuration + here (https://www.cockroachlabs.com/docs/stable/configure-logs.html#default-logging-configuration) + The default logging for cockroach version v20.x or less is stderr, + logging API is ignored for older versions. NOTE: The `data` field + of map must contain an entry called `logging.yaml` that contains + config options.' + type: string + maxSQLMemory: + description: '(Optional) The maximum in-memory storage capacity available + to store temporary data for SQL queries (`--max-sql-memory` parameter) + Default: "25%"' + type: string + maxUnavailable: + description: (Optional) The maximum number of pods that can be unavailable + during a rolling update. This number is set in the PodDistruptionBudget + and defaults to 1. + format: int32 + type: integer + minAvailable: + description: (Optional) The min number of pods that can be unavailable + during a rolling update. This number is set in the PodDistruptionBudget + and defaults to 1. + format: int32 + type: integer + nodeSelector: + additionalProperties: + type: string + description: (Optional) If specified, the pod's nodeSelector + type: object + nodeTLSSecret: + description: '(Optional) The secret with certificates and a private + key for the TLS endpoint on the database port. The standard naming + of files is expected (tls.key, tls.crt, ca.crt) Default: ""' + type: string + nodes: + description: Number of nodes (pods) in the cluster + format: int32 + minimum: 3 + type: integer + podEnvVariables: + description: '(Optional) PodEnvVariables is a slice of environment + variables that are added to the pods Default: (empty list)' + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previous defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a double $$, ie: + $$(VAR_NAME). Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + resources: + description: '(Optional) Database container resource limits. Any container + limits can be specified. Default: (not specified)' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + 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/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + 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/' + type: object + type: object + sqlPort: + description: '(Optional) The SQL Port number Default: 26257' + format: int32 + type: integer + tlsEnabled: + description: (Optional) TLSEnabled determines if TLS is enabled for + your CockroachDB Cluster + type: boolean + tolerations: + description: (Optional) Tolerations for scheduling pods onto some + dedicated nodes + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: (Optional) If specified, the pod's topology spread constraints + items: + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching pods. Pods + that match this label selector are counted to determine the + number of pods in their corresponding topology domain. + 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 + maxSkew: + description: 'MaxSkew describes the degree to which pods may + be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between the number + of matching pods in the target topology and the global minimum. + For example, in a 3-zone cluster, MaxSkew is set to 1, and + pods with the same labelSelector spread as 1/1/0: | zone1 + | zone2 | zone3 | | P | P | | - if MaxSkew is + 1, incoming pod can only be scheduled to zone3 to become 1/1/1; + scheduling it onto zone1(zone2) would make the ActualSkew(2-0) + on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies that satisfy + it. It''s a required field. Default value is 1 and 0 is not + allowed.' + format: int32 + type: integer + topologyKey: + description: TopologyKey is the key of node labels. Nodes that + have a label with this key and identical values are considered + to be in the same topology. We consider each + as a "bucket", and try to put balanced number of pods into + each bucket. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a + pod if it doesn''t satisfy the spread constraint. - DoNotSchedule + (default) tells the scheduler not to schedule it. - ScheduleAnyway + tells the scheduler to schedule the pod in any location, but + giving higher precedence to topologies that would help reduce + the skew. A constraint is considered "Unsatisfiable" for + an incoming pod if and only if every possible node assigment + for that pod would violate "MaxSkew" on some topology. For + example, in a 3-zone cluster, MaxSkew is set to 1, and pods + with the same labelSelector spread as 3/1/1: | zone1 | zone2 + | zone3 | | P P P | P | P | If WhenUnsatisfiable is + set to DoNotSchedule, incoming pod can only be scheduled to + zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on + zone2(zone3) satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t make it *more* + imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + required: + - dataStore + - nodes + type: object + status: + description: CrdbClusterStatus defines the observed state of Cluster + properties: + clusterStatus: + description: OperatorStatus represent the status of the operator(Failed, + Starting, Running or Other) + type: string + conditions: + description: List of conditions representing the current status of + the cluster resource. + items: + description: ClusterCondition represents cluster status as it is + perceived by the operator + properties: + lastTransitionTime: + description: The time when the condition was updated + format: date-time + type: string + status: + description: 'Condition status: True, False or Unknown' + type: string + type: + description: Type/Name of the condition + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + crdbcontainerimage: + description: CrdbContainerImage is the container that will be installed + type: string + operatorActions: + items: + description: ClusterAction represents cluster status as it is perceived + by the operator + properties: + lastTransitionTime: + description: The time when the condition was updated + format: date-time + type: string + message: + description: (Optional) Message related to the status of the + action + type: string + status: + description: 'Action status: Failed, Finished or Unknown' + type: string + type: + description: Type/Name of the action + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + sqlHost: + description: SQLHost is the host to be used with SQL ingress + type: string + version: + description: Database service version. Not populated and is just a + placeholder currently. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests/cockroachdb/operator.yaml b/manifests/cockroachdb/operator.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2be72d329b48bc6f45d66f811c299140cda85e27 --- /dev/null +++ b/manifests/cockroachdb/operator.yaml @@ -0,0 +1,616 @@ +# 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 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: cockroach-operator + name: cockroach-operator-sa + namespace: cockroach-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: cockroach-operator-role +rules: +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - get + - patch + - update +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - patch + - update +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - statefulsets/finalizers + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - statefulsets/scale + verbs: + - get + - update + - watch +- apiGroups: + - apps + resources: + - statefulsets/status + verbs: + - get + - patch + - update +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs/finalizers + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs/status + verbs: + - get +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests/approval + verbs: + - update +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - list + - update +- apiGroups: + - "" + resources: + - pods + verbs: + - delete + - deletecollection + - get + - list +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - services/finalizers + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services/status + verbs: + - get + - patch + - update +- apiGroups: + - crdb.cockroachlabs.com + resources: + - crdbclusters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crdb.cockroachlabs.com + resources: + - crdbclusters/finalizers + verbs: + - update +- apiGroups: + - crdb.cockroachlabs.com + resources: + - crdbclusters/status + verbs: + - get + - patch + - update +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/finalizers + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - get +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - policy + resources: + - poddisruptionbudgets/finalizers + verbs: + - get + - list + - watch +- apiGroups: + - policy + resources: + - poddisruptionbudgets/status + verbs: + - get +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - get + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - get + - list + - watch +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cockroach-operator-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cockroach-operator-role +subjects: +- kind: ServiceAccount + name: cockroach-operator-sa + namespace: cockroach-operator-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: cockroach-operator + name: cockroach-operator-webhook-service + namespace: cockroach-operator-system +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + app: cockroach-operator +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: cockroach-operator + name: cockroach-operator-manager + namespace: cockroach-operator-system +spec: + replicas: 1 + selector: + matchLabels: + app: cockroach-operator + template: + metadata: + labels: + app: cockroach-operator + spec: + containers: + - args: + - -zap-log-level + - info + env: + - name: RELATED_IMAGE_COCKROACH_v20_1_4 + value: cockroachdb/cockroach:v20.1.4 + - name: RELATED_IMAGE_COCKROACH_v20_1_5 + value: cockroachdb/cockroach:v20.1.5 + - name: RELATED_IMAGE_COCKROACH_v20_1_8 + value: cockroachdb/cockroach:v20.1.8 + - name: RELATED_IMAGE_COCKROACH_v20_1_11 + value: cockroachdb/cockroach:v20.1.11 + - name: RELATED_IMAGE_COCKROACH_v20_1_12 + value: cockroachdb/cockroach:v20.1.12 + - name: RELATED_IMAGE_COCKROACH_v20_1_13 + value: cockroachdb/cockroach:v20.1.13 + - name: RELATED_IMAGE_COCKROACH_v20_1_15 + value: cockroachdb/cockroach:v20.1.15 + - name: RELATED_IMAGE_COCKROACH_v20_1_16 + value: cockroachdb/cockroach:v20.1.16 + - name: RELATED_IMAGE_COCKROACH_v20_1_17 + value: cockroachdb/cockroach:v20.1.17 + - name: RELATED_IMAGE_COCKROACH_v20_2_0 + value: cockroachdb/cockroach:v20.2.0 + - name: RELATED_IMAGE_COCKROACH_v20_2_1 + value: cockroachdb/cockroach:v20.2.1 + - name: RELATED_IMAGE_COCKROACH_v20_2_2 + value: cockroachdb/cockroach:v20.2.2 + - name: RELATED_IMAGE_COCKROACH_v20_2_3 + value: cockroachdb/cockroach:v20.2.3 + - name: RELATED_IMAGE_COCKROACH_v20_2_4 + value: cockroachdb/cockroach:v20.2.4 + - name: RELATED_IMAGE_COCKROACH_v20_2_5 + value: cockroachdb/cockroach:v20.2.5 + - name: RELATED_IMAGE_COCKROACH_v20_2_6 + value: cockroachdb/cockroach:v20.2.6 + - name: RELATED_IMAGE_COCKROACH_v20_2_8 + value: cockroachdb/cockroach:v20.2.8 + - name: RELATED_IMAGE_COCKROACH_v20_2_9 + value: cockroachdb/cockroach:v20.2.9 + - name: RELATED_IMAGE_COCKROACH_v20_2_10 + value: cockroachdb/cockroach:v20.2.10 + - name: RELATED_IMAGE_COCKROACH_v20_2_11 + value: cockroachdb/cockroach:v20.2.11 + - name: RELATED_IMAGE_COCKROACH_v20_2_12 + value: cockroachdb/cockroach:v20.2.12 + - name: RELATED_IMAGE_COCKROACH_v20_2_13 + value: cockroachdb/cockroach:v20.2.13 + - name: RELATED_IMAGE_COCKROACH_v20_2_14 + value: cockroachdb/cockroach:v20.2.14 + - name: RELATED_IMAGE_COCKROACH_v20_2_15 + value: cockroachdb/cockroach:v20.2.15 + - name: RELATED_IMAGE_COCKROACH_v20_2_16 + value: cockroachdb/cockroach:v20.2.16 + - name: RELATED_IMAGE_COCKROACH_v20_2_17 + value: cockroachdb/cockroach:v20.2.17 + - name: RELATED_IMAGE_COCKROACH_v20_2_18 + value: cockroachdb/cockroach:v20.2.18 + - name: RELATED_IMAGE_COCKROACH_v20_2_19 + value: cockroachdb/cockroach:v20.2.19 + - name: RELATED_IMAGE_COCKROACH_v21_1_0 + value: cockroachdb/cockroach:v21.1.0 + - name: RELATED_IMAGE_COCKROACH_v21_1_1 + value: cockroachdb/cockroach:v21.1.1 + - name: RELATED_IMAGE_COCKROACH_v21_1_2 + value: cockroachdb/cockroach:v21.1.2 + - name: RELATED_IMAGE_COCKROACH_v21_1_3 + value: cockroachdb/cockroach:v21.1.3 + - name: RELATED_IMAGE_COCKROACH_v21_1_4 + value: cockroachdb/cockroach:v21.1.4 + - name: RELATED_IMAGE_COCKROACH_v21_1_5 + value: cockroachdb/cockroach:v21.1.5 + - name: RELATED_IMAGE_COCKROACH_v21_1_6 + value: cockroachdb/cockroach:v21.1.6 + - name: RELATED_IMAGE_COCKROACH_v21_1_7 + value: cockroachdb/cockroach:v21.1.7 + - name: RELATED_IMAGE_COCKROACH_v21_1_9 + value: cockroachdb/cockroach:v21.1.9 + - name: RELATED_IMAGE_COCKROACH_v21_1_10 + value: cockroachdb/cockroach:v21.1.10 + - name: RELATED_IMAGE_COCKROACH_v21_1_11 + value: cockroachdb/cockroach:v21.1.11 + - name: RELATED_IMAGE_COCKROACH_v21_1_12 + value: cockroachdb/cockroach:v21.1.12 + - name: RELATED_IMAGE_COCKROACH_v21_1_13 + value: cockroachdb/cockroach:v21.1.13 + - name: RELATED_IMAGE_COCKROACH_v21_1_14 + value: cockroachdb/cockroach:v21.1.14 + - name: RELATED_IMAGE_COCKROACH_v21_1_15 + value: cockroachdb/cockroach:v21.1.15 + - name: RELATED_IMAGE_COCKROACH_v21_1_16 + value: cockroachdb/cockroach:v21.1.16 + - name: RELATED_IMAGE_COCKROACH_v21_1_17 + value: cockroachdb/cockroach:v21.1.17 + - name: RELATED_IMAGE_COCKROACH_v21_1_18 + value: cockroachdb/cockroach:v21.1.18 + - name: RELATED_IMAGE_COCKROACH_v21_1_19 + value: cockroachdb/cockroach:v21.1.19 + - name: RELATED_IMAGE_COCKROACH_v21_1_20 + value: cockroachdb/cockroach:v21.1.20 + - name: RELATED_IMAGE_COCKROACH_v21_1_21 + value: cockroachdb/cockroach:v21.1.21 + - name: RELATED_IMAGE_COCKROACH_v21_2_0 + value: cockroachdb/cockroach:v21.2.0 + - name: RELATED_IMAGE_COCKROACH_v21_2_1 + value: cockroachdb/cockroach:v21.2.1 + - name: RELATED_IMAGE_COCKROACH_v21_2_2 + value: cockroachdb/cockroach:v21.2.2 + - name: RELATED_IMAGE_COCKROACH_v21_2_3 + value: cockroachdb/cockroach:v21.2.3 + - name: RELATED_IMAGE_COCKROACH_v21_2_4 + value: cockroachdb/cockroach:v21.2.4 + - name: RELATED_IMAGE_COCKROACH_v21_2_5 + value: cockroachdb/cockroach:v21.2.5 + - name: RELATED_IMAGE_COCKROACH_v21_2_7 + value: cockroachdb/cockroach:v21.2.7 + - name: RELATED_IMAGE_COCKROACH_v21_2_8 + value: cockroachdb/cockroach:v21.2.8 + - name: RELATED_IMAGE_COCKROACH_v21_2_9 + value: cockroachdb/cockroach:v21.2.9 + - name: RELATED_IMAGE_COCKROACH_v21_2_10 + value: cockroachdb/cockroach:v21.2.10 + - name: RELATED_IMAGE_COCKROACH_v21_2_11 + value: cockroachdb/cockroach:v21.2.11 + - name: RELATED_IMAGE_COCKROACH_v21_2_12 + value: cockroachdb/cockroach:v21.2.12 + - name: RELATED_IMAGE_COCKROACH_v21_2_13 + value: cockroachdb/cockroach:v21.2.13 + - name: RELATED_IMAGE_COCKROACH_v21_2_14 + value: cockroachdb/cockroach:v21.2.14 + - name: RELATED_IMAGE_COCKROACH_v21_2_15 + value: cockroachdb/cockroach:v21.2.15 + - name: RELATED_IMAGE_COCKROACH_v21_2_16 + value: cockroachdb/cockroach:v21.2.16 + - name: RELATED_IMAGE_COCKROACH_v21_2_17 + value: cockroachdb/cockroach:v21.2.17 + - name: RELATED_IMAGE_COCKROACH_v22_1_0 + value: cockroachdb/cockroach:v22.1.0 + - name: RELATED_IMAGE_COCKROACH_v22_1_1 + value: cockroachdb/cockroach:v22.1.1 + - name: RELATED_IMAGE_COCKROACH_v22_1_2 + value: cockroachdb/cockroach:v22.1.2 + - name: RELATED_IMAGE_COCKROACH_v22_1_3 + value: cockroachdb/cockroach:v22.1.3 + - name: RELATED_IMAGE_COCKROACH_v22_1_4 + value: cockroachdb/cockroach:v22.1.4 + - name: RELATED_IMAGE_COCKROACH_v22_1_5 + value: cockroachdb/cockroach:v22.1.5 + - name: RELATED_IMAGE_COCKROACH_v22_1_7 + value: cockroachdb/cockroach:v22.1.7 + - name: RELATED_IMAGE_COCKROACH_v22_1_8 + value: cockroachdb/cockroach:v22.1.8 + - name: RELATED_IMAGE_COCKROACH_v22_1_10 + value: cockroachdb/cockroach:v22.1.10 + - name: RELATED_IMAGE_COCKROACH_v22_1_11 + value: cockroachdb/cockroach:v22.1.11 + - name: RELATED_IMAGE_COCKROACH_v22_1_12 + value: cockroachdb/cockroach:v22.1.12 + - name: RELATED_IMAGE_COCKROACH_v22_2_0 + value: cockroachdb/cockroach:v22.2.0 + - name: OPERATOR_NAME + value: cockroachdb + - name: WATCH_NAMESPACE + value: %TFS_CRDB_NAMESPACE% + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: cockroachdb/cockroach-operator:v2.9.0 + imagePullPolicy: IfNotPresent + name: cockroach-operator + resources: + requests: + cpu: 10m + memory: 32Mi + serviceAccountName: cockroach-operator-sa +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: cockroach-operator-mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: cockroach-operator-webhook-service + namespace: cockroach-operator-system + path: /mutate-crdb-cockroachlabs-com-v1alpha1-crdbcluster + failurePolicy: Fail + name: mcrdbcluster.kb.io + rules: + - apiGroups: + - crdb.cockroachlabs.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - crdbclusters + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: cockroach-operator-validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: cockroach-operator-webhook-service + namespace: cockroach-operator-system + path: /validate-crdb-cockroachlabs-com-v1alpha1-crdbcluster + failurePolicy: Fail + name: vcrdbcluster.kb.io + rules: + - apiGroups: + - crdb.cockroachlabs.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - crdbclusters + sideEffects: None diff --git a/manifests/cockroachdb/single-node.yaml b/manifests/cockroachdb/single-node.yaml new file mode 100644 index 0000000000000000000000000000000000000000..72454a0904fa70b6b4062dae8ef7e2e5d8625648 --- /dev/null +++ b/manifests/cockroachdb/single-node.yaml @@ -0,0 +1,84 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: cockroachdb-public + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: cockroachdb + app.kubernetes.io/name: cockroachdb +spec: + type: ClusterIP + selector: + app.kubernetes.io/component: database + app.kubernetes.io/instance: cockroachdb + app.kubernetes.io/name: cockroachdb + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + - name: sql + port: 26257 + protocol: TCP + targetPort: 26257 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: cockroachdb +spec: + selector: + matchLabels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: cockroachdb + app.kubernetes.io/name: cockroachdb + serviceName: "cockroachdb-public" + replicas: 1 + minReadySeconds: 5 + template: + metadata: + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: cockroachdb + app.kubernetes.io/name: cockroachdb + spec: + terminationGracePeriodSeconds: 10 + restartPolicy: Always + containers: + - name: cockroachdb + image: cockroachdb/cockroach:latest-v22.2 + args: + - start-single-node + ports: + - containerPort: 8080 + name: http + - containerPort: 26257 + name: sql + env: + - name: COCKROACH_DATABASE + value: "%CRDB_DATABASE%" + - name: COCKROACH_USER + value: "%CRDB_USERNAME%" + - name: COCKROACH_PASSWORD + value: "%CRDB_PASSWORD%" + resources: + requests: + cpu: "250m" + memory: 1Gi + limits: + cpu: "1" + memory: 2Gi diff --git a/manifests/computeservice.yaml b/manifests/computeservice.yaml index 0c8d0a6724a49f4dec0f903570ff04e49cb4e793..7e40ef988bc7dcb77960b224dfe5626ee95cfdfb 100644 --- a/manifests/computeservice.yaml +++ b/manifests/computeservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/compute:latest + image: labs.etsi.org:5050/tfs/controller/compute:latest imagePullPolicy: Always ports: - containerPort: 8080 diff --git a/manifests/contextservice.yaml b/manifests/contextservice.yaml index 80d6c94f90c7ad400c07a6591bf733ec78990c77..b1e6eb89dc4ec92409dbd05bbe668987ea93828f 100644 --- a/manifests/contextservice.yaml +++ b/manifests/contextservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,35 +28,22 @@ spec: spec: terminationGracePeriodSeconds: 5 containers: - #- name: redis - # image: redis:6.2 - # ports: - # - containerPort: 6379 - # resources: - # requests: - # cpu: 100m - # memory: 128Mi - # limits: - # cpu: 500m - # memory: 1024Mi - name: server - image: registry.gitlab.com/teraflow-h2020/controller/context:latest + image: labs.etsi.org:5050/tfs/controller/context:latest imagePullPolicy: Always ports: - containerPort: 1010 - - containerPort: 8080 - containerPort: 9192 env: - - name: DB_BACKEND - value: "inmemory" - name: MB_BACKEND - value: "inmemory" - #- name: REDIS_DATABASE_ID - # value: "0" + value: "nats" - name: LOG_LEVEL value: "INFO" - - name: POPULATE_FAKE_DATA - value: "false" + envFrom: + - secretRef: + name: crdb-data + - secretRef: + name: nats-data readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:1010"] @@ -86,10 +73,6 @@ spec: protocol: TCP port: 1010 targetPort: 1010 - - name: http - protocol: TCP - port: 8080 - targetPort: 8080 - name: metrics protocol: TCP port: 9192 diff --git a/manifests/dbscanservingservice.yaml b/manifests/dbscanservingservice.yaml index 9553ed556bddaa437d89881f0c4220ae6e418239..ae920143454da2c63bccc6eb74ea75670bad6eff 100644 --- a/manifests/dbscanservingservice.yaml +++ b/manifests/dbscanservingservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/dbscanserving:latest + image: labs.etsi.org:5050/tfs/controller/dbscanserving:latest imagePullPolicy: Always ports: - containerPort: 10006 diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml index 83daa41f3c0cdf8e84b02dfc0ad18d8f7644e57b..ca2c81f0f2e5d874066464ab0537adeec734cfbb 100644 --- a/manifests/deviceservice.yaml +++ b/manifests/deviceservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -29,7 +29,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/device:latest + image: labs.etsi.org:5050/tfs/controller/device:latest imagePullPolicy: Always ports: - containerPort: 2020 diff --git a/manifests/dltservice.yaml b/manifests/dltservice.yaml index 0f6b5bb9df1ccfc6057c0746058da6754233376a..5e8f745f78b14ea4f8881b8992ef788ce89fdcc2 100644 --- a/manifests/dltservice.yaml +++ b/manifests/dltservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: connector - image: registry.gitlab.com/teraflow-h2020/controller/dlt-connector:latest + image: labs.etsi.org:5050/tfs/controller/dlt-connector:latest imagePullPolicy: Always ports: - containerPort: 8080 @@ -55,7 +55,7 @@ spec: cpu: 500m memory: 512Mi - name: gateway - image: registry.gitlab.com/teraflow-h2020/controller/dlt-gateway:latest + image: labs.etsi.org:5050/tfs/controller/dlt-gateway:latest imagePullPolicy: Always ports: - containerPort: 50051 diff --git a/manifests/interdomainservice.yaml b/manifests/interdomainservice.yaml index b275035f62c68eeb8d28f1892909650ca10defee..79acf96def508837fd0b3def816d3e4c4e20a368 100644 --- a/manifests/interdomainservice.yaml +++ b/manifests/interdomainservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/interdomain:latest + image: labs.etsi.org:5050/tfs/controller/interdomain:latest imagePullPolicy: Always ports: - containerPort: 10010 diff --git a/manifests/l3_attackmitigatorservice.yaml b/manifests/l3_attackmitigatorservice.yaml index 2240776ebb2e234b58febe9520a4b9e07d42b6d4..dec1bc4d936a9db5758679691f0fb130a5d67324 100644 --- a/manifests/l3_attackmitigatorservice.yaml +++ b/manifests/l3_attackmitigatorservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/l3_attackmitigator:latest + image: labs.etsi.org:5050/tfs/controller/l3_attackmitigator:latest imagePullPolicy: Always ports: - containerPort: 10002 diff --git a/manifests/l3_centralizedattackdetectorservice.yaml b/manifests/l3_centralizedattackdetectorservice.yaml index fa7ee9dccd99982d35d7f7705e463ecee30c7c9b..0ef23ba512ac5397203baa4195ceebe17cf6c743 100644 --- a/manifests/l3_centralizedattackdetectorservice.yaml +++ b/manifests/l3_centralizedattackdetectorservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/l3_centralizedattackdetector:latest + image: labs.etsi.org:5050/tfs/controller/l3_centralizedattackdetector:latest imagePullPolicy: Always ports: - containerPort: 10001 diff --git a/manifests/l3_distributedattackdetectorservice.yaml b/manifests/l3_distributedattackdetectorservice.yaml index 6b28f68dd5e08561eb29e4512af330b26f6408cf..b363c1d5c5f82083d525959d6aedf337554f604a 100644 --- a/manifests/l3_distributedattackdetectorservice.yaml +++ b/manifests/l3_distributedattackdetectorservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/l3_distributedattackdetector:latest + image: labs.etsi.org:5050/tfs/controller/l3_distributedattackdetector:latest imagePullPolicy: Always ports: - containerPort: 10000 diff --git a/manifests/load_generatorservice.yaml b/manifests/load_generatorservice.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b94e11e725757fa2ec67de19f98ecfa6a03f085b --- /dev/null +++ b/manifests/load_generatorservice.yaml @@ -0,0 +1,67 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: load-generatorservice +spec: + selector: + matchLabels: + app: load-generatorservice + replicas: 1 + template: + metadata: + labels: + app: load-generatorservice + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: labs.etsi.org:5050/tfs/controller/load_generator:latest + imagePullPolicy: Always + ports: + - containerPort: 50052 + env: + - name: LOG_LEVEL + value: "INFO" + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:50052"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:50052"] + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 500m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: load-generatorservice + labels: + app: load-generatorservice +spec: + type: ClusterIP + selector: + app: load-generatorservice + ports: + - name: grpc + protocol: TCP + port: 50052 + targetPort: 50052 diff --git a/manifests/mock_blockchain.yaml b/manifests/mock_blockchain.yaml index bf9abac703b263ad6a843f0d70848dde94a4ab97..1093610f8a0cf4d735e16e99df56cb78fd6481fc 100644 --- a/manifests/mock_blockchain.yaml +++ b/manifests/mock_blockchain.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/mock_blockchain:latest + image: labs.etsi.org:5050/tfs/controller/mock_blockchain:latest imagePullPolicy: Always ports: - containerPort: 50051 diff --git a/manifests/monitoringservice.yaml b/manifests/monitoringservice.yaml index aed8d1c51e5e84abec11dcc272c786b208dd9556..4447a1427980be6554228087924bf8e4ca775758 100644 --- a/manifests/monitoringservice.yaml +++ b/manifests/monitoringservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,42 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: monitoringdb -spec: - selector: - matchLabels: - app: monitoringservice - serviceName: "monitoringservice" - replicas: 1 - template: - metadata: - labels: - app: monitoringservice - spec: - terminationGracePeriodSeconds: 5 - restartPolicy: Always - containers: - - name: metricsdb - image: questdb/questdb - ports: - - name: http - containerPort: 9000 - protocol: TCP - - name: influxdb - containerPort: 9009 - protocol: TCP - - name: postgre - containerPort: 8812 - protocol: TCP - env: - - name: QDB_CAIRO_COMMIT_LAG - value: "1000" - - name: QDB_CAIRO_MAX_UNCOMMITTED_ROWS - value: "100000" ---- apiVersion: apps/v1 kind: Deployment metadata: @@ -63,29 +27,19 @@ spec: app: monitoringservice spec: terminationGracePeriodSeconds: 5 - restartPolicy: Always containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/monitoring:latest + image: labs.etsi.org:5050/tfs/controller/monitoring:latest imagePullPolicy: Always ports: - - name: grpc - containerPort: 7070 - protocol: TCP - - name: metrics - containerPort: 9192 - protocol: TCP + - containerPort: 7070 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" - - name: METRICSDB_HOSTNAME - value: "monitoringservice" - - name: METRICSDB_ILP_PORT - value: "9009" - - name: METRICSDB_REST_PORT - value: "9000" - - name: METRICSDB_TABLE - value: "monitoring" + envFrom: + - secretRef: + name: qdb-data readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:7070"] @@ -94,11 +48,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:7070"] resources: requests: - cpu: 250m - memory: 512Mi + cpu: 50m + memory: 64Mi limits: - cpu: 700m - memory: 1024Mi + cpu: 500m + memory: 512Mi --- apiVersion: v1 kind: Service @@ -115,41 +69,7 @@ spec: protocol: TCP port: 7070 targetPort: 7070 - - name: http - protocol: TCP - port: 9000 - targetPort: 9000 - - name: influxdb - protocol: TCP - port: 9009 - targetPort: 9009 - - name: postgre - protocol: TCP - port: 8812 - targetPort: 8812 - name: metrics protocol: TCP port: 9192 targetPort: 9192 - ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: access-monitoring -spec: - podSelector: - matchLabels: - app: monitoringservice - ingress: - - from: [] - ports: - - port: 7070 - - port: 8812 - - from: - - podSelector: - matchLabels: - app: monitoringservice - ports: - - port: 9009 - - port: 9000 diff --git a/manifests/nginx_ingress_http.yaml b/manifests/nginx_ingress_http.yaml index 50ff81c79eaa02647562456809226d1aed847204..5db05d4af0e3594edd6186a5adbcb6733ed7d5c8 100644 --- a/manifests/nginx_ingress_http.yaml +++ b/manifests/nginx_ingress_http.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: @@ -22,13 +36,13 @@ spec: name: webuiservice port: number: 3000 - - path: /context(/|$)(.*) - pathType: Prefix - backend: - service: - name: contextservice - port: - number: 8080 + #- path: /context(/|$)(.*) + # pathType: Prefix + # backend: + # service: + # name: contextservice + # port: + # number: 8080 - path: /()(restconf/.*) pathType: Prefix backend: diff --git a/manifests/opticalattackmitigatorservice.yaml b/manifests/opticalattackmitigatorservice.yaml index afe2e4069fbae2fd3b5300da614b4deb5d785fab..bfac05e40917aeca1f55c68ebf845937b46c9cdb 100644 --- a/manifests/opticalattackmitigatorservice.yaml +++ b/manifests/opticalattackmitigatorservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/opticalattackmitigator:latest + image: labs.etsi.org:5050/tfs/controller/opticalattackmitigator:latest imagePullPolicy: Always ports: - containerPort: 10007 diff --git a/manifests/opticalcentralizedattackdetectorservice.yaml b/manifests/opticalcentralizedattackdetectorservice.yaml index 664bcb54348e533ff40c7f882b5668f727a39053..13d4d97c222699544dc051564ec1609cad7ed7e1 100644 --- a/manifests/opticalcentralizedattackdetectorservice.yaml +++ b/manifests/opticalcentralizedattackdetectorservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -28,7 +28,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/opticalcentralizedattackdetector:latest + image: labs.etsi.org:5050/tfs/controller/opticalcentralizedattackdetector:latest imagePullPolicy: Always ports: - containerPort: 10005 diff --git a/manifests/pathcompservice.yaml b/manifests/pathcompservice.yaml index e9b890e76ca45cb2e56e87570d2dd01285f3fc50..fd3599f429f48ebb3cf3f8d802f8f61f00e1b41d 100644 --- a/manifests/pathcompservice.yaml +++ b/manifests/pathcompservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -29,7 +29,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: frontend - image: registry.gitlab.com/teraflow-h2020/controller/pathcomp-frontend:latest + image: labs.etsi.org:5050/tfs/controller/pathcomp-frontend:latest imagePullPolicy: Always ports: - containerPort: 10020 @@ -51,7 +51,7 @@ spec: cpu: 500m memory: 512Mi - name: backend - image: registry.gitlab.com/teraflow-h2020/controller/pathcomp-backend:latest + image: labs.etsi.org:5050/tfs/controller/pathcomp-backend:latest imagePullPolicy: Always #readinessProbe: # httpGet: diff --git a/manifests/prometheus.yaml b/manifests/prometheus.yaml index 221123eea5cf8ba61d078ccfccd697d7c6c01127..43a766b6e2ae67e36d161c3063a8a2d3ccc875d3 100644 --- a/manifests/prometheus.yaml +++ b/manifests/prometheus.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/manifests/questdb/manifest.yaml b/manifests/questdb/manifest.yaml new file mode 100644 index 0000000000000000000000000000000000000000..50a2ce2c668603fe39a3d2b42fc6e5461dd7ef93 --- /dev/null +++ b/manifests/questdb/manifest.yaml @@ -0,0 +1,67 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: StatefulSet +metadata: + name: questdb +spec: + selector: + matchLabels: + app: questdb + serviceName: "questdb-public" + replicas: 1 + template: + metadata: + labels: + app: questdb + spec: + terminationGracePeriodSeconds: 5 + restartPolicy: Always + containers: + - name: metricsdb + image: questdb/questdb + ports: + - containerPort: 9000 + - containerPort: 9009 + - containerPort: 8812 + env: + - name: QDB_CAIRO_COMMIT_LAG + value: "1000" + - name: QDB_CAIRO_MAX_UNCOMMITTED_ROWS + value: "100000" +--- +apiVersion: v1 +kind: Service +metadata: + name: questdb-public + labels: + app: questdb +spec: + type: ClusterIP + selector: + app: questdb + ports: + - name: http + protocol: TCP + port: 9000 + targetPort: 9000 + - name: ilp + protocol: TCP + port: 9009 + targetPort: 9009 + - name: sql + protocol: TCP + port: 8812 + targetPort: 8812 diff --git a/manifests/servicemonitors.yaml b/manifests/servicemonitors.yaml index ad5f042baa273d67d646a9168be1e0c0b1133ec1..06c3390f4fddbcb6f8adec5d931989cc8a41cc68 100644 --- a/manifests/servicemonitors.yaml +++ b/manifests/servicemonitors.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index d9ecc998e17947320ae380e6017505a84ffcd309..3fa4a6e0dc256ba964fd4ee26a8b7095bb2303f4 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -29,7 +29,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/service:latest + image: labs.etsi.org:5050/tfs/controller/service:latest imagePullPolicy: Always ports: - containerPort: 3030 diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml index ff4b41fe7c709acf0d58c9c73b9f6198104a89fd..447f6a1c77cc6862db3df3e83b73add3257a5c0d 100644 --- a/manifests/sliceservice.yaml +++ b/manifests/sliceservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -29,7 +29,7 @@ spec: terminationGracePeriodSeconds: 5 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/slice:latest + image: labs.etsi.org:5050/tfs/controller/slice:latest imagePullPolicy: Always ports: - containerPort: 4040 diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml index be400c6911a6ea69819825545852746190145333..f25dbf6e501775d56f266699b1474429b42b2015 100644 --- a/manifests/webuiservice.yaml +++ b/manifests/webuiservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -32,7 +32,7 @@ spec: - 0 containers: - name: server - image: registry.gitlab.com/teraflow-h2020/controller/webui:latest + image: labs.etsi.org:5050/tfs/controller/webui:latest imagePullPolicy: Always ports: - containerPort: 8004 @@ -60,43 +60,43 @@ spec: limits: cpu: 700m memory: 1024Mi -# - name: grafana -# image: grafana/grafana:8.5.11 -# imagePullPolicy: IfNotPresent -# ports: -# - containerPort: 3000 -# name: http-grafana -# protocol: TCP -# env: -# - name: GF_SERVER_ROOT_URL -# value: "http://0.0.0.0:3000/grafana/" -# - name: GF_SERVER_SERVE_FROM_SUB_PATH -# value: "true" -# readinessProbe: -# failureThreshold: 3 -# httpGet: -# path: /robots.txt -# port: 3000 -# scheme: HTTP -# initialDelaySeconds: 10 -# periodSeconds: 30 -# successThreshold: 1 -# timeoutSeconds: 2 -# livenessProbe: -# failureThreshold: 3 -# initialDelaySeconds: 30 -# periodSeconds: 10 -# successThreshold: 1 -# tcpSocket: -# port: 3000 -# timeoutSeconds: 1 -# resources: -# requests: -# cpu: 250m -# memory: 750Mi -# limits: -# cpu: 700m -# memory: 1024Mi + - name: grafana + image: grafana/grafana:8.5.11 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 3000 + name: http-grafana + protocol: TCP + env: + - name: GF_SERVER_ROOT_URL + value: "http://0.0.0.0:3000/grafana/" + - name: GF_SERVER_SERVE_FROM_SUB_PATH + value: "true" + readinessProbe: + failureThreshold: 3 + httpGet: + path: /robots.txt + port: 3000 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 2 + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: 3000 + timeoutSeconds: 1 + resources: + requests: + cpu: 250m + memory: 750Mi + limits: + cpu: 700m + memory: 1024Mi --- apiVersion: v1 kind: Service @@ -110,6 +110,6 @@ spec: - name: webui port: 8004 targetPort: 8004 -# - name: grafana -# port: 3000 -# targetPort: 3000 + - name: grafana + port: 3000 + targetPort: 3000 diff --git a/my_deploy.sh b/my_deploy.sh old mode 100644 new mode 100755 index ffd91da35186fe21f418950493ef797a9af1b522..6f0e64afe311b8e56446caabfac6329024c207a9 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -1,18 +1,31 @@ -# Set the URL of your local Docker registry where the images will be uploaded to. -export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" +#!/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. -# Supported components are: -# context device automation policy service compute monitoring webui -# interdomain slice pathcomp dlt -# dbscanserving opticalattackmitigator opticalattackdetector -# l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector -export TFS_COMPONENTS="context device automation monitoring pathcomp service slice compute webui" +export TFS_COMPONENTS="context device automation monitoring pathcomp service slice compute 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 to. +# Set the name of the Kubernetes namespace to deploy TFS to. export TFS_K8S_NAMESPACE="tfs" # Set additional manifest files to be applied after the deployment @@ -21,6 +34,60 @@ export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" # Set the new Grafana admin password export TFS_GRAFANA_PASSWORD="admin123+" -# If not already set, disable skip-build flag. -# If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used. -export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} +# 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 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" + +# 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 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" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# If not already set, set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb" + +# If not already set, set the database username to be used by Monitoring. +export QDB_USERNAME="admin" + +# If not already set, set the database user's password to be used by Monitoring. +export QDB_PASSWORD="quest" + +# If not already set, set the table name to be used by Monitoring. +export QDB_TABLE="tfs_monitoring" + +## If not already set, disable flag for dropping table if exists. +#export QDB_DROP_TABLE_IF_EXISTS="" + +# If not already set, disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/proto/acl.proto b/proto/acl.proto index d3717e9c4cdcf978324d08757b260ab1e9be028a..3dba735dccf44d584a998eb02b4835bac7ceddd1 100644 --- a/proto/acl.proto +++ b/proto/acl.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/attack_mitigator.proto b/proto/attack_mitigator.proto index e538a9d2e62f7bc0cf91497b6b13414c36e1bc41..0ec503bda8a633f880231474d1c133eb87be5cfc 100644 --- a/proto/attack_mitigator.proto +++ b/proto/attack_mitigator.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/automation.proto b/proto/automation.proto index 9297236766a28878a5f0c0de6a4aeae0487d330a..e2dbe33223566c4065ecb0086fbd8231a56834d4 100644 --- a/proto/automation.proto +++ b/proto/automation.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/centralized_attack_detector.proto b/proto/centralized_attack_detector.proto index 4ce34cfa443b67aa8d060802dca6c9c29b2f7087..7b4fc35f07b079955d4c347ecf3f728abd0292f5 100644 --- a/proto/centralized_attack_detector.proto +++ b/proto/centralized_attack_detector.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/compute.proto b/proto/compute.proto index 0e7c7a7386b5c8d5924f93745bc9aa3039b60703..ecc9a075f19cef180423db350d2153638be94265 100644 --- a/proto/compute.proto +++ b/proto/compute.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/context.proto b/proto/context.proto index 3f0532d231535c2e59c798cbc9a6b1c92e1eb4bf..e403c4a22f2df62f695041c094cc1c6e6a193d5f 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -19,56 +19,59 @@ import "acl.proto"; import "kpi_sample_types.proto"; service ContextService { - rpc ListContextIds (Empty ) returns ( ContextIdList ) {} - rpc ListContexts (Empty ) returns ( ContextList ) {} - rpc GetContext (ContextId ) returns ( Context ) {} - rpc SetContext (Context ) returns ( ContextId ) {} - rpc RemoveContext (ContextId ) returns ( Empty ) {} - rpc GetContextEvents (Empty ) returns (stream ContextEvent ) {} - - rpc ListTopologyIds (ContextId ) returns ( TopologyIdList ) {} - rpc ListTopologies (ContextId ) returns ( TopologyList ) {} - rpc GetTopology (TopologyId ) returns ( Topology ) {} - rpc SetTopology (Topology ) returns ( TopologyId ) {} - rpc RemoveTopology (TopologyId ) returns ( Empty ) {} - rpc GetTopologyEvents (Empty ) returns (stream TopologyEvent ) {} - - rpc ListDeviceIds (Empty ) returns ( DeviceIdList ) {} - rpc ListDevices (Empty ) returns ( DeviceList ) {} - rpc GetDevice (DeviceId ) returns ( Device ) {} - rpc SetDevice (Device ) returns ( DeviceId ) {} - rpc RemoveDevice (DeviceId ) returns ( Empty ) {} - rpc GetDeviceEvents (Empty ) returns (stream DeviceEvent ) {} - - rpc ListLinkIds (Empty ) returns ( LinkIdList ) {} - rpc ListLinks (Empty ) returns ( LinkList ) {} - rpc GetLink (LinkId ) returns ( Link ) {} - rpc SetLink (Link ) returns ( LinkId ) {} - rpc RemoveLink (LinkId ) returns ( Empty ) {} - rpc GetLinkEvents (Empty ) returns (stream LinkEvent ) {} - - rpc ListServiceIds (ContextId ) returns ( ServiceIdList ) {} - rpc ListServices (ContextId ) returns ( ServiceList ) {} - rpc GetService (ServiceId ) returns ( Service ) {} - rpc SetService (Service ) returns ( ServiceId ) {} - rpc UnsetService (Service ) returns ( ServiceId ) {} - rpc RemoveService (ServiceId ) returns ( Empty ) {} - rpc GetServiceEvents (Empty ) returns (stream ServiceEvent ) {} - - rpc ListSliceIds (ContextId ) returns ( SliceIdList ) {} - rpc ListSlices (ContextId ) returns ( SliceList ) {} - rpc GetSlice (SliceId ) returns ( Slice ) {} - rpc SetSlice (Slice ) returns ( SliceId ) {} - rpc UnsetSlice (Slice ) returns ( SliceId ) {} - rpc RemoveSlice (SliceId ) returns ( Empty ) {} - rpc GetSliceEvents (Empty ) returns (stream SliceEvent ) {} - - rpc ListConnectionIds (ServiceId ) returns ( ConnectionIdList) {} - rpc ListConnections (ServiceId ) returns ( ConnectionList ) {} - rpc GetConnection (ConnectionId) returns ( Connection ) {} - rpc SetConnection (Connection ) returns ( ConnectionId ) {} - rpc RemoveConnection (ConnectionId) returns ( Empty ) {} - rpc GetConnectionEvents(Empty ) returns (stream ConnectionEvent ) {} + rpc ListContextIds (Empty ) returns ( ContextIdList ) {} + rpc ListContexts (Empty ) returns ( ContextList ) {} + rpc GetContext (ContextId ) returns ( Context ) {} + rpc SetContext (Context ) returns ( ContextId ) {} + rpc RemoveContext (ContextId ) returns ( Empty ) {} + rpc GetContextEvents (Empty ) returns (stream ContextEvent ) {} + + rpc ListTopologyIds (ContextId ) returns ( TopologyIdList ) {} + rpc ListTopologies (ContextId ) returns ( TopologyList ) {} + rpc GetTopology (TopologyId ) returns ( Topology ) {} + rpc GetTopologyDetails (TopologyId ) returns ( TopologyDetails ) {} + rpc SetTopology (Topology ) returns ( TopologyId ) {} + rpc RemoveTopology (TopologyId ) returns ( Empty ) {} + rpc GetTopologyEvents (Empty ) returns (stream TopologyEvent ) {} + + rpc ListDeviceIds (Empty ) returns ( DeviceIdList ) {} + rpc ListDevices (Empty ) returns ( DeviceList ) {} + rpc GetDevice (DeviceId ) returns ( Device ) {} + rpc SetDevice (Device ) returns ( DeviceId ) {} + rpc RemoveDevice (DeviceId ) returns ( Empty ) {} + rpc GetDeviceEvents (Empty ) returns (stream DeviceEvent ) {} + + rpc ListEndPointNames (EndPointIdList) returns ( EndPointNameList) {} + + rpc ListLinkIds (Empty ) returns ( LinkIdList ) {} + rpc ListLinks (Empty ) returns ( LinkList ) {} + rpc GetLink (LinkId ) returns ( Link ) {} + rpc SetLink (Link ) returns ( LinkId ) {} + rpc RemoveLink (LinkId ) returns ( Empty ) {} + rpc GetLinkEvents (Empty ) returns (stream LinkEvent ) {} + + rpc ListServiceIds (ContextId ) returns ( ServiceIdList ) {} + rpc ListServices (ContextId ) returns ( ServiceList ) {} + rpc GetService (ServiceId ) returns ( Service ) {} + rpc SetService (Service ) returns ( ServiceId ) {} + rpc UnsetService (Service ) returns ( ServiceId ) {} + rpc RemoveService (ServiceId ) returns ( Empty ) {} + rpc GetServiceEvents (Empty ) returns (stream ServiceEvent ) {} + + rpc ListSliceIds (ContextId ) returns ( SliceIdList ) {} + rpc ListSlices (ContextId ) returns ( SliceList ) {} + rpc GetSlice (SliceId ) returns ( Slice ) {} + rpc SetSlice (Slice ) returns ( SliceId ) {} + rpc UnsetSlice (Slice ) returns ( SliceId ) {} + rpc RemoveSlice (SliceId ) returns ( Empty ) {} + rpc GetSliceEvents (Empty ) returns (stream SliceEvent ) {} + + rpc ListConnectionIds (ServiceId ) returns ( ConnectionIdList) {} + rpc ListConnections (ServiceId ) returns ( ConnectionList ) {} + rpc GetConnection (ConnectionId ) returns ( Connection ) {} + rpc SetConnection (Connection ) returns ( ConnectionId ) {} + rpc RemoveConnection (ConnectionId ) returns ( Empty ) {} + rpc GetConnectionEvents(Empty ) returns (stream ConnectionEvent ) {} } // ----- Generic ------------------------------------------------------------------------------------------------------- @@ -101,9 +104,11 @@ message ContextId { message Context { ContextId context_id = 1; - repeated TopologyId topology_ids = 2; - repeated ServiceId service_ids = 3; - TeraFlowController controller = 4; + string name = 2; + repeated TopologyId topology_ids = 3; + repeated ServiceId service_ids = 4; + repeated SliceId slice_ids = 5; + TeraFlowController controller = 6; } message ContextIdList { @@ -128,8 +133,16 @@ message TopologyId { message Topology { TopologyId topology_id = 1; - repeated DeviceId device_ids = 2; - repeated LinkId link_ids = 3; + string name = 2; + repeated DeviceId device_ids = 3; + repeated LinkId link_ids = 4; +} + +message TopologyDetails { + TopologyId topology_id = 1; + string name = 2; + repeated Device devices = 3; + repeated Link links = 4; } message TopologyIdList { @@ -153,12 +166,13 @@ message DeviceId { message Device { DeviceId device_id = 1; - string device_type = 2; - DeviceConfig device_config = 3; - DeviceOperationalStatusEnum device_operational_status = 4; - repeated DeviceDriverEnum device_drivers = 5; - repeated EndPoint device_endpoints = 6; - repeated Component component = 7; // Used for inventory + string name = 2; + string device_type = 3; + DeviceConfig device_config = 4; + DeviceOperationalStatusEnum device_operational_status = 5; + repeated DeviceDriverEnum device_drivers = 6; + repeated EndPoint device_endpoints = 7; + repeated Component component = 8; // Used for inventory } message Component { @@ -207,7 +221,8 @@ message LinkId { message Link { LinkId link_id = 1; - repeated EndPointId link_endpoint_ids = 2; + string name = 2; + repeated EndPointId link_endpoint_ids = 3; } message LinkIdList { @@ -232,12 +247,13 @@ message ServiceId { message Service { ServiceId service_id = 1; - ServiceTypeEnum service_type = 2; - repeated EndPointId service_endpoint_ids = 3; - repeated Constraint service_constraints = 4; - ServiceStatus service_status = 5; - ServiceConfig service_config = 6; - Timestamp timestamp = 7; + string name = 2; + ServiceTypeEnum service_type = 3; + repeated EndPointId service_endpoint_ids = 4; + repeated Constraint service_constraints = 5; + ServiceStatus service_status = 6; + ServiceConfig service_config = 7; + Timestamp timestamp = 8; } enum ServiceTypeEnum { @@ -284,14 +300,15 @@ message SliceId { message Slice { SliceId slice_id = 1; - repeated EndPointId slice_endpoint_ids = 2; - repeated Constraint slice_constraints = 3; - repeated ServiceId slice_service_ids = 4; - repeated SliceId slice_subslice_ids = 5; - SliceStatus slice_status = 6; - SliceConfig slice_config = 7; - SliceOwner slice_owner = 8; - Timestamp timestamp = 9; + string name = 2; + repeated EndPointId slice_endpoint_ids = 3; + repeated Constraint slice_constraints = 4; + repeated ServiceId slice_service_ids = 5; + repeated SliceId slice_subslice_ids = 6; + SliceStatus slice_status = 7; + SliceConfig slice_config = 8; + SliceOwner slice_owner = 9; + Timestamp timestamp = 10; } message SliceOwner { @@ -300,11 +317,11 @@ message SliceOwner { } enum SliceStatusEnum { - SLICESTATUS_UNDEFINED = 0; - SLICESTATUS_PLANNED = 1; - SLICESTATUS_INIT = 2; - SLICESTATUS_ACTIVE = 3; - SLICESTATUS_DEINIT = 4; + SLICESTATUS_UNDEFINED = 0; + SLICESTATUS_PLANNED = 1; + SLICESTATUS_INIT = 2; + SLICESTATUS_ACTIVE = 3; + SLICESTATUS_DEINIT = 4; SLICESTATUS_SLA_VIOLATED = 5; } @@ -400,17 +417,33 @@ message EndPointId { message EndPoint { EndPointId endpoint_id = 1; - string endpoint_type = 2; - repeated kpi_sample_types.KpiSampleType kpi_sample_types = 3; - Location endpoint_location = 4; + string name = 2; + string endpoint_type = 3; + repeated kpi_sample_types.KpiSampleType kpi_sample_types = 4; + Location endpoint_location = 5; +} + +message EndPointName { + EndPointId endpoint_id = 1; + string device_name = 2; + string endpoint_name = 3; + string endpoint_type = 4; +} + +message EndPointIdList { + repeated EndPointId endpoint_ids = 1; +} + +message EndPointNameList { + repeated EndPointName endpoint_names = 1; } // ----- Configuration ------------------------------------------------------------------------------------------------- enum ConfigActionEnum { CONFIGACTION_UNDEFINED = 0; - CONFIGACTION_SET = 1; - CONFIGACTION_DELETE = 2; + CONFIGACTION_SET = 1; + CONFIGACTION_DELETE = 2; } message ConfigRule_Custom { diff --git a/proto/context_policy.proto b/proto/context_policy.proto index efad68df6c65481a3a8c21417bc62ed230673c44..f6dae48306e2ef7fe8a0682185ec46e1f2ad637e 100644 --- a/proto/context_policy.proto +++ b/proto/context_policy.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/dbscanserving.proto b/proto/dbscanserving.proto index d7d0512b6c5215f05f0c2568a0271e11f8e03a6c..21ff45dfaf2b031a24b573e45f7c21827f0b11b4 100644 --- a/proto/dbscanserving.proto +++ b/proto/dbscanserving.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/device.proto b/proto/device.proto index f41e2891a85301da445367db2cf96f9a2d97d313..30e60079db6c1eb8641d10115f6f43840eabf39c 100644 --- a/proto/device.proto +++ b/proto/device.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/distributed_cybersecurity.proto b/proto/distributed_cybersecurity.proto index 664e1383f162ee874d1ef89b0e59c70ac2ee62e1..bc95fcc3d8c89ab0d9f705c4f2e8e482920ca70c 100644 --- a/proto/distributed_cybersecurity.proto +++ b/proto/distributed_cybersecurity.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/dlt_connector.proto b/proto/dlt_connector.proto index cee0c70bdcda42f435339751c6cfabf609b14d21..3a4d11dd9eff0793fb6dee0b8efbab7bd2d04f3f 100644 --- a/proto/dlt_connector.proto +++ b/proto/dlt_connector.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/dlt_gateway.proto b/proto/dlt_gateway.proto index 84fe0fef6be366deb9286d49193ddb934c70a55c..6ae4fbb75ea3244a01549784390ad8af010b90eb 100644 --- a/proto/dlt_gateway.proto +++ b/proto/dlt_gateway.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/forecaster.proto b/proto/forecaster.proto index 576afb101ea4c8d733f3adf37fdf061e44b390eb..5a4403b01c7f85d6d5b33548d0eaf463e39558cc 100644 --- a/proto/forecaster.proto +++ b/proto/forecaster.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/generate_code_python.sh b/proto/generate_code_python.sh index b0df357eb079fb2721cffca43465588f7013e341..5c5db5444d3ef31570019abbcd7eab4f1a305a48 100755 --- a/proto/generate_code_python.sh +++ b/proto/generate_code_python.sh @@ -1,5 +1,5 @@ #!/bin/bash -eu -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -20,7 +20,7 @@ mkdir -p src/python rm -rf src/python/*.py tee src/python/__init__.py << EOF > /dev/null -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/generate_uml.sh b/proto/generate_uml.sh index 6f20b6f4cf695274fe5d6ed27e57671196c44b70..8bdd76ac5d504c7a93a997dd37092c749051bf3b 100755 --- a/proto/generate_uml.sh +++ b/proto/generate_uml.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/health.proto b/proto/health.proto index 0252f5d877343864a75ff641d4a019e7cb6de499..f3057a7e72f9b37b4ad084dd72a5670c18355354 100644 --- a/proto/health.proto +++ b/proto/health.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/interdomain.proto b/proto/interdomain.proto index b8a31c2498a216e183aecbb975821d5c0ec25885..3e44fb4477c400e8ca278bda38a7af6d142cebe0 100644 --- a/proto/interdomain.proto +++ b/proto/interdomain.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/kpi_sample_types.proto b/proto/kpi_sample_types.proto index 4419a8df4a22047d8708c5cf2e2c3657148b5eeb..1ade4d69bf5a6c23d993cd37ed731eee10d7374e 100644 --- a/proto/kpi_sample_types.proto +++ b/proto/kpi_sample_types.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/l3_attackmitigator.proto b/proto/l3_attackmitigator.proto index 39333718a5904d1617ba827d35149687ff903b65..5ce9428b6f47318cf4bdd205c48645295ff26d71 100644 --- a/proto/l3_attackmitigator.proto +++ b/proto/l3_attackmitigator.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/l3_centralizedattackdetector.proto b/proto/l3_centralizedattackdetector.proto index 3cb1b0991b1dc4df2c268d511c0ebd6f9f9d80aa..2aeb8826e8662b6495f10a333145a9f6abe594b9 100644 --- a/proto/l3_centralizedattackdetector.proto +++ b/proto/l3_centralizedattackdetector.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/load_generator.proto b/proto/load_generator.proto new file mode 100644 index 0000000000000000000000000000000000000000..98f6eefda88db7abac4651857326952789a879ba --- /dev/null +++ b/proto/load_generator.proto @@ -0,0 +1,23 @@ +// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; +package load_generator; + +import "context.proto"; + +service LoadGeneratorService { + rpc Start(context.Empty) returns (context.Empty) {} + rpc Stop (context.Empty) returns (context.Empty) {} +} diff --git a/proto/monitoring.proto b/proto/monitoring.proto index f9c408c96ced121f35cc1116bf64d013e7320e6a..3862973e056d6267d8defc68e77cbf3c8a10ebee 100644 --- a/proto/monitoring.proto +++ b/proto/monitoring.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/optical_attack_mitigator.proto b/proto/optical_attack_mitigator.proto index 881f9fde375bb67b0362ca634ad84b45fb60220b..1dbb4e19a62f39dfcf85312ce3cb99472467993d 100644 --- a/proto/optical_attack_mitigator.proto +++ b/proto/optical_attack_mitigator.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/optical_centralized_attack_detector.proto b/proto/optical_centralized_attack_detector.proto index d480054f2ca3b1cf32cbb40c51df51c562f9b4d5..98ffeddc81c7533fccfd118075732a3f7799264f 100644 --- a/proto/optical_centralized_attack_detector.proto +++ b/proto/optical_centralized_attack_detector.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/pathcomp.proto b/proto/pathcomp.proto index 08f33efe99b6a25c568c8be14f1355b3d4521909..181f05cc288b8c739eb55315868a4fbbe79702f3 100644 --- a/proto/pathcomp.proto +++ b/proto/pathcomp.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/policy.proto b/proto/policy.proto index 9d0c34a3304f68c47a19ac56d0e96b10936bee7b..a6f16015035096c6baf13a7b4e707c06e9ab1727 100644 --- a/proto/policy.proto +++ b/proto/policy.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/policy_action.proto b/proto/policy_action.proto index 8f681adf38f321aa06410bcb1bac26ea69fe14ec..17dd721196c0ed407849aa23099477ea34d39ddd 100644 --- a/proto/policy_action.proto +++ b/proto/policy_action.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/policy_condition.proto b/proto/policy_condition.proto index 7cd6576678872df07a2da6a3706349f004b3a8a1..2037af93c375838209e78a07ec95e25d469d1d5a 100644 --- a/proto/policy_condition.proto +++ b/proto/policy_condition.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/service.proto b/proto/service.proto index 90a2f2ecf32dcda0366281224d31725fb4f95622..21e5699413cc4842962af6ee9c204b383fc61ec0 100644 --- a/proto/service.proto +++ b/proto/service.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/slice.proto b/proto/slice.proto index 69fa242e2310f791faa2429d59c01fc2572025d2..cad483c0fddb1000adeee7756a939fe5a3c3cbb7 100644 --- a/proto/slice.proto +++ b/proto/slice.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/src/python/__init__.py b/proto/src/python/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/proto/src/python/__init__.py +++ b/proto/src/python/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/te.proto b/proto/te.proto index d639cb7f45f682d3e95d77e8b6d10d404ee51b9f..983f6602b8cb961404843812e069348a2530dd73 100644 --- a/proto/te.proto +++ b/proto/te.proto @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/proto/uml/monitoring.png b/proto/uml/monitoring.png index 98f2e1d64766faf55599e465dd30f57e3518b11f..4257b4d3f4b570fa9c51734480bd8c73e8c72622 100644 Binary files a/proto/uml/monitoring.png and b/proto/uml/monitoring.png differ diff --git a/report_coverage_slice.sh b/report_coverage_slice.sh deleted file mode 100755 index f783ec069329a9efe100154a2702a72a93e0ad8a..0000000000000000000000000000000000000000 --- a/report_coverage_slice.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -./report_coverage_all.sh | grep --color -E -i "^slice/.*$|$" diff --git a/run_tests_docker.sh b/run_tests_docker.sh index fd885140999ac0f045c162f361f0075af96a8d48..d27c4e7d8a36f89b3b0b72e9c5725c80b520141f 100755 --- a/run_tests_docker.sh +++ b/run_tests_docker.sh @@ -1,4 +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. + ######################################################################################################################## # Define your deployment settings here diff --git a/scripts/add_license_header_to_files.sh b/scripts/add_license_header_to_files.sh index 4da23894414cfc57cda9ea1277e144f8e7244056..4c11fc316484b2c8f02677337bacf09197ee12b7 100755 --- a/scripts/add_license_header_to_files.sh +++ b/scripts/add_license_header_to_files.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -26,6 +26,5 @@ docker run -it -v ${PWD}:/src ghcr.io/google/addlicense \ -ignore "src/**/target/generated-sources/grpc/*" -ignore "src/**/target/generated-sources/grpc/**" \ -ignore "src/**/*_pb2.py" -ignore "src/**/*_pb2_grpc.py" \ -ignore "src/device/service/drivers/openconfig/templates/**/*.xml" \ - -ignore "src/dlt/*" -ignore "src/dlt/**" \ -ignore "src/**/.mvn/*" -ignore "src/**/.mvn/**" \ * diff --git a/scripts/build_run_report_tests_locally.sh b/scripts/build_run_report_tests_locally.sh index 9bdc81d9894df35a6bcc325d78e7f1f5214e8a96..7a44eef0282ec87bf5ebca33907d5dc0acb1e2f8 100755 --- a/scripts/build_run_report_tests_locally.sh +++ b/scripts/build_run_report_tests_locally.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/cockroachdb_client.sh b/scripts/cockroachdb_client.sh new file mode 100755 index 0000000000000000000000000000000000000000..0300bb294dcc2dbf713a8515b3e5adc706247ec1 --- /dev/null +++ b/scripts/cockroachdb_client.sh @@ -0,0 +1,51 @@ +#!/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 namespace where CockroackDB will be deployed. +export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} + +# If not already set, set the database username to be used by Context. +export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"} + +# If not already set, set the database user's password to be used by Context. +export CRDB_PASSWORD=${CRDB_PASSWORD:-"tfs123"} + +# If not already set, set the database name to be used by Context. +export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"} + +# If not already set, set CockroachDB installation mode. Accepted values are: 'single' and 'cluster'. +export CRDB_DEPLOY_MODE=${CRDB_DEPLOY_MODE:-"single"} + + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +if [ "$CRDB_DEPLOY_MODE" == "single" ]; then + CRDB_SQL_PORT=$(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_SQL_PORT}/defaultdb?sslmode=require" + kubectl exec -it --namespace ${CRDB_NAMESPACE} cockroachdb-0 -- \ + ./cockroach sql --certs-dir=/cockroach/cockroach-certs --url=${CRDB_CLIENT_URL} +elif [ "$CRDB_DEPLOY_MODE" == "cluster" ]; then + kubectl exec -it --namespace ${CRDB_NAMESPACE} cockroachdb-client-secure -- \ + ./cockroach sql --certs-dir=/cockroach/cockroach-certs --host=cockroachdb-public +else + echo "Unsupported value: CRDB_DEPLOY_MODE=$CRDB_DEPLOY_MODE" +fi diff --git a/scripts/create_component.sh b/scripts/create_component.sh index 17f6abc64140f88e0b8f09f548afdaf1f1362f6f..549f09bf40dde79c181d3205cd4da6427f4226dd 100755 --- a/scripts/create_component.sh +++ b/scripts/create_component.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/dump_logs.sh b/scripts/dump_logs.sh index a6db945d245b832564353de71610bf720eb0acb8..f50f8b133a76dd58e0af2b5ab10ebdbf1b0f2869 100755 --- a/scripts/dump_logs.sh +++ b/scripts/dump_logs.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/old/configure_dashboards_in_kubernetes.sh b/scripts/old/configure_dashboards_in_kubernetes.sh index 4a32d76deb79bb514b6d547c0e3e2b87ec269e77..545e13cffe54c28fec5447314405172f3ac30473 100755 --- a/scripts/old/configure_dashboards_in_kubernetes.sh +++ b/scripts/old/configure_dashboards_in_kubernetes.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/old/deploy_in_kubernetes.sh b/scripts/old/deploy_in_kubernetes.sh index 89f45a5484f95f065f6656249f3fb04bf507a782..c13a236664bde370a323f1663095afd72f72aaec 100755 --- a/scripts/old/deploy_in_kubernetes.sh +++ b/scripts/old/deploy_in_kubernetes.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -43,7 +43,7 @@ export EXTRA_MANIFESTS=${EXTRA_MANIFESTS:-""} ######################################################################################################################## # Constants -GITLAB_REPO_URL="registry.gitlab.com/teraflow-h2020/controller" +GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller" TMP_FOLDER="./tmp" # Create a tmp folder for files modified during the deployment diff --git a/scripts/old/open_dashboard.sh b/scripts/old/open_dashboard.sh index d0529a00921be896ae976c86d10d67139719de9c..4ea206f4538c27fe8563ce5c30ed837781f8d362 100755 --- a/scripts/old/open_dashboard.sh +++ b/scripts/old/open_dashboard.sh @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/old/open_webui.sh b/scripts/old/open_webui.sh index d539c1970adb7882c9621fc909acf21c2dde743a..5bb0082e16075238a72f4e439810703ecd016a58 100755 --- a/scripts/old/open_webui.sh +++ b/scripts/old/open_webui.sh @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_all.sh b/scripts/report_coverage_all.sh index 3b7df170c880ede72dea356752c5120e59dd9d71..cf3a05c03c48f41d5960e317e27047b003ecb2d4 100755 --- a/scripts/report_coverage_all.sh +++ b/scripts/report_coverage_all.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_common.sh b/scripts/report_coverage_common.sh index f69c57a01aa83a75263a2dc888951aeaf4867ca2..f7f1076bdb26c8185b26b4392448560199316945 100755 --- a/scripts/report_coverage_common.sh +++ b/scripts/report_coverage_common.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_compute.sh b/scripts/report_coverage_compute.sh index 15e9e3422e9c2674206dfd17fec9a4396ea77cca..4d986b5c36e6fdc2b1360881d2120c881f468535 100755 --- a/scripts/report_coverage_compute.sh +++ b/scripts/report_coverage_compute.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_context.sh b/scripts/report_coverage_context.sh index b39c45833189ca755a088983e9fbe341bb6dd471..2784bdf10e6ae8bd75e3630b6b1a3074e6081d63 100755 --- a/scripts/report_coverage_context.sh +++ b/scripts/report_coverage_context.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_device.sh b/scripts/report_coverage_device.sh index d7a1dc0841f9fb2fa495363b248747668d704886..c1bbb84734ae89ed8d380981312fd6618b89ae06 100755 --- a/scripts/report_coverage_device.sh +++ b/scripts/report_coverage_device.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_l3_attackmitigator.sh b/scripts/report_coverage_l3_attackmitigator.sh index c34283dbb91e21099ac5246566a3698c280b4725..80496eaf83060821930538ac94a7d3d6c59c2016 100755 --- a/scripts/report_coverage_l3_attackmitigator.sh +++ b/scripts/report_coverage_l3_attackmitigator.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_l3_centralizedattackdetector.sh b/scripts/report_coverage_l3_centralizedattackdetector.sh index 1060bae05eb383aea5d9caf6bd1b1a9e5e4cfeaa..d662dadb78eb12bfe84ad239d7ee7838c7df77ad 100755 --- a/scripts/report_coverage_l3_centralizedattackdetector.sh +++ b/scripts/report_coverage_l3_centralizedattackdetector.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_l3_distributedattackdetector.sh b/scripts/report_coverage_l3_distributedattackdetector.sh index 94c2a16f4c6ff9b0a6adfd0a45b59a208297c327..e83dd01e649ec67bfecbb2753ff12a811d25b8a4 100755 --- a/scripts/report_coverage_l3_distributedattackdetector.sh +++ b/scripts/report_coverage_l3_distributedattackdetector.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_pathcomp.sh b/scripts/report_coverage_pathcomp.sh index 3af2790f838619e495a9b5727506f6829ad12a35..9e91fb2586df1bd71b3e8b22b6c8f7df253e2b15 100755 --- a/scripts/report_coverage_pathcomp.sh +++ b/scripts/report_coverage_pathcomp.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_service.sh b/scripts/report_coverage_service.sh index 4a3c5cc067d009d6354939c06d9002f038bc0441..41c25bfabb91b792b9171763616045e0de89846f 100755 --- a/scripts/report_coverage_service.sh +++ b/scripts/report_coverage_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/report_coverage_slice.sh b/scripts/report_coverage_slice.sh index f9b17e8bd162500e2be77a871f7f2976f923ca68..64c68d492a45758969d170e145ab2d47ef3f55ac 100755 --- a/scripts/report_coverage_slice.sh +++ b/scripts/report_coverage_slice.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-compute.sh b/scripts/run_tests_locally-compute.sh index d48fe417134d2f8c3078d549b3bb84e2cc745da6..3fed523e541e1cc9dabb0a55579f38a3338b30b9 100755 --- a/scripts/run_tests_locally-compute.sh +++ b/scripts/run_tests_locally-compute.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-context.sh b/scripts/run_tests_locally-context.sh index 7033fcb01a468731b498708096a80fac8d9a9a85..79bac938a44f72dfc61c3d9dad7c3322f9a04d3d 100755 --- a/scripts/run_tests_locally-context.sh +++ b/scripts/run_tests_locally-context.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,31 +13,73 @@ # See the License for the specific language governing permissions and # limitations under the License. -######################################################################################################################## -# Define your deployment settings here -######################################################################################################################## +PROJECTDIR=`pwd` -# If not already set, set the name of the Kubernetes namespace to deploy to. -export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} +cd $PROJECTDIR/src +RCFILE=$PROJECTDIR/coverage/.coveragerc +COVERAGEFILE=$PROJECTDIR/coverage/.coverage -export TFS_K8S_HOSTNAME="tfs-vm" +# Destroy old coverage file and configure the correct folder on the .coveragerc file +rm -f $COVERAGEFILE +cat $PROJECTDIR/coverage/.coveragerc.template | sed s+~/tfs-ctrl+$PROJECTDIR+g > $RCFILE -######################################################################################################################## -# Automated steps start here -######################################################################################################################## +echo +echo "Pre-test clean-up:" +echo "------------------" +docker rm -f crdb nats +docker volume rm -f crdb +docker network rm tfs-br -PROJECTDIR=`pwd` +echo +echo "Pull Docker images:" +echo "-------------------" +docker pull cockroachdb/cockroach:latest-v22.2 +docker pull nats:2.9 -cd $PROJECTDIR/src -RCFILE=$PROJECTDIR/coverage/.coveragerc +echo +echo "Create test environment:" +echo "------------------------" +docker network create -d bridge --subnet=172.254.254.0/24 --gateway=172.254.254.1 --ip-range=172.254.254.0/24 tfs-br +docker volume create crdb +docker run --name crdb -d --network=tfs-br --ip 172.254.254.10 -p 26257:26257 -p 8080:8080 \ + --env COCKROACH_DATABASE=tfs_test --env COCKROACH_USER=tfs --env COCKROACH_PASSWORD=tfs123\ + --volume "crdb:/cockroach/cockroach-data" \ + cockroachdb/cockroach:latest-v22.2 start-single-node +docker run --name nats -d --network=tfs-br --ip 172.254.254.11 -p 4222:4222 -p 8222:8222 \ + nats:2.9 --http_port 8222 --user tfs --pass tfs123 -kubectl --namespace $TFS_K8S_NAMESPACE expose deployment contextservice --name=redis-tests --port=6379 --type=NodePort -#export REDIS_SERVICE_HOST=$(kubectl --namespace $TFS_K8S_NAMESPACE get service redis-tests -o 'jsonpath={.spec.clusterIP}') -export REDIS_SERVICE_HOST=$(kubectl get node $TFS_K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}') -export REDIS_SERVICE_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service redis-tests -o 'jsonpath={.spec.ports[?(@.port==6379)].nodePort}') +echo +echo "Waiting for initialization..." +echo "-----------------------------" +#docker logs -f crdb 2>&1 | grep --max-count=1 'finished creating default user "tfs"' +while ! docker logs crdb 2>&1 | grep -q 'finished creating default user \"tfs\"'; do sleep 1; done +docker logs crdb +#docker logs -f nats 2>&1 | grep --max-count=1 'Server is ready' +while ! docker logs nats 2>&1 | grep -q 'Server is ready'; do sleep 1; done +docker logs nats +#sleep 10 +docker ps -a -# Run unitary tests and analyze coverage of code at same time +echo +echo "Run unitary tests and analyze code coverage:" +echo "--------------------------------------------" +export CRDB_URI="cockroachdb://tfs:tfs123@172.254.254.10:26257/tfs_test?sslmode=require" +export MB_BACKEND="nats" +export NATS_URI="nats://tfs:tfs123@172.254.254.11:4222" +export PYTHONPATH=/home/tfs/tfs-ctrl/src +# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose --maxfail=1 \ - context/tests/test_unitary.py + context/tests/test_*.py + +echo +echo "Coverage report:" +echo "----------------" +#coverage report --rcfile=$RCFILE --sort cover --show-missing --skip-covered | grep --color -E -i "^context/.*$|$" +coverage report --rcfile=$RCFILE --sort cover --show-missing --skip-covered --include="context/*" -kubectl --namespace $TFS_K8S_NAMESPACE delete service redis-tests +echo +echo "Post-test clean-up:" +echo "-------------------" +docker rm -f crdb nats +docker volume rm -f crdb +docker network rm tfs-br diff --git a/scripts/run_tests_locally-device-all.sh b/scripts/run_tests_locally-device-all.sh index a60eab0be932862cf1adc3a81678239de566bd37..b44db77cea2dc56e4c40c0ccc8d2849a8fd5ba10 100755 --- a/scripts/run_tests_locally-device-all.sh +++ b/scripts/run_tests_locally-device-all.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-device-emulated.sh b/scripts/run_tests_locally-device-emulated.sh index 541017f7a6b9f3d1289162ad69b27f572aa046cb..0f1c74df0ef8cd8d309e6e8a28500e3d8fccc46c 100755 --- a/scripts/run_tests_locally-device-emulated.sh +++ b/scripts/run_tests_locally-device-emulated.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-device-microwave.sh b/scripts/run_tests_locally-device-microwave.sh index 21f3e5ab67c882ab51f7c8c14a95ed6df26418de..e4cab1796b34504f40d9e0053ae9f97fb635202f 100755 --- a/scripts/run_tests_locally-device-microwave.sh +++ b/scripts/run_tests_locally-device-microwave.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-device-openconfig.sh b/scripts/run_tests_locally-device-openconfig.sh index 0d493db9c18065d9ab73f62e7226ec05b29d92a1..b0a6f946f2fa5f440fbff406647cb28062f8252b 100755 --- a/scripts/run_tests_locally-device-openconfig.sh +++ b/scripts/run_tests_locally-device-openconfig.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-device-p4.sh b/scripts/run_tests_locally-device-p4.sh index 4e6754e4d56741f960e1e5562abb0c10abc0ccb4..0d73e3564a55f3557733de746ac0f0ce02495519 100755 --- a/scripts/run_tests_locally-device-p4.sh +++ b/scripts/run_tests_locally-device-p4.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-device-tapi.sh b/scripts/run_tests_locally-device-tapi.sh index d37e4e2b7f8545c2033b0049722cdbb8c589b55b..3a00f5857393949e0ef101a0072e54d5907bf51e 100755 --- a/scripts/run_tests_locally-device-tapi.sh +++ b/scripts/run_tests_locally-device-tapi.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-pathcomp-frontend.sh b/scripts/run_tests_locally-pathcomp-frontend.sh index 1bcf5e7f3792622622f9e59978fddbf11c54e492..4318b2f472a54f52be71d02d6344d24ccfd8e826 100755 --- a/scripts/run_tests_locally-pathcomp-frontend.sh +++ b/scripts/run_tests_locally-pathcomp-frontend.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-service.sh b/scripts/run_tests_locally-service.sh index 8816b9faa24e55e486a54852632fdb8e00db1d04..e671b0fc89db38aa64137d754c45baa1730f61a3 100755 --- a/scripts/run_tests_locally-service.sh +++ b/scripts/run_tests_locally-service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally-slice.sh b/scripts/run_tests_locally-slice.sh index fa3af4eba1f9d42a1f9d283964a536a00f9547ae..9e5f47c18fcdfbc82316c345df35cad73e6fe4b0 100755 --- a/scripts/run_tests_locally-slice.sh +++ b/scripts/run_tests_locally-slice.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/run_tests_locally.sh b/scripts/run_tests_locally.sh index 1d48cc1af18629874b0275b1fa92bf31961741c3..b609fbb391266702e6fc4be8c7a0aa7990596235 100755 --- a/scripts/run_tests_locally.sh +++ b/scripts/run_tests_locally.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -54,7 +54,7 @@ rm -f $COVERAGEFILE coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ common/orm/tests/test_unitary.py \ common/message_broker/tests/test_unitary.py \ - common/rpc_method_wrapper/tests/test_unitary.py + common/method_wrappers/tests/test_unitary.py coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ context/tests/test_unitary.py diff --git a/scripts/show_logs_automation.sh b/scripts/show_logs_automation.sh index 0c0615d9915db6e5b9958ec1205c7a99f096f019..46c0dbba9752b207b11136535403f0c009d0a377 100755 --- a/scripts/show_logs_automation.sh +++ b/scripts/show_logs_automation.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_compute.sh b/scripts/show_logs_compute.sh index 759918f11a366450b5c7058a9a2c46bbb701f2cd..fc992eb43e5872b4522db6f5c8ce39207f12d559 100755 --- a/scripts/show_logs_compute.sh +++ b/scripts/show_logs_compute.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_context.sh b/scripts/show_logs_context.sh index f4b6c620b89d566c8af6950d7240a8286152417d..1051e6fd5b830b73f4fb4df0486850935f1c8047 100755 --- a/scripts/show_logs_context.sh +++ b/scripts/show_logs_context.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_device.sh b/scripts/show_logs_device.sh index d3ef781c92274ecf6b9f2b9ef8eb44b2fde497d6..6a77c38152716f1e6fbf320671dda25d974431c8 100755 --- a/scripts/show_logs_device.sh +++ b/scripts/show_logs_device.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_dlt_connector.sh b/scripts/show_logs_dlt_connector.sh index db4c388c20399007ba10b357a5e153df4a86c519..9e1f21ab911f93003497bd764c5919e13db98c22 100755 --- a/scripts/show_logs_dlt_connector.sh +++ b/scripts/show_logs_dlt_connector.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_dlt_gateway.sh b/scripts/show_logs_dlt_gateway.sh index c00be2df16cb69b3ace501a854d1248a72abbf3e..db29eebfaf8f424c628880ccc0cb7113fe913fde 100755 --- a/scripts/show_logs_dlt_gateway.sh +++ b/scripts/show_logs_dlt_gateway.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_monitoring.sh b/scripts/show_logs_monitoring.sh index faa825fdfae2bb85f0790a877b75d533ff5aa0d5..1a152a32216545f53607880c3908266f4ac41e95 100755 --- a/scripts/show_logs_monitoring.sh +++ b/scripts/show_logs_monitoring.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_pathcomp_backend.sh b/scripts/show_logs_pathcomp_backend.sh index cee99ee4bd19de9b7cd4e45eb651e809397ccaeb..b60b4e06cdf9a197ef0024bf0b24d8c389eb8ae1 100755 --- a/scripts/show_logs_pathcomp_backend.sh +++ b/scripts/show_logs_pathcomp_backend.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_pathcomp_frontend.sh b/scripts/show_logs_pathcomp_frontend.sh index 32f92b59d53b5804e9f1a0b145576667cfa21131..a08a67886dda07506d930e2fa705712ebe404680 100755 --- a/scripts/show_logs_pathcomp_frontend.sh +++ b/scripts/show_logs_pathcomp_frontend.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_service.sh b/scripts/show_logs_service.sh index 6089d0ac6f3008bd5f35e2f813fd1cab2c4d4060..7ca1c1c2f4286a5fc46f7d36197d376472b447ed 100755 --- a/scripts/show_logs_service.sh +++ b/scripts/show_logs_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_slice.sh b/scripts/show_logs_slice.sh index c7bc0b69588307092b22ea3c600669359f04de99..c71bc92eaa4a8d411372fc0ad4194881a5a2a9c8 100755 --- a/scripts/show_logs_slice.sh +++ b/scripts/show_logs_slice.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/show_logs_webui.sh b/scripts/show_logs_webui.sh index 38cffd624b35ce8196c7bbde2838a0971a7d7024..450527be6b916cdf1430efc1ba89d98fd92a43aa 100755 --- a/scripts/show_logs_webui.sh +++ b/scripts/show_logs_webui.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/scripts/update_license_headers.py b/scripts/update_license_headers.py new file mode 100644 index 0000000000000000000000000000000000000000..f721425f89b84fe76783cd2f26b923c0c9005e5a --- /dev/null +++ b/scripts/update_license_headers.py @@ -0,0 +1,114 @@ +#!/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. + +# Run from ~/tfs-ctrl as: +# python scripts/update_license_headers.py + +import logging, os, re, sys +from io import TextIOWrapper + +logging.basicConfig(level=logging.INFO) +LOGGER = logging.getLogger(__name__) + +ROOT_PATH = '.' +FILE_PATH_SKIPPED = 'out-skipped.txt' +FILE_PATH_NO_HEADER = 'out-no-header.txt' +FILE_PATH_UPDATED = 'out-updated.txt' + +RE_OLD_COPYRIGHT = re.compile(r'Copyright\ 2021\-2023\ H2020\ TeraFlow\ \(https\:\/\/www\.teraflow\-h2020\.eu\/\)') +STR_NEW_COPYRIGHT = 'Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)' + +def skip_file(file_path : str) -> bool: + if file_path.endswith('.pyc'): return True + if file_path.endswith('_pb2_grpc.py'): return True + if file_path.endswith('_pb2.py'): return True + if file_path.endswith('.md'): return True + if file_path.endswith('.png'): return True + if file_path.endswith('.json'): return True + if file_path.endswith('.zip'): return True + if file_path.endswith('.zip'): return True + if file_path.endswith('.jar'): return True + if file_path.endswith('/tstat'): return True + if file_path.endswith('/.gitignore'): return True + if file_path.endswith('/.gitkeep'): return True + if file_path.endswith('/coverage/.coverage'): return True + if file_path.startswith('./netconf_openconfig/'): return True + if file_path.startswith('./tmp/'): return True + if '/manifests/cttc-ols/' in file_path: return True + if '/hackfest/netconf-oc/openconfig/' in file_path: return True + if '/.git/' in file_path: return True + if '/.vscode/' in file_path: return True + if '/.pytest_cache/' in file_path: return True + if '/__pycache__/' in file_path: return True + if '/.mvn/' in file_path: return True + if '/hackfest/kafka/kafka_2.13-2.8.0' in file_path: return True + if '/src/device/service/drivers/openconfig/templates/' in file_path: return True + if '/automation/target/generated-sources/grpc/' in file_path: return True + if '/automation/target/kubernetes/' in file_path: return True + if '/policy/target/generated-sources/grpc/' in file_path: return True + if '/policy/target/kubernetes/' in file_path: return True + if '/src/dlt/gateway/' in file_path: return True + if FILE_PATH_SKIPPED in file_path: return True + if FILE_PATH_NO_HEADER in file_path: return True + if FILE_PATH_UPDATED in file_path: return True + if file_path in {'./LICENSE', './.python-version', './.env'}: return True + return False + +def process_line(line_in : str) -> str: + line_out = RE_OLD_COPYRIGHT.sub(STR_NEW_COPYRIGHT, line_in) + if line_out != line_in: return line_out + return line_in + +def process_file( + file_path : str, file_no_header : TextIOWrapper, file_skipped : TextIOWrapper, file_updated : TextIOWrapper +) -> None: + if skip_file(file_path): + file_skipped.write(file_path + '\n') + return + + LOGGER.info(' File {:s}...'.format(str(file_path))) + + temp_file_path = file_path + '.temp' + replaced = False + try: + with open(file_path, encoding='UTF-8') as source: + with open(temp_file_path, 'w', encoding='UTF-8') as target: + for line_in in source: + line_out = process_line(line_in) + target.write(line_out) + replaced = replaced or (line_out != line_in) + except: # pylint: disable=bare-except + replaced = False + + if not replaced: + file_no_header.write(file_path + '\n') + else: + file_updated.write(file_path + '\n') + + os.rename(temp_file_path, file_path) + +def main() -> int: + with open(FILE_PATH_NO_HEADER, 'w', encoding='UTF-8') as file_no_header: + with open(FILE_PATH_SKIPPED, 'w', encoding='UTF-8') as file_skipped: + with open(FILE_PATH_UPDATED, 'w', encoding='UTF-8') as file_updated: + for dirpath, _, filenames in os.walk(ROOT_PATH): + LOGGER.info('Folder {:s}...'.format(str(dirpath))) + for filename in filenames: + file_path = os.path.join(dirpath, filename) + process_file(file_path, file_no_header, file_skipped, file_updated) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/__init__.py b/src/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/automation/.gitlab-ci.yml b/src/automation/.gitlab-ci.yml index 87d141d5bef56c8d3fbd5bb5a0a961ac12598dd6..0dc6284a4086253e64138343a989055581eccdda 100644 --- a/src/automation/.gitlab-ci.yml +++ b/src/automation/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -79,22 +79,22 @@ unit_test automation: - manifests/${IMAGE_NAME}service.yaml - .gitlab-ci.yml -# Deployment of automation service in Kubernetes Cluster -deploy automation: - stage: deploy - needs: - - build automation - - unit_test automation - script: - - kubectl version - - kubectl get all - - kubectl delete --ignore-not-found=true -f "manifests/automationservice.yaml" - - kubectl apply -f "manifests/automationservice.yaml" - - kubectl delete pods --selector app=automationservice - - kubectl get all - 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 +## Deployment of automation service in Kubernetes Cluster +#deploy automation: +# stage: deploy +# needs: +# - build automation +# - unit_test automation +# script: +# - kubectl version +# - kubectl get all +# - kubectl delete --ignore-not-found=true -f "manifests/automationservice.yaml" +# - kubectl apply -f "manifests/automationservice.yaml" +# - kubectl delete pods --selector app=automationservice +# - kubectl get all +# 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/automation/mvnw b/src/automation/mvnw old mode 100755 new mode 100644 diff --git a/src/automation/pom.xml b/src/automation/pom.xml index 4609c2c8db9aae825a86e3820efa9c00a9d737f0..2fd5fd263a698145f39c37ed358982de58dfee77 100644 --- a/src/automation/pom.xml +++ b/src/automation/pom.xml @@ -1,6 +1,6 @@ operation considered complete when IPM responds with suitable status code, + # including "accepted", that only means request is semantically good and queued. + # synchronous --> operation is considered complete once result is also reflected in GETs in REST API. + # 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")) + + self.__cm_connection = CmConnection(address, int(port), username, password, self.__timeout, tls_verify = tls_verify, consistency_mode=consistency_mode) self.__constellation = None - LOGGER.info(f"XrDriver instantiated, cm {address}:{port}, {settings=}") + LOGGER.info(f"XrDriver instantiated, cm {address}:{port}, consistency mode {str(consistency_mode)}, {settings=}") def __str__(self): return f"{self.__hub_module_name}@{self.__cm_address}" diff --git a/src/device/service/drivers/xr/__init__.py b/src/device/service/drivers/xr/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/device/service/drivers/xr/__init__.py +++ b/src/device/service/drivers/xr/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm-cli.py b/src/device/service/drivers/xr/cm-cli.py old mode 100755 new mode 100644 index 8b8fec59c45f458d802a9ff609c345f55948626e..924ca0c966bbefd8b72c655ea788bdfd0ed08c5d --- a/src/device/service/drivers/xr/cm-cli.py +++ b/src/device/service/drivers/xr/cm-cli.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -19,7 +19,7 @@ import argparse import logging import traceback from typing import Tuple -from cm.cm_connection import CmConnection +from cm.cm_connection import CmConnection, ConsistencyMode from cm.tf_service import TFService from cm.transport_capacity import TransportCapacity from cm.connection import Connection @@ -43,6 +43,8 @@ parser.add_argument('--delete-connection', nargs='?', type=str, help="connection parser.add_argument('--list-transport-capacities', action='store_true') parser.add_argument('--create-transport-capacity', nargs='?', type=str, help="uuid;ifname;ifname;capacity") parser.add_argument('--emulate-tf-set-config-service', nargs='?', type=str, help="hubmodule;uuid;ifname;ifname;capacity or hubmodule;uuid;ifname;ifname;capacity;FORCE-VTI-ON") +parser.add_argument('--consistency-mode', nargs='?', type=str, help="asynchronous|synchronous|lifecycle;RETRY_INTERVAL_FLOAT_AS_S") +parser.add_argument('--timeout', help='REST call timeout in seconds (per request and total for consistency validation)', type=int, default=60) args = parser.parse_args() @@ -66,7 +68,22 @@ def cli_modify_string_to_tf_service(cli_create_str: str) -> Tuple[str, TFService print("Invalid object create arguments. Expecting \"href;oid;ifname1;ifname2;bandwidthgbits\" or \"href;oid;ifname1;ifname2\", where ifname is form \"MODULE|PORT\"") exit(-1) -cm = CmConnection(args.ip, args.port, args.username, args.password, tls_verify=False) +if args.consistency_mode: + ca = args.consistency_mode.split(";") + if 2 != len(ca): + print("Invalid consistency mode specification. Expecting \"asynchronous|synchronous|lifecycle;RETRY_INTERVAL_FLOAT_AS_S\"") + exit(-1) + consistency_mode = ConsistencyMode.from_str(ca[0]) + try: + retry_interval = float(ca[1]) + except ValueError: + print("Invalid consistency mode retry interval (non-float)") + exit(-1) +else: + consistency_mode = ConsistencyMode.lifecycle + 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) diff --git a/src/device/service/drivers/xr/cm/__init__.py b/src/device/service/drivers/xr/cm/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/device/service/drivers/xr/cm/__init__.py +++ b/src/device/service/drivers/xr/cm/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/cm_connection.py b/src/device/service/drivers/xr/cm/cm_connection.py index b4aee586668e842b372c3aa7b87240c5041c8118..8ee9ee236c6bcfd504d4044dd023ef3a61fe4802 100644 --- a/src/device/service/drivers/xr/cm/cm_connection.py +++ b/src/device/service/drivers/xr/cm/cm_connection.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations import collections.abc import logging import json @@ -21,6 +22,7 @@ from typing import Optional, List, Dict, Union import re import requests import urllib3 +from enum import Enum from .connection import Connection from .transport_capacity import TransportCapacity from .constellation import Constellation @@ -49,6 +51,22 @@ class ExpiringValue: class UnexpectedEmptyBody(Exception): pass +# 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): + asynchronous = 0 + synchronous = 1 + lifecycle = 2 + + @staticmethod + def from_str(s: str) -> ConsistencyMode: + if "synchronous" == s: + return ConsistencyMode.synchronous + elif "lifecycle" == s: + return ConsistencyMode.lifecycle + # Async is the default + return ConsistencyMode.asynchronous + class HttpResult: def __init__(self, method: str, url: str, params: Dict[str, any] = None): self.method = method @@ -71,7 +89,7 @@ class HttpResult: return f"{self.method} {self.url} {self.params}, status {status_code}, body {body_text}" def process_http_response(self, response: requests.Response, permit_empty_body:bool = False): - LOGGER.info(f"process_http_response(): {self.method}: {self.url} qparams={self.params} ==> {response.status_code}") # FIXME: params + LOGGER.info(f"process_http_response(): {self.method}: {self.url} qparams={self.params} ==> {response.status_code}") self.status_code = response.status_code if response.content != b'null' and len(response.text): self.text = response.text @@ -117,12 +135,19 @@ class HttpResult: return True class CmConnection: - def __init__(self, address: str, port: int, username: str, password: str, timeout=30, tls_verify=True) -> None: + 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: self.__tls_verify = tls_verify if not tls_verify: urllib3.disable_warnings() + self.__consistency_mode = consistency_mode self.__timeout = timeout + self.__retry_interval = retry_interval if retry_interval > 0.01 else 0.01 + # Consistency tries limit is mostly useful for testing where it can be use to make + # test cases faster without timing dependency + self.__max_consistency_tries = max_consistency_tries self.__username = username self.__password = password self.__cm_root = 'https://' + address + ':' + str(port) @@ -275,6 +300,101 @@ class CmConnection: LOGGER.info(f"Deleting transport-capacity {href=} failed, status {resp.status_code}") return False + def apply_create_consistency(self, obj, get_fn): + # Asynchronous, no validation + if self.__consistency_mode == ConsistencyMode.asynchronous: + return obj + + ts_start = time.perf_counter() + log_ts = ts_start + get_result = get_fn() + valid = False + limit = self.__max_consistency_tries + while True: + if get_result: + if self.__consistency_mode == ConsistencyMode.synchronous: + valid = True + break + if get_result.life_cycle_info.is_terminal_state(): + valid = True + break + else: + ts = time.perf_counter() + if ts - log_ts >= self.CONSISTENCY_WAIT_LOG_INTERVAL: + 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: + ts = time.perf_counter() + if ts - log_ts >= self.CONSISTENCY_WAIT_LOG_INTERVAL: + log_ts = ts + LOGGER.info(f"apply_create_consistency(): waiting for REST API object for {obj}, ellapsed time {ts-ts_start} seconds") + limit -= 1 + if limit < 0 or time.perf_counter() - ts_start > self.__timeout: + break + time.sleep(self.__retry_interval) + get_result = get_fn() + + 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") + else: + LOGGER.info(f"Failed to apply create consistency for {obj}, REST object did not appear, duration {duration} seconds") + return None + else: + LOGGER.info(f"Applied create consistency for {get_result}, final life-cycle-state {str(get_result.life_cycle_info)}, duration {duration} seconds") + + return get_result + + def apply_delete_consistency(self, href: str, get_fn): + # Asynchronous, no validation + if self.__consistency_mode == ConsistencyMode.asynchronous: + return None + + ts_start = time.perf_counter() + log_ts = ts_start + get_result = get_fn() + valid = False + limit = self.__max_consistency_tries + while True: + if not get_result: + # Object no longer exist, so this is completely successful operation + valid = True + break + else: + # In delete, treat terminal life cycle state as criteria for ConsistencyMode.synchronous: + # This is unobvious, but in delete non-existence is stronger guarantee than just lifecycle + # (so this is exact opposite ) + if get_result.life_cycle_info.is_terminal_state() and self.__consistency_mode == ConsistencyMode.synchronous: + valid = True + break + else: + ts = time.perf_counter() + if ts - log_ts >= self.CONSISTENCY_WAIT_LOG_INTERVAL: + log_ts = ts + if get_result.life_cycle_info.is_terminal_state(): + LOGGER.info(f"apply_delete_consistency(): waiting for delete to be reflected in REST API for {get_result}, current life-cycle-state: {str(get_result.life_cycle_info)}, ellapsed time {ts-ts_start} seconds") + else: + LOGGER.info(f"apply_delete_consistency(): waiting for life cycle state progress for {get_result}, current: {str(get_result.life_cycle_info)}, ellapsed time {ts-ts_start} seconds") + + limit -= 1 + if limit < 0 or time.perf_counter() - ts_start > self.__timeout: + break + time.sleep(self.__retry_interval) + get_result = get_fn() + + duration = time.perf_counter() - ts_start + if not valid: + if get_result: + if not get_result.life_cycle_info.is_terminal_state(): + LOGGER.info(f"Failed to apply create delete for {get_result}, insufficient life-cycle-state progress ({str(get_result.life_cycle_info)}), duration {duration} seconds") + else: + LOGGER.info(f"Failed to apply delete consistency for {get_result}, REST object did not dissappear, duration {duration} seconds") + else: + LOGGER.info(f"Applied delete consistency for {href}, duration {duration} seconds") + + return get_result + def create_connection(self, connection: Connection) -> Optional[str]: # Create wants a list, so wrap connection to list cfg = [connection.create_config()] @@ -282,8 +402,14 @@ class CmConnection: resp = self.__post("/api/v1/ncs/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"Created connection {connection}") - return connection.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"Create failure for connection {connection}, result {resp}") return None @@ -344,6 +470,7 @@ class CmConnection: #print(resp) # Returns empty body if resp.is_valid_with_status_ignore_body(202): + self.apply_delete_consistency(href, lambda: self.get_connection_by_href(href)) LOGGER.info(f"Deleted connection {href=}") return True else: diff --git a/src/device/service/drivers/xr/cm/connection.py b/src/device/service/drivers/xr/cm/connection.py index 088c743d50d6c04fd0688b5c6318e35eae4d7dc0..98736cce534685189069703d9560b9d34b1d8007 100644 --- a/src/device/service/drivers/xr/cm/connection.py +++ b/src/device/service/drivers/xr/cm/connection.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import annotations from typing import Dict, Optional from dataclasses import dataclass from .tf_service import TFService @@ -33,7 +34,6 @@ class CEndpoint: capacity: int href: Optional[str] - def ifname(self) -> str: if self.vlan is None: return self.module + "|" + self.port @@ -56,6 +56,45 @@ class CEndpoint: return cfg +@dataclass +class LifeCycleInfo: + # State is None (if not known), or one of the following (in future there might be more, so lets not assuem too much) + # 'pendingConfiguration': This state occurs when one of the network connection modules is pending configuration or pending deletion. + # 'configured': This state occurs when all network connection modules are configured. + # 'configurationFailed': This state may occur when at least a configuration of a module from this network connection failed or timeout. + # 'pendingDeletion': This state may occur when a request to delete this network connection is being processed. + # 'deletionFailed': This state may occur when at least a removal of a module from this network connection failed or timeout. + # 'networkConflict': This state may occur when there is a conflict in a network connection module configuration. + # 'deleted': This state occurs when a network connection is removed. + state: Optional[str] + reason: Optional[str] + + def is_terminal_state(self) -> bool: + if self.state is None: + return True + if self.state.endswith('Failed') or self.state.endswith('Conflict'): + return True + if self.state == "configured" or self.state == "deleted": + return True + return False + + def __str__(self): + state_str = "unknown" if self.state is None else self.state + if self.reason: + return f"({state_str} (reason: {self.reason})" + return state_str + + @staticmethod + def new_from_top_level_json(json_dict: Dict[str, any]) -> LifeCycleInfo: + if "state" not in json_dict: + return LifeCycleInfo(None, None) + state = json_dict["state"] + return LifeCycleInfo(state.get("lifecycleState", None), state.get("lifecycleReason", None)) + + @staticmethod + def new_unknown() -> LifeCycleInfo: + return LifeCycleInfo(None, "not yet communicated with IPM") + class ConnectionDeserializationError(Exception): pass @@ -91,6 +130,8 @@ class Connection: ep_mod_aip = get_endpoint_mod_aid(ep) if ep_mod_aip: self.endpoints.append(CEndpoint(*ep_mod_aip, None, get_endpoint_capacity(ep), ep["href"])) + + self.life_cycle_info = LifeCycleInfo.new_from_top_level_json(from_json) self.cm_data = from_json except KeyError as e: raise ConnectionDeserializationError(f"Missing mandatory key {str(e)}") from e @@ -113,6 +154,7 @@ class Connection: # String "none" has a special meaning for implicitTransportCapacity self.implicitTransportCapacity ="none" + self.life_cycle_info = LifeCycleInfo.new_unknown() self.cm_data = None else: # May support other initializations in future diff --git a/src/device/service/drivers/xr/cm/constellation.py b/src/device/service/drivers/xr/cm/constellation.py index 468cf70b6180080bfa11ea3321aca1af623b73fc..f93be0eaeb9195bfe409242f6f535e3b4d8dd7b0 100644 --- a/src/device/service/drivers/xr/cm/constellation.py +++ b/src/device/service/drivers/xr/cm/constellation.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring, wildcard-import, unused-wildcard-import -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/tests/__init__.py b/src/device/service/drivers/xr/cm/tests/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/device/service/drivers/xr/cm/tests/__init__.py +++ b/src/device/service/drivers/xr/cm/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. 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 60cbeac06abf312335abb693f4cd190281fffa7b..4f45be686c2c3a0f619d58230b2c52ed66a3eb6f 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 @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/tests/test_connection.py b/src/device/service/drivers/xr/cm/tests/test_connection.py index cf1f9f8744dd58a31c15fc28a7f8e893aa17fb97..dc330a1e015726d875dfab6a1b52bfa2689c3eed 100644 --- a/src/device/service/drivers/xr/cm/tests/test_connection.py +++ b/src/device/service/drivers/xr/cm/tests/test_connection.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -30,6 +30,8 @@ def test_connection_json(): assert connection.name == "FooBar123" assert "name: FooBar123, id: /network-connections/4505d5d3-b2f3-40b8-8ec2-4a5b28523c03, service-mode: XR-L1, end-points: [(XR LEAF 1|XR-T1, 0), (XR HUB 1|XR-T1, 0)]" == str(connection) + assert "configured" == str(connection.life_cycle_info) + assert connection.life_cycle_info.is_terminal_state() config = connection.create_config() expected_config = {'name': 'FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} @@ -94,6 +96,8 @@ def test_connection_from_service(): # Port mode connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1", "XR HUB 1|XR-T1", 0)) assert connection.create_config() == {'name': 'TF:FooBar123', 'serviceMode': 'XR-L1', 'implicitTransportCapacity': 'portMode', 'endpoints': [{'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR LEAF 1', 'moduleClientIfAid': 'XR-T1'}}}, {'selector': {'moduleIfSelectorByModuleName': {'moduleName': 'XR HUB 1', 'moduleClientIfAid': 'XR-T1'}}}]} + assert '(unknown (reason: not yet communicated with IPM)' == str(connection.life_cycle_info) + assert connection.life_cycle_info.is_terminal_state() # VTI mode connection = Connection(from_tf_service=TFService("FooBar123", "XR LEAF 1|XR-T1.A", "XR HUB 1|XR-T1.100", 0)) diff --git a/src/device/service/drivers/xr/cm/tests/test_constellation.py b/src/device/service/drivers/xr/cm/tests/test_constellation.py index 82848b57e87884826e42234124aade4f447003fe..b0f5803caa2c5832ceba28991fef9744e45f4795 100644 --- a/src/device/service/drivers/xr/cm/tests/test_constellation.py +++ b/src/device/service/drivers/xr/cm/tests/test_constellation.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/tests/test_transport_capacitity.py b/src/device/service/drivers/xr/cm/tests/test_transport_capacitity.py index 7ed085337ac25b1c6983f868de1374fff18633a7..1897b11110e4bcd790769ed29f8e9f5521f461db 100644 --- a/src/device/service/drivers/xr/cm/tests/test_transport_capacitity.py +++ b/src/device/service/drivers/xr/cm/tests/test_transport_capacitity.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. 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 5a97e6ee2ee5d2ca119f2f8c3ffb776f34d8c1bc..3bfd63def82ae89f53ab6ec3a5fc18bd79ecd38f 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 @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -16,10 +16,11 @@ import inspect import os import json -import requests_mock import traceback +import copy +import requests_mock -from ..cm_connection import CmConnection +from ..cm_connection import CmConnection, ConsistencyMode 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"}' @@ -74,6 +75,97 @@ def test_xr_set_config(): ] assert called_mocks == expected_mocks +# In life cycle tests, multiple queries are performed by the driver to check life cycle progress. +# Extend expected mock to match called mock length by replicating the last item (the repeated GET) +def repeat_last_expected(expected: list[tuple], called: list[tuple]) -> list[tuple]: + diff = len(called) - len(expected) + if diff > 0: + expected = list(expected) # Don't modify the original list + expected.extend([expected[-1]] * diff) + return expected + +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) + assert cm.Connect() + + constellation = cm.get_constellation_by_hub_name("XR HUB 1") + assert constellation + + # Note that JSON here is for different object, but we are not inspecting fields where it would matter (e.g. IDs). + json_terminal = res_connection_by_name_json[0] + json_non_terminal = copy.deepcopy(json_terminal) + json_non_terminal["state"]["lifecycleState"] = "pendingConfiguration" + # We go trough 404 and non-terminal lstate first and then terminal state. + m.get("https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432", + [{'text': '', 'status_code': 404}, + { 'json': json_non_terminal, 'status_code': 200 }, + {'json': json_terminal, 'status_code': 200 }]) + + result = set_config_for_service(cm, constellation, uuid, config) + _validate_result(result, True) + + called_mocks = [(r._request.method, r._request.url) for r in m._adapter.request_history] + expected_mocks = [ + ('POST', 'https://127.0.0.1:9999/realms/xr-cm/protocol/openid-connect/token'), # Authentication + ('GET', 'https://127.0.0.1:9999/api/v1/ns/xr-networks?content=expanded&content=expanded&q=%7B%22hubModule.state.module.moduleName%22%3A+%22XR+HUB+1%22%7D'), # Hub module by name + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections?content=expanded&q=%7B%22state.name%22%3A+%22TF%3A12345ABCDEFGHIJKLMN%22%7D'), # Get by name, determine update or create + ('POST', 'https://127.0.0.1:9999/api/v1/ncs/network-connections'), # Create + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432?content=expanded'), # Life cycle state check --> no REST API object + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432?content=expanded'), # Life cycle state check --> non-terminal + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432?content=expanded') # Life cycle state check --> terminal + ] + assert called_mocks == expected_mocks + + ################################################################################ + # Same as before, but without life cycle progress + m.reset_mock() + m.get("https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432", + [{'text': '', 'status_code': 401}, + { '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 + + called_mocks = [(r._request.method, r._request.url) for r in m._adapter.request_history] + expected_mocks_no_connect = [ + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections?content=expanded&q=%7B%22state.name%22%3A+%22TF%3A12345ABCDEFGHIJKLMN%22%7D'), # Get by name, determine update or create + ('POST', 'https://127.0.0.1:9999/api/v1/ncs/network-connections'), # Create + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432?content=expanded'), # Life cycle state check --> no REST API object + ('GET', 'https://127.0.0.1:9999/api/v1/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432?content=expanded'), # Life cycle state check --> non-terminal + ] + assert called_mocks == repeat_last_expected(expected_mocks_no_connect, called_mocks) + + ################################################################################ + # 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) + 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/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432", + [{'text': '', 'status_code': 401}, + { 'json': json_non_terminal, 'status_code': 200 }]) + result = set_config_for_service(cm, constellation, uuid, config) + _validate_result(result, True) + called_mocks = [(r._request.method, r._request.url) for r in m._adapter.request_history] + assert called_mocks == expected_mocks[:2] + expected_mocks_no_connect + + ################################################################################ + # 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) + 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/ncs/network-connections/c3b31608-0bb7-4a4f-9f9a-88b24a059432", + [{'text': '', 'status_code': 401}]) + result = set_config_for_service(cm, constellation, uuid, config) + _validate_result(result, False) + 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) diff --git a/src/device/service/drivers/xr/cm/tf.py b/src/device/service/drivers/xr/cm/tf.py index 1872bfe6c374c9e295b71c8f9673689c67202cd9..c44cb0c9f3ce0e755ce375908a520374e639e40f 100644 --- a/src/device/service/drivers/xr/cm/tf.py +++ b/src/device/service/drivers/xr/cm/tf.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/tf_service.py b/src/device/service/drivers/xr/cm/tf_service.py index 7ba8d9ee44bca7820857c50ff5894099c75e8c5b..98b122fa5f72c69f19ef02e4f5179111b594c041 100644 --- a/src/device/service/drivers/xr/cm/tf_service.py +++ b/src/device/service/drivers/xr/cm/tf_service.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring, wildcard-import, unused-wildcard-import -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/transport_capacity.py b/src/device/service/drivers/xr/cm/transport_capacity.py index d28d5b13707249a60fde04ccf4a1f1d35cc45cc8..a13073d003ddca20888f8b0ef3c60ae59d0c8b32 100644 --- a/src/device/service/drivers/xr/cm/transport_capacity.py +++ b/src/device/service/drivers/xr/cm/transport_capacity.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/cm/utils.py b/src/device/service/drivers/xr/cm/utils.py index ad59dc6616f50023f923dac67025b0b5aa74cf16..9bfdc93853b233a8085b0ebcbce86032840f8578 100644 --- a/src/device/service/drivers/xr/cm/utils.py +++ b/src/device/service/drivers/xr/cm/utils.py @@ -1,5 +1,5 @@ #pylint: disable=invalid-name, missing-function-docstring, line-too-long, logging-fstring-interpolation, missing-class-docstring, missing-module-docstring -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/service/drivers/xr/ipm_rest_api_0_6_71.json b/src/device/service/drivers/xr/ipm_rest_api_0_6_71.json new file mode 100644 index 0000000000000000000000000000000000000000..72c641c5da6add9d32f094a18728030056869312 --- /dev/null +++ b/src/device/service/drivers/xr/ipm_rest_api_0_6_71.json @@ -0,0 +1,26618 @@ +{ + "openapi": "3.0.2", + "info": { + "description": "Infinera XR Optics Intelligent Pluggables Manager Application API", + "title": "IPM", + "version": "1.0", + "x-initials": "NDUS", + "x-cm-api-version": "v0.6.71" + }, + "servers": [ + { + "url": "/api/v1" + } + ], + "paths": { + "/modules": { + "get": { + "operationId": "getModules", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of modules" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all modules" + } + }, + "/modules/{moduleId}": { + "delete": { + "operationId": "deleteSpecificModule", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "delete specific module" + }, + "get": { + "operationId": "getModuleByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module data" + }, + "put": { + "operationId": "UpdateModule", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.update" + } + } + }, + "description": "Update Module", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "update module data" + } + }, + "/modules/{moduleId}/linePtps": { + "get": { + "operationId": "getLinePtps", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of module line ports" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module line ports" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}": { + "get": { + "operationId": "getLinePtpByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module line port data" + }, + "put": { + "operationId": "UpdateLinePtp", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp.update" + } + } + }, + "description": "Update module line port", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update module line port data" + } + }, + "/modules/{moduleId}/ethernetClients": { + "get": { + "operationId": "getEthernetClients", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.ethernetClient" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of ethernetClients" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module client ethernet interfaces" + } + }, + "/modules/{moduleId}/ethernetClients/{ethernetColId}": { + "get": { + "operationId": "getEthernetClientByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Ethernet client signal identifier within module.", + "explode": false, + "in": "path", + "name": "ethernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.ethernetClient" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific client ethernet interface data" + }, + "put": { + "operationId": "updateEthernetClient", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Ethernet client signal identifier within module.", + "explode": false, + "in": "path", + "name": "ethernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.ethernetClient.update" + } + } + }, + "description": "Update client ethernet interface", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update module client ethernet interface data" + } + }, + "/modules/{moduleId}/ethernetClients/{ethernetColId}/acs": { + "get": { + "operationId": "getEthernetClientAcs", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Ethernet client signal identifier within module.", + "explode": false, + "in": "path", + "name": "ethernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ac" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of ethernetClients" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all attachment circuits of a module client ethernet interface" + } + }, + "/modules/{moduleId}/ethernetClients/{ethernetColId}/acs/{acColId}": { + "get": { + "operationId": "getEthernetClientAcByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Ethernet client signal identifier within module.", + "explode": false, + "in": "path", + "name": "ethernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "attachment circuit identifier within module client ethernet interface.", + "explode": false, + "in": "path", + "name": "acColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ac" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific client ethernet attachment circuit data" + } + }, + "/modules/{moduleId}/localConnections": { + "get": { + "operationId": "getLcs", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.localConnection" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of local connections" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module localConnections" + } + }, + "/modules/{moduleId}/localConnections/{lcColId}": { + "get": { + "operationId": "getLcByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "local connection identifier within module.", + "explode": false, + "in": "path", + "name": "lcColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.localConnection" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module local connection data" + } + }, + "/modules/{moduleId}/otus": { + "get": { + "operationId": "getOtus", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.otu" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of otus" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module OTUs" + } + }, + "/modules/{moduleId}/otus/{otuColId}": { + "get": { + "operationId": "getOtuByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within module.", + "explode": false, + "in": "path", + "name": "otuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.otu" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module OTU data" + }, + "put": { + "operationId": "updateOtu", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within module.", + "explode": false, + "in": "path", + "name": "otuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.otu.update" + } + } + }, + "description": "Update OTU", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update module OTU data" + } + }, + "/modules/{moduleId}/otus/{otuColId}/odus": { + "get": { + "operationId": "getOdus", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within module.", + "explode": false, + "in": "path", + "name": "otuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.odu" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of hosts" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module ODUs" + } + }, + "/modules/{moduleId}/otus/{otuColId}/odus/{oduColId}": { + "get": { + "operationId": "getOduByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within module.", + "explode": false, + "in": "path", + "name": "otuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "ODU signal identifier within module.", + "explode": false, + "in": "path", + "name": "oduColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.odu" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module ODU data" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}/carriers": { + "get": { + "operationId": "getCarriers", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of module carriers" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module carriers" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}/carriers/{carrierColId}": { + "get": { + "operationId": "getCarrierByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module carrier data" + }, + "put": { + "operationId": "updateCarrier", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.update" + } + } + }, + "description": "Update Carrier", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update module Carrier data" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}/carriers/{carrierColId}/dscgs": { + "get": { + "operationId": "getDscgs", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscg" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of otus" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all module Dscgs" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}/carriers/{carrierColId}/dscgs/{dscgColId}": { + "get": { + "operationId": "getDscgByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "DSCG identifier within module carrier.", + "explode": false, + "in": "path", + "name": "dscgColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscg" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module dscg data" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}/carriers/{carrierColId}/dscs": { + "get": { + "operationId": "getCarrierDscs", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of modules" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all carrier dscs" + } + }, + "/modules/{moduleId}/linePtps/{linePtpColId}/carriers/{carrierColId}/dscs/{dscColId}": { + "get": { + "operationId": "getCarrierDscByID", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "DSC identifier within module carrier.", + "explode": false, + "in": "path", + "name": "dscColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific carrier dsc data" + }, + "put": { + "operationId": "UpdateCarrierDsc", + "parameters": [ + { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "DSC identifier within module carrier.", + "explode": false, + "in": "path", + "name": "dscColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.update" + } + } + }, + "description": "Update carrier DSC", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update carrier DSC data" + } + }, + "/devices": { + "get": { + "operationId": "getDevices", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": [ + { + "href": "/devices/02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "rt": [ + "cm.device" + ], + "id": "02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "config": { + "status": "onboarded" + }, + "state": { + "moduleName": "XR LEAF 1", + "piid": "abb81108-8bbf-4222-9bf3-0a6bbb75ac65", + "dmn": { + "language": "en", + "value": "Infinera" + }, + "ownershipStatus": "owned", + "status": "onboarded", + "online": true + } + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.device" + }, + "type": "array" + } + } + }, + "description": "Sucessful response containing an array of network connections" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieves available devices cached in the system" + }, + "put": { + "operationId": "UpdateDevices", + "requestBody": { + "content": { + "application/json": { + "example": [ + { + "id": "02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "config": { + "status": "onboarded" + } + }, + { + "id": "230bfea9-1579-412d-54b9-860e8a832608", + "config": { + "status": "offboarded" + } + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.device.updateRequest" + }, + "type": "array" + } + } + }, + "description": "Update device onboard status", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "update Devices" + } + }, + "/devices/{deviceIdx}": { + "get": { + "operationId": "getDeviceByID", + "parameters": [ + { + "description": "Index into the device list", + "explode": false, + "in": "path", + "name": "deviceIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "href": "/devices/02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "rt": [ + "cm.device" + ], + "id": "02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "config": { + "status": "onboarded" + }, + "state": { + "moduleName": "XR LEAF 1", + "piid": "abb81108-8bbf-4222-9bf3-0a6bbb75ac65", + "dmn": { + "language": "en", + "value": "Infinera" + }, + "ownershipStatus": "owned", + "status": "onboarded", + "online": true + } + }, + "schema": { + "$ref": "#/components/schemas/cm.device" + } + } + }, + "description": "Successful response containing the specified device" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific device cached in the system" + }, + "put": { + "operationId": "UpdateDevice", + "parameters": [ + { + "description": "Index into the device list", + "explode": false, + "in": "path", + "name": "deviceIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "example": { + "status": "onboarded" + }, + "schema": { + "$ref": "#/components/schemas/cm.device.config" + } + } + }, + "description": "Update specific device onboard status", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "update Device" + } + }, + "/sw/actions": { + "get": { + "operationId": "getSwCtrlActions", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.sw.action" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of software control action objects" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of software control action objects" + }, + "post": { + "operationId": "createSwCtrlActions", + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.sw.action.create" + }, + "maxLength": 1, + "type": "array" + } + } + }, + "description": "Software control actions", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create software control actions" + } + }, + "/sw/actions/{actionId}": { + "get": { + "operationId": "getSwCtrlActionByID", + "parameters": [ + { + "description": "Software control action identifier within the sw action list", + "explode": false, + "in": "path", + "name": "actionId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.sw.action" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific software control action data" + } + }, + "/sw/moduleActions/": { + "get": { + "operationId": "getSwCtrlModuleActions", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.sw.moduleAction" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of module software control actions" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of module software control actions of an action request" + } + }, + "/sw/moduleActions/{moduleActionId}": { + "get": { + "operationId": "getSwCtrlModuleActionByID", + "parameters": [ + { + "description": "Software control action identifier within the module sw action list", + "explode": false, + "in": "path", + "name": "moduleActionId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.sw.moduleAction" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific module software control action data" + } + }, + "/sw/inventory/ctrl": { + "get": { + "operationId": "getSwImages", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.sw.ctrl" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all XR module SW images" + } + }, + "/sw/inventory/device/{deviceId}/ctrl": { + "get": { + "operationId": "getSwCtrlByID", + "parameters": [ + { + "description": "Device identifier (XR pluggable module or NDU).", + "explode": false, + "in": "path", + "name": "deviceId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.sw.ctrl" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific software control object data" + } + }, + "/sw/inventory/device/{deviceId}/swBanks": { + "get": { + "operationId": "getSwBanks", + "parameters": [ + { + "description": "Device identifier (XR pluggable module or NDU).", + "explode": false, + "in": "path", + "name": "deviceId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.sw.banks" + } + } + }, + "description": "Successful response containing an array of hosts" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all software banks in a XR pluggable module or ndu device" + } + }, + "/sw/inventory/device/{deviceId}/swBanks/{swBankColId}": { + "get": { + "operationId": "getSwBankByID", + "parameters": [ + { + "description": "Device identifier (XR pluggable module or NDU).", + "explode": false, + "in": "path", + "name": "deviceId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Software bank identifier within module.\n- '1': Refers to Bank A\n- '2': Refers to Bank B\n", + "explode": false, + "in": "path", + "name": "swBankColId", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.sw.bank" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific software bank data" + } + }, + "/network-connections": { + "get": { + "operationId": "getConnections", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.network-connection" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all network connections" + }, + "post": { + "operationId": "createConnections", + "requestBody": { + "content": { + "application/json": { + "example": [ + { + "name": "connection 01: Sunnyvale <> San Jose", + "owner": "CM", + "endpoints": [ + { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:2" + } + }, + { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + } + ] + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.network-connection.create" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Network connection configuration data", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": [ + { + "code": "NCS-07-006", + "message": "Missing endpoint selector configuration" + } + ] + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create network connections" + } + }, + "/network-connections/{ncId}": { + "delete": { + "operationId": "deleteConnection", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": [ + { + "code": "NCS-07-006", + "message": "Network-Connection must be owned by CM" + } + ] + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Delete specific network connection" + }, + "get": { + "operationId": "getConnectionByID", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.network-connection" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific network connection data" + }, + "put": { + "operationId": "updateConnection", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "example": { + "name": "connection 01: Sunnyvale <> San Jose", + "owner": "CM" + }, + "schema": { + "$ref": "#/components/schemas/cm.network-connection.update" + } + } + }, + "description": "Update connection", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update specific network connection data" + } + }, + "/network-connections/{ncId}/endpoints": { + "get": { + "operationId": "getConnectionEndpoints", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.network-connection.endpoint" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve network connection endpoints" + }, + "post": { + "operationId": "createConnectionEndpoints", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.create" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Connection endpoints info", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create network connection endpoints" + } + }, + "/network-connections/{ncId}/endpoints/{epId}": { + "delete": { + "operationId": "deleteConnectionEndpoint", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Endpoint identifier within the connection", + "explode": false, + "in": "path", + "name": "epId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": [ + { + "code": "NCS-07-006", + "message": "Network-Connection must be owned by CM" + } + ] + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Delete specific network connection endpoint" + }, + "get": { + "operationId": "getConnectionEndpointByID", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Endpoint identifier within the connection", + "explode": false, + "in": "path", + "name": "epId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.network-connection.endpoint" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific endpoint data from a network connection" + }, + "put": { + "operationId": "updateConnectionEndpoint", + "parameters": [ + { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Endpoint identifier within the connection", + "explode": false, + "in": "path", + "name": "epId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.update" + } + } + }, + "description": "Update connection endpoint", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update specific network connection endpoint data" + } + }, + "/lcs": { + "get": { + "operationId": "getLocalConnections", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.network-connection.local-connection" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all local connections with associated network connections information" + } + }, + "/lcs/{lcId}": { + "get": { + "operationId": "getConnectionLocalConnectionByID", + "parameters": [ + { + "description": "Local connection identifier within the connection scope", + "explode": false, + "in": "path", + "name": "lcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.network-connection.local-connection" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific local connection data with associated network connections" + } + }, + "/acs": { + "get": { + "operationId": "getAcs", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.network-connection.ac" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all attachment circuits with associated network connections information" + } + }, + "/acs/{acId}": { + "get": { + "operationId": "getAcByID", + "parameters": [ + { + "description": "Attachment circuit identifier within the connection scope", + "explode": false, + "in": "path", + "name": "acId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.network-connection.ac" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific attachment circuit data with associated network connections" + } + }, + "/xr-networks": { + "get": { + "operationId": "getConstellations", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.xr-network" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of xr networks" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all xr-network objects" + }, + "post": { + "operationId": "createConstellation", + "requestBody": { + "content": { + "application/json": { + "example": [ + { + "config": { + "name": "Sunnyvale Constellation", + "constellationFrequency": 193000000, + "modulation": "16QAM" + }, + "hubModule": { + "config": { + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:2" + } + }, + "module": { + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "maxAllowedDSCs": 16 + } + } + }, + "leafModules": [ + { + "config": { + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + }, + "module": { + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual" + } + } + }, + { + "config": { + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:99:F8:2c:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + }, + "module": { + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual" + } + } + } + ] + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.xr-network.createRequest" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Constellation info", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create xr-network" + } + }, + "/xr-networks/{networkId}": { + "delete": { + "operationId": "deleteConstellation", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "delete specific xr-network" + }, + "get": { + "operationId": "getConstellationByID", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.xr-network" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific xr-network data" + }, + "put": { + "operationId": "UpdateConstellation", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.xr-network.update" + } + } + }, + "description": "Update xr-network", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update xr-network" + } + }, + "/xr-networks/{networkId}/hubModule": { + "get": { + "operationId": "getConstellationHub", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.xr-network.hubModule" + }, + "type": "array" + } + } + }, + "description": "Successful response containing xr-network hub node" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve xr-network hub info" + }, + "put": { + "operationId": "UpdateConstellationHub", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.xr-network.node.update" + } + } + }, + "description": "Update hub module constellation parameters", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update hub module constellation parameters" + } + }, + "/xr-networks/{networkId}/leafModules": { + "get": { + "operationId": "getConstellationLeafModules", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.xr-network.leafModule" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of xr-network leaf modules" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve xr-network leaf modules" + }, + "post": { + "operationId": "createConstellationLeafModule", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.xr-network.node.create" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Constellation leaf module info", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Add xr-network leaf modules" + } + }, + "/xr-networks/{networkId}/leafModules/{nodeId}": { + "delete": { + "operationId": "deleteConstellationLeafModule", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index of leaf module into xr-network list", + "explode": false, + "in": "path", + "name": "nodeId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "delete specific xr-network leaf module" + }, + "get": { + "operationId": "getConstellationLeafModuleByID", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index of leaf module into xr-network list", + "explode": false, + "in": "path", + "name": "nodeId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.xr-network.leafModule" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific xr-network leaf module data" + }, + "put": { + "operationId": "UpdateConstellationLeafModule", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index of leaf module into xr-network list", + "explode": false, + "in": "path", + "name": "nodeId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.xr-network.node.update" + } + } + }, + "description": "Update leaf module constellation parameters", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update leaf module constellation parameters" + } + }, + "/xr-networks/{networkId}/reachableModules": { + "get": { + "operationId": "getConstellationreachableModules", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.xr-network.reachableModule" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of xr-network reachableModules" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve xr-network reachableModules" + } + }, + "/xr-networks/{networkId}/reachableModules/{nodeId}": { + "get": { + "operationId": "getConstellationReachableModuleByID", + "parameters": [ + { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index of leaf module into xr-network list", + "explode": false, + "in": "path", + "name": "nodeId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.xr-network.reachableModule" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific xr-network reachableModule data" + } + }, + "/transport-capacities": { + "get": { + "operationId": "getTransportCapacities", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.transport-capacity" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all transport-capacity services" + }, + "post": { + "operationId": "createTransportCapacities", + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.transport-capacity.createRequest" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "transport-capacity configuration data", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create transport-capacity services" + } + }, + "/transport-capacities/{tcId}": { + "delete": { + "operationId": "deleteTransportCapacity", + "parameters": [ + { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Delete specific transport-capacity" + }, + "get": { + "operationId": "getTransportCapacityByID", + "parameters": [ + { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.transport-capacity" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific transport-capacity data" + }, + "put": { + "operationId": "UpdateTransportCapacity", + "parameters": [ + { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.transport-capacity.update" + } + } + }, + "description": "Update transport-capacity", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update specific transport-capacity data" + } + }, + "/transport-capacities/{tcId}/endpoints": { + "get": { + "operationId": "getTransportCapacityEndpoints", + "parameters": [ + { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve transport-capacity connection endpoints" + } + }, + "/transport-capacities/{tcId}/endpoints/{epId}": { + "get": { + "operationId": "getTransportCapacityEndpointByID", + "parameters": [ + { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Endpoint identifier within the transport-connection", + "explode": false, + "in": "path", + "name": "epId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific endpoint data from a transport-capacity connection" + }, + "put": { + "operationId": "updateTransportCapacityEndpoint", + "parameters": [ + { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Endpoint identifier within the transport-connection", + "explode": false, + "in": "path", + "name": "epId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.update" + } + } + }, + "description": "Update transport-capacity endpoint", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update specific transport-capacity connection endpoint data" + } + }, + "/capacity-links": { + "get": { + "operationId": "getCapacityLinks", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.capacity-link" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all capacity-links" + } + }, + "/capacity-links/{clId}": { + "get": { + "operationId": "getCapacityLinkByID", + "parameters": [ + { + "description": "Index into the capacity-link list", + "explode": false, + "in": "path", + "name": "clId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.capacity-link" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific capacity-link data" + } + }, + "/subscriptions": { + "get": { + "operationId": "getSubscriptions", + "responses": { + "200": { + "content": { + "application/json": { + "example": [ + { + "href": "/subscription/a9575258-c1ce-4c35-9930-d3d902061cf3", + "rt": [ + "cm.subscription" + ], + "subscriptionId": "a9575258-c1ce-4c35-9930-d3d902061cf3", + "subscriptionName": "ConstellationNeighboursTable", + "notificationChannel": { + "streamAddress": "/api/v1/ws/a9575258-c1ce-4c35-9930-d3d902061cf3" + }, + "subscriptionFilters": [ + { + "requestedNotificationTypes": [ + "AVC" + ], + "requestedResources": [ + { + "resourceType": "cm.network", + "ids": [ + "c664b89e-6a3c-4747-559f-d79d0563a6a9" + ] + } + ] + }, + { + "requestedNotificationTypes": [ + "AVC" + ], + "requestedResources": [ + { + "resourceType": "cm.network", + "moduleIds": [ + "0705ee6f-2c79-40c0-41ce-967da13fbf8f" + ] + } + ] + }, + { + "requestedNotificationTypes": [ + "AVC" + ], + "requestedResources": [ + { + "resourceType": "cm.module", + "moduleIds": [ + "0705ee6f-2c79-40c0-41ce-967da13fbf8f" + ] + } + ] + } + ] + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.subscription" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array subscriptions" + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-001", + "message": "Invalid URI: /api/v1/eg/subscriptions/?error" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of subscriptions" + }, + "post": { + "operationId": "createSubscriptions", + "requestBody": { + "content": { + "application/json": { + "example": [ + { + "subscriptionName": "ConstellationNeighboursTable", + "subscriptionFilters": [ + { + "requestedNotificationTypes": [ + "AVC" + ], + "requestedResources": [ + { + "resourceType": "cm.network", + "ids": [ + "c664b89e-6a3c-4747-559f-d79d0563a6a9" + ] + } + ] + }, + { + "requestedNotificationTypes": [ + "AVC" + ], + "requestedResources": [ + { + "resourceType": "cm.network", + "moduleIds": [ + "0705ee6f-2c79-40c0-41ce-967da13fbf8f" + ] + } + ] + }, + { + "requestedNotificationTypes": [ + "AVC" + ], + "requestedResources": [ + { + "resourceType": "cm.network", + "moduleIds": [ + "0705ee6f-2c79-40c0-41ce-967da13fbf8f" + ] + } + ] + } + ] + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.subscription.request" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Subscription info", + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "example": [ + { + "subscriptionId": "a9575258-c1ce-4c35-9930-d3d902061cf3", + "notificationChannel": { + "streamAddress": "/ws/a9575258-c1ce-4c35-9930-d3d902061cf3" + } + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.subscription.response" + }, + "type": "array" + } + } + }, + "description": "Request has been fulfilled and new a new subscription resource has been created." + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-01-001", + "message": "Invalid request body: line \"5\"; parameter: \"subscriptionFilter.resourceType\"; value: \"cm.invalidResourceType\"" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "503": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create Subscriptions" + } + }, + "/subscriptions/{subscriptionIdx}": { + "delete": { + "operationId": "deleteSubscription", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "subscriptionIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-002", + "message": "Path: \"/subscriptions/0e64146b-1335-4fa6-61ad-f05f9fdde3e0\"; Resource Type: \"cm.subscription\"; ID: \"0e64146b-1335-4fa6-61ad-f05f9fdde3e0\"" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Delete subscription" + }, + "get": { + "operationId": "getSubscriptionById", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "subscriptionIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.subscription" + } + } + }, + "description": "Successful response containing subscription data" + }, + "401": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-002", + "message": "Path: \"/subscriptions/0e64146b-1335-4fa6-61ad-f05f9fdde3e0\"; Resource Type: \"cm.subscription\"; ID: \"0e64146b-1335-4fa6-61ad-f05f9fdde3e0\"" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific subscription data" + }, + "put": { + "operationId": "UpdateSubscription", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "subscriptionIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.subscription.request" + } + } + }, + "description": "Subscription data to be updated", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-01-001", + "message": "Invalid request body: line \"5\"; parameter: \"subscriptionFilter.resourceType\"; value: \"cm.invalidResourceType\"" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-002", + "message": "Path: \"/subscriptions/0e64146b-1335-4fa6-61ad-f05f9fdde3e0\"; Resource Type: \"cm.subscription\"; ID: \"0e64146b-1335-4fa6-61ad-f05f9fdde3e0\"" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "example": { + "errors": { + "code": "EG-00-xxx", + "message": "xxxTBDxxx" + } + }, + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update subscription data" + } + }, + "/{subscriptionIdx}": { + "description": "WebSocket endpoints for existing subscriptions", + "servers": [ + { + "url": "/api/v1/ws" + } + ] + }, + "/hosts": { + "get": { + "operationId": "getHosts", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": [ + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "rt": [ + "cm.host" + ], + "id": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "name": "Sunnyvale Router 001", + "managedBy": "CM", + "location": { + "latitude": 20, + "longitude": 134.1 + }, + "selector": { + "hostSelectorByChassisId": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "state": { + "name": "Sunnyvale Router 001", + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "sysName": "Vendor A Router", + "sysDescr": "", + "managedBy": "CM", + "lldpState": "Present", + "location": { + "latitude": 37.368832, + "longitude": -122.036346 + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "ports": [ + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/5f8c47b4-c02a-6242-260c-185dd04b8faf", + "rt": [ + "cm.host.port" + ], + "id": "5f8c47b4-c02a-6242-260c-185dd04b8faf", + "config": { + "name": "towards San Jose", + "managedBy": "CM", + "selector": { + "ifSelectorByHostPortSourceMAC": { + "portSourceMAC": "28:c0:da:3e:3e:44" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "state": { + "name": "towards San Jose", + "managedBy": "CM", + "lldpState": "Present", + "hostPort": { + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "28:c0:da:3e:3e:44" + }, + "moduleIf": { + "moduleId": "aa079e7c-02df-43ed-636e-71f7bfc212ff", + "moduleName": "Sunnyvale-1/0/0", + "macAddress": "00:0B:F8:00:01:01", + "serialNumber": "12345678901", + "clientIfAid": "XR-T1" + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + } + }, + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/4868c57e-0f4f-11ec-82a8-0242ac130003", + "rt": [ + "cm.host.port" + ], + "id": "4868c57e-0f4f-11ec-82a8-0242ac130003", + "config": { + "name": "towards Santa Clara", + "managedBy": "CM", + "selector": { + "ifSelectorByModuleMAC": { + "moduleMAC": "00:0B:F8:00:01:01", + "clientIfAid": "XR-T1" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "state": { + "name": "towards Santa Clara", + "managedBy": "Host", + "lldpState": "Present", + "hostPort": { + "portIdSubtype": "interfaceName", + "portId": "et-1/0/2:0", + "portSourceMAC": "58:00:BB:00:00:12" + }, + "moduleIf": { + "moduleId": "4e58f211-oa575-41ae-65d6-54fbeba5a2fe", + "moduleName": "Sunnyvale-1/0/2", + "macAddress": "00:0B:F8:00:01:01", + "serialNumber": "12345678901", + "clientIfAid": "XR-T2" + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + } + } + ] + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.host" + }, + "type": "array" + } + } + }, + "description": "Sucessful response containing an array of hosts" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all hosts" + }, + "post": { + "operationId": "createHosts", + "requestBody": { + "content": { + "application/json": { + "example": [ + { + "name": "Sunnyvale Router 001", + "location": { + "latitude": 37.368832, + "longitude": -122.036346 + }, + "selector": { + "hostSelectorByChassisId": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + { + "name": "Santa Clara", + "location": { + "latitude": 37.354107, + "longitude": -121.955238 + }, + "selector": { + "hostSelectorByChassisId": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:10" + } + } + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.host.create" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Host info", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create hosts" + } + }, + "/hosts/{hostId}": { + "delete": { + "operationId": "deleteSpecificHost", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "delete specific host" + }, + "get": { + "operationId": "getHostByID", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "rt": [ + "cm.host" + ], + "id": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "name": "Sunnyvale Router 001", + "managedBy": "CM", + "location": { + "latitude": 37.368832, + "longitude": -122.036346 + }, + "selector": { + "hostSelectorByChassisId": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + }, + "ports": [ + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/5f8c47b4-c02a-6242-260c-185dd04b8faf" + }, + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/4868c57e-0f4f-11ec-82a8-0242ac130003" + } + ] + }, + "state": { + "name": "Sunnyvale Router 001", + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "sysName": "Vendor A Router", + "sysDescr": "", + "lldpState": "Present", + "managedBy": "CM", + "location": { + "latitude": 37.368832, + "longitude": -122.036346 + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + }, + "ports": [ + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/5f8c47b4-c02a-6242-260c-185dd04b8faf", + "rt": [ + "cm.host.port" + ] + }, + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/4868c57e-0f4f-11ec-82a8-0242ac130003", + "rt": [ + "cm.host.port" + ] + } + ] + } + }, + "schema": { + "$ref": "#/components/schemas/cm.host" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific host data" + }, + "put": { + "operationId": "UpdateHost", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "example": { + "name": "Madrid Router 001", + "location": { + "latitude": 40.416775, + "longitude": -3.70379 + } + }, + "schema": { + "$ref": "#/components/schemas/cm.host.update" + } + } + }, + "description": "Update Host", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "update host" + } + }, + "/hosts/{hostId}/ports": { + "get": { + "operationId": "getHostPorts", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": [ + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/5f8c47b4-c02a-6242-260c-185dd04b8faf", + "rt": [ + "cm.host.port" + ] + }, + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/4868c57e-0f4f-11ec-82a8-0242ac130003", + "rt": [ + "cm.host.port" + ] + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.host.port" + }, + "type": "array" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve host' ports" + }, + "post": { + "operationId": "createHostPorts", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "example": [ + { + "name": "towards Lisbon", + "managedBy": "CM", + "selector": { + "ifSelectorByHostPortId": { + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + }, + "labels": { + "region": "Iberia", + "city": "Madrid" + } + } + ], + "schema": { + "items": { + "$ref": "#/components/schemas/cm.host.port.create" + }, + "maxLength": 30, + "type": "array" + } + } + }, + "description": "Host ports info", + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.resource" + }, + "type": "array" + } + } + }, + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Create host ports" + } + }, + "/hosts/{hostId}/ports/{portIdx}": { + "delete": { + "operationId": "deleteHostPort", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index into the Ports list", + "explode": false, + "in": "path", + "name": "portIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "delete specific host port" + }, + "get": { + "operationId": "getHostPort", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index into the Ports list", + "explode": false, + "in": "path", + "name": "portIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.host.port" + } + } + }, + "description": "Successful" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + } + }, + "summary": "Retrieve specific host's port" + }, + "put": { + "operationId": "updateHostPort", + "parameters": [ + { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Index into the Ports list", + "explode": false, + "in": "path", + "name": "portIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.host.port.update" + } + } + }, + "description": "Update Host Port", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "update hosts' Port" + } + }, + "/ndus": { + "get": { + "operationId": "getNdus", + "parameters": [ + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDUs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDUs" + } + }, + "/ndus/{nduId}": { + "delete": { + "operationId": "deleteSpecificNdu", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "delete specific NDU" + }, + "get": { + "operationId": "getNduByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU data" + }, + "put": { + "operationId": "UpdateNdu", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.update" + } + } + }, + "description": "Update NDU", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "update NDU data" + } + }, + "/ndus/{nduId}/ports": { + "get": { + "operationId": "getNduPorts", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU ports" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU ports" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}": { + "get": { + "operationId": "getNduPortByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU port data" + }, + "put": { + "operationId": "UpdateNduPort", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.update" + } + } + }, + "description": "Update NDU port", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU port data" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/toms": { + "get": { + "operationId": "getNduToms", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.tom" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU TOMs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU TOMs" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/toms/{nduTomColId}": { + "get": { + "operationId": "getNduTomByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Tom identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduTomColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.tom" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU port TOM data" + }, + "put": { + "operationId": "UpdateNduTom", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Tom identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduTomColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.tom.update" + } + } + }, + "description": "Update NDU TOM", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU port TOM data" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/xrs": { + "get": { + "operationId": "getNduXRs", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.xr" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU XRs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU XR pluggable interfaces" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/xrs/{nduXrColId}": { + "get": { + "operationId": "getNduXrByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "XR pluggable identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduXrColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.xr" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU port XR pluggable data" + }, + "put": { + "operationId": "UpdateNduXr", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "XR pluggable identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduXrColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.xr.update" + } + } + }, + "description": "Update NDU XR pluggable", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU port XR pluggable data" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/edfas": { + "get": { + "operationId": "getNduEdfas", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.edfa" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU EDFAa" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU EDFAa" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/edfas/{nduEdfaColId}": { + "get": { + "operationId": "getNduEdfaByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Edfa identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduEdfaColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.edfa" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU port EDFA data" + }, + "put": { + "operationId": "UpdateNduEdfa", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Edfa identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduEdfaColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.edfa.update" + } + } + }, + "description": "Update NDU EDFA", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU port EDFA data" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/voas": { + "get": { + "operationId": "getNduVoas", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.voa" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU VOAs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU VOAs" + } + }, + "/ndus/{nduId}/ports/{nduPortColId}/voas/{nduVoaColId}": { + "get": { + "operationId": "getNduVoaByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "VOA identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduVoaColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.voa" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU port VOA data" + }, + "put": { + "operationId": "UpdateNduVoa", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "VOA identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduVoaColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.port.voa.update" + } + } + }, + "description": "Update NDU VOA", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU port VOA data" + } + }, + "/ndus/{nduId}/lineptps": { + "get": { + "operationId": "getNduLinePtps", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.linePtp" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU line ports" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU line ports" + } + }, + "/ndus/{nduId}/lineptps/{nduLinePtpColId}": { + "get": { + "operationId": "getNduLinePtpByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduLinePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.linePtp" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU line port data" + } + }, + "/ndus/{nduId}/lineptps/{nduLinePtpColId}/carriers": { + "get": { + "operationId": "getNduLinePtpCarriers", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduLinePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.linePtp.carrier" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU line port carriers" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU line port carriers" + } + }, + "/ndus/{nduId}/lineptps/{nduLinePtpColId}/carriers/{nduCarrierColId}": { + "get": { + "operationId": "getNduLinePtpCarrierByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Line port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduLinePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Carrier identifier within NDU line port.", + "explode": false, + "in": "path", + "name": "nduCarrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.linePtp.carrier" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU line port carrier data" + } + }, + "/ndus/{nduId}/tribPtps": { + "get": { + "operationId": "getNduTribPtps", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.tribPtp" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU tributary ports" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU tributary ports" + } + }, + "/ndus/{nduId}/tribPtps/{nduTribPtpColId}": { + "get": { + "operationId": "getNduTribPtpByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Triburaty port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduTribPtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.tribPtp" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU tributary port data" + }, + "put": { + "operationId": "UpdateNduTribPtp", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Triburaty port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduTribPtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.tribPtp.update" + } + } + }, + "description": "Update NDU tributary port", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU tributary port data" + } + }, + "/ndus/{nduId}/otus": { + "get": { + "operationId": "getNduOtus", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.otu" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU OTUs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU OTUs" + } + }, + "/ndus/{nduId}/otus/{nduOtuColId}": { + "get": { + "operationId": "getNduOtuByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOtuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.otu" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU OTU data" + }, + "put": { + "operationId": "updateNduOtu", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOtuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.otu.update" + } + } + }, + "description": "Update NDU OTU", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU OTU data" + } + }, + "/ndus/{nduId}/otus/{nduOtuColId}/odus": { + "get": { + "operationId": "getNduOdus", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOtuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.otu.odu" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of ODUs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of ODUs from a NDU OTU" + } + }, + "/ndus/{nduId}/otus/{nduOtuColId}/odus/{nduOduColId}": { + "get": { + "operationId": "getNduOduByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "OTU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOtuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "ODU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOduColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.otu.odu" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific ODU data from a NDU OTU" + } + }, + "/ndus/{nduId}/ethernetClients": { + "get": { + "operationId": "getNduEthernetClients", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.ethernetClient" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU ethernet clients" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU ethernet clients" + } + }, + "/ndus/{nduId}/ethernetClients/{nduEthernetColId}": { + "get": { + "operationId": "getNduEthernetClientByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Ethernet client signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduEthernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.ethernetClient" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU ethernet client data" + }, + "put": { + "operationId": "updateNduEthernetClient", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Ethernet client signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduEthernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.ethernetClient.update" + } + } + }, + "description": "Update NDU Ethernet client", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU Ethernet client data" + } + }, + "/ndus/{nduId}/trails": { + "get": { + "operationId": "getNduTrails", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.trail" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU trails" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU trail" + } + }, + "/ndus/{nduId}/trails/{nduTrailColId}": { + "get": { + "operationId": "getNduTrailByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Trail identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduTrailColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.trail" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU ethernetClient data" + } + }, + "/ndus/{nduId}/fans": { + "get": { + "operationId": "getNduFans", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/cm.ndu.fan" + }, + "type": "array" + } + } + }, + "description": "Successful response containing an array of NDU fan modules" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU fan modules" + } + }, + "/ndus/{nduId}/fans/{nduFanColId}": { + "get": { + "operationId": "getNduFanByID", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Fan identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduFanColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.fan" + } + } + }, + "description": "Successful" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve specific NDU fan module data" + } + }, + "/ndus/{nduId}/pem": { + "get": { + "operationId": "getNduPem", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.pem" + } + } + }, + "description": "Successful response containing an NDU pem module" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU pem module" + }, + "put": { + "operationId": "updateNduPem", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.pem.update" + } + } + }, + "description": "Update NDU PEM", + "required": true + }, + "responses": { + "202": { + "description": "Request has been accepted for processing, but the processing has not been completed." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Update NDU PEM data" + } + }, + "/ndus/{nduId}/leds": { + "get": { + "operationId": "getNduLeds", + "parameters": [ + { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + { + "description": "Query content type\n- 'base' indicates response payload links are not resolved.\n- 'all' indicates that response payload is resolved (i.e. resource representation) and links are not resolved.\n- 'expanded' indicates that response payload and links are resolved\n", + "in": "query", + "name": "content", + "required": false, + "schema": { + "default": "base", + "enum": [ + "base", + "all", + "expanded" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cm.ndu.leds" + } + } + }, + "description": "Successful response containing an NDU LEDs" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "BadRequest" + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Unauthorized" + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Forbidden" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Not Found" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Service Unavailable" + }, + "504": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/errors" + } + } + }, + "description": "Gateway Timeout" + } + }, + "summary": "Retrieve list of all NDU LEDs" + } + } + }, + "components": { + "parameters": { + "moduleId": { + "description": "Module identifier.", + "explode": false, + "in": "path", + "name": "moduleId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "linePtpColId": { + "description": "Line port identifier within module.", + "explode": false, + "in": "path", + "name": "linePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "carrierColId": { + "description": "Carrier identifier within module line port.", + "explode": false, + "in": "path", + "name": "carrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "dscgColId": { + "description": "DSCG identifier within module carrier.", + "explode": false, + "in": "path", + "name": "dscgColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "dscColId": { + "description": "DSC identifier within module carrier.", + "explode": false, + "in": "path", + "name": "dscColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "otuColId": { + "description": "OTU signal identifier within module.", + "explode": false, + "in": "path", + "name": "otuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "oduColId": { + "description": "ODU signal identifier within module.", + "explode": false, + "in": "path", + "name": "oduColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "ethernetColId": { + "description": "Ethernet client signal identifier within module.", + "explode": false, + "in": "path", + "name": "ethernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "hostNeighborColId": { + "description": "hostNeighbor data identifier.", + "explode": false, + "in": "path", + "name": "hostNeighborColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "ethernetLldpColId": { + "description": "ethernet LLDP data identifier.", + "explode": false, + "in": "path", + "name": "ethernetLldpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "lcColId": { + "description": "local connection identifier within module.", + "explode": false, + "in": "path", + "name": "lcColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "acColId": { + "description": "attachment circuit identifier within module client ethernet interface.", + "explode": false, + "in": "path", + "name": "acColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "deviceIdx": { + "description": "Index into the device list", + "explode": false, + "in": "path", + "name": "deviceIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "actionId": { + "description": "Software control action identifier within the sw action list", + "explode": false, + "in": "path", + "name": "actionId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "moduleActionId": { + "description": "Software control action identifier within the module sw action list", + "explode": false, + "in": "path", + "name": "moduleActionId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "deviceId": { + "description": "Device identifier (XR pluggable module or NDU).", + "explode": false, + "in": "path", + "name": "deviceId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "swBankColId": { + "description": "Software bank identifier within module.\n- '1': Refers to Bank A\n- '2': Refers to Bank B\n", + "explode": false, + "in": "path", + "name": "swBankColId", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + }, + "style": "simple" + }, + "ncId": { + "description": "Connection identifier within the connection list", + "explode": false, + "in": "path", + "name": "ncId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "epId": { + "description": "Endpoint identifier within the transport-connection", + "explode": false, + "in": "path", + "name": "epId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "lcId": { + "description": "Local connection identifier within the connection scope", + "explode": false, + "in": "path", + "name": "lcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "acId": { + "description": "Attachment circuit identifier within the connection scope", + "explode": false, + "in": "path", + "name": "acId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "networkId": { + "description": "Index into the xr-network list", + "explode": false, + "in": "path", + "name": "networkId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "nodeId": { + "description": "Index of leaf module into xr-network list", + "explode": false, + "in": "path", + "name": "nodeId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "tcId": { + "description": "Index into the transport-connection list", + "explode": false, + "in": "path", + "name": "tcId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "clId": { + "description": "Index into the capacity-link list", + "explode": false, + "in": "path", + "name": "clId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "subscriptionIdx": { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "subscriptionIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "hostId": { + "description": "Index into the Hosts list", + "explode": false, + "in": "path", + "name": "hostId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "portIdx": { + "description": "Index into the Ports list", + "explode": false, + "in": "path", + "name": "portIdx", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "nduId": { + "description": "NDU identifier.", + "explode": false, + "in": "path", + "name": "nduId", + "required": true, + "schema": { + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type": "string" + }, + "style": "simple" + }, + "nduPortColId": { + "description": "NDU port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduPortColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduTomColId": { + "description": "Tom identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduTomColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduXrColId": { + "description": "XR pluggable identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduXrColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduEdfaColId": { + "description": "Edfa identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduEdfaColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduVoaColId": { + "description": "VOA identifier within NDU port.", + "explode": false, + "in": "path", + "name": "nduVoaColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduLinePtpColId": { + "description": "Line port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduLinePtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduTribPtpColId": { + "description": "Triburaty port identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduTribPtpColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduCarrierColId": { + "description": "Carrier identifier within NDU line port.", + "explode": false, + "in": "path", + "name": "nduCarrierColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduOtuColId": { + "description": "OTU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOtuColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduOduColId": { + "description": "ODU signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduOduColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduEthernetColId": { + "description": "Ethernet client signal identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduEthernetColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduTrailColId": { + "description": "Trail identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduTrailColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + }, + "nduFanColId": { + "description": "Fan identifier within NDU.", + "explode": false, + "in": "path", + "name": "nduFanColId", + "required": true, + "schema": { + "type": "integer" + }, + "style": "simple" + } + }, + "schemas": { + "cm.module": { + "description": "Definition of host object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.module.config" + }, + "state": { + "$ref": "#/components/schemas/cm.module.state" + }, + "linePtps": { + "$ref": "#/components/schemas/cm.module.linePtps" + }, + "otus": { + "$ref": "#/components/schemas/cm.module.otus" + }, + "ethernetClients": { + "$ref": "#/components/schemas/cm.module.ethernetClients" + }, + "localConnections": { + "$ref": "#/components/schemas/cm.module.localConnections" + } + } + }, + "cm.module.config": { + "additionalProperties": false, + "description": "Definition of module configurable parameters", + "properties": { + "moduleName": { + "$ref": "#/components/schemas/cm.module.parameters.moduleName" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.module.state": { + "description": "Definition of module state object", + "properties": { + "moduleName": { + "$ref": "#/components/schemas/xr.device.n" + }, + "moduleAid": { + "$ref": "#/components/schemas/xr.device.aid" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + }, + "configuredRole": { + "$ref": "#/components/schemas/xr.configuration.configuredRole" + }, + "currentRole": { + "$ref": "#/components/schemas/xr.configuration.currentRole" + }, + "roleStatus": { + "$ref": "#/components/schemas/xr.configuration.roleStatus" + }, + "trafficMode": { + "$ref": "#/components/schemas/xr.configuration.trafficMode" + }, + "serdesRate": { + "$ref": "#/components/schemas/xr.configuration.serdesRate" + }, + "fiberConnectionMode": { + "$ref": "#/components/schemas/xr.configuration.fiberConnectionMode" + }, + "tcMode": { + "$ref": "#/components/schemas/xr.configuration.tcMode" + }, + "connectivityState": { + "$ref": "#/components/schemas/cm.module.parameters.connectivityState" + }, + "hwDescription": { + "$ref": "#/components/schemas/cm.module.state.hwDescription" + } + } + }, + "cm.module.state.hwDescription": { + "description": "Definition of module platform properties", + "properties": { + "pi": { + "$ref": "#/components/schemas/xr.platform.pi" + }, + "mnfv": { + "$ref": "#/components/schemas/xr.platform.mnfv" + }, + "mnmn": { + "$ref": "#/components/schemas/xr.platform.mnmn" + }, + "mnmo": { + "$ref": "#/components/schemas/xr.platform.mnmo" + }, + "mnhw": { + "$ref": "#/components/schemas/xr.platform.mnhw" + }, + "mndt": { + "$ref": "#/components/schemas/xr.platform.mndt" + }, + "serialNumber": { + "$ref": "#/components/schemas/xr.platform.mnsel" + }, + "clei": { + "$ref": "#/components/schemas/xr.platform.clei" + }, + "macAddress": { + "$ref": "#/components/schemas/xr.platform.macAddress" + }, + "connectorType": { + "$ref": "#/components/schemas/xr.platform.connectorType" + }, + "formFactor": { + "$ref": "#/components/schemas/xr.platform.formFactor" + }, + "piid": { + "$ref": "#/components/schemas/xr.device.piid" + }, + "dmn": { + "$ref": "#/components/schemas/xr.device.dmn" + }, + "sv": { + "$ref": "#/components/schemas/xr.device.sv" + }, + "icv": { + "$ref": "#/components/schemas/xr.device.icv" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "hwDescription" + } + }, + "cm.module.parameters.moduleName": { + "description": "Property to change the device name. This is also reflected in the same property in oic.wk.d", + "maxLength": 64, + "title": "Device name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleName" + } + }, + "cm.module.parameters.connectivityState": { + "description": "The CM connectivity state between the CM and the device.", + "enum": [ + "active", + "inactive" + ], + "title": "Connectivity state", + "type": "string", + "x-enum-varnames": [ + "Active", + "Inactive" + ], + "x-oapi-codegen-extra-tags": { + "bson": "connectivityState" + } + }, + "cm.module.update": { + "additionalProperties": false, + "description": "Definition of module editable parameters", + "minProperties": 1, + "properties": { + "moduleName": { + "$ref": "#/components/schemas/cm.module.parameters.moduleName" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.module.linePtp": { + "description": "Definition of module line port object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.module.linePtp.config" + }, + "state": { + "$ref": "#/components/schemas/cm.module.linePtp.state" + }, + "carriers": { + "$ref": "#/components/schemas/cm.module.linePtp.carriers" + } + } + }, + "cm.module.linePtps": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "linePtps" + } + }, + "cm.module.linePtp.config": { + "additionalProperties": false, + "description": "Definition of module port configurable parameters", + "properties": { + "administrativeState": { + "$ref": "#/components/schemas/cm.module.linePtp.parameters.administrativeState" + } + }, + "type": "object" + }, + "cm.module.linePtp.state": { + "description": "Definition of module line port state object", + "properties": { + "linePtpAid": { + "$ref": "#/components/schemas/xr.lineptp.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.lineptp.parentAid" + }, + "administrativeState": { + "$ref": "#/components/schemas/cm.module.linePtp.parameters.administrativeState" + }, + "operStatus": { + "$ref": "#/components/schemas/xr.lineptp.operStatus" + }, + "discoveredNeighbors": { + "$ref": "#/components/schemas/cm.module.linePtp.discoveredNeighbors" + }, + "ctrlPlaneNeighbors": { + "$ref": "#/components/schemas/cm.module.linePtp.ctrlPlaneNeighbors" + } + }, + "type": "object" + }, + "cm.module.linePtp.ctrlPlaneNeighbor": { + "properties": { + "macAddress": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.macAddress" + }, + "currentRole": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.currentRole" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.constellationFrequency" + }, + "conState": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.conState" + }, + "lastConStateChange": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.lastConStateChange" + } + } + }, + "cm.module.linePtp.ctrlPlaneNeighbors": { + "description": "Array of XR modules to which control plane connectivity is, or has been, established.", + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.ctrlPlaneNeighbor" + }, + "maxItems": 20, + "minItems": 0, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "ctrlPlaneNeighbors" + } + }, + "cm.module.linePtp.discoveredNeighbor": { + "properties": { + "macAddress": { + "$ref": "#/components/schemas/xr.discovered.neighbor.macAddress" + }, + "currentRole": { + "$ref": "#/components/schemas/xr.discovered.neighbor.currentRole" + }, + "discoveredTime": { + "$ref": "#/components/schemas/xr.discovered.neighbor.discoveredTime" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/xr.discovered.neighbor.constellationFrequency" + } + } + }, + "cm.module.linePtp.discoveredNeighbors": { + "description": "Array of XR modules discovered in the last performed fast scan.\nEntities in the ctrlPlaneNeighbors array will not be shown here.\n", + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.discoveredNeighbor" + }, + "maxItems": 10, + "minItems": 0, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "discoveredNeighbors" + } + }, + "cm.module.linePtp.parameters.administrativeState": { + "description": "Configurable admin state of the line side port", + "enum": [ + "lock", + "unlock", + "maintenance" + ], + "title": "Administrative State", + "type": "string", + "x-enum-varnames": [ + "Lock", + "Unlock", + "Maintenance" + ], + "x-oapi-codegen-extra-tags": { + "bson": "administrativeState" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.update": { + "additionalProperties": false, + "description": "Definition of module line port editable parameters", + "minProperties": 1, + "properties": { + "administrativeState": { + "$ref": "#/components/schemas/cm.module.linePtp.parameters.administrativeState" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier": { + "description": "Definition of module carrier object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.config" + }, + "state": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.state" + }, + "dscgs": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscgs" + }, + "dscs": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscs" + } + } + }, + "cm.module.linePtp.carriers": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "carriers" + } + }, + "cm.module.linePtp.carrier.config": { + "description": "Definition of module carrier configurable parameters", + "properties": { + "loopback": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.parameters.loopback" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.state": { + "description": "Definition of module carrier state object", + "properties": { + "carrierAid": { + "$ref": "#/components/schemas/xr.carrier.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.carrier.parentAid" + }, + "frequencyCtrl": { + "$ref": "#/components/schemas/xr.carrier.frequencyCtrl" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/xr.carrier.constellationFrequency" + }, + "operatingFrequency": { + "$ref": "#/components/schemas/xr.carrier.operatingFrequency" + }, + "ncoFrequency": { + "$ref": "#/components/schemas/xr.carrier.ncoFrequency" + }, + "modulation": { + "$ref": "#/components/schemas/xr.carrier.modulation" + }, + "capacity": { + "$ref": "#/components/schemas/xr.carrier.capacity" + }, + "clientPortMode": { + "$ref": "#/components/schemas/xr.carrier.clientPortMode" + }, + "baudRate": { + "$ref": "#/components/schemas/xr.carrier.baudRate" + }, + "maxAllowedDSCs": { + "$ref": "#/components/schemas/xr.carrier.maxAllowedDSCs" + }, + "txPowerTargetPerDsc": { + "$ref": "#/components/schemas/xr.carrier.txPowerTargetPerDsc" + }, + "loopback": { + "$ref": "#/components/schemas/xr.carrier.diagnostic.loopback" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.parameters.loopback": { + "default": "disabled", + "description": "Enable/Disable loopback", + "enum": [ + "disabled", + "terminal" + ], + "title": "Loopback", + "type": "string", + "x-enum-varnames": [ + "Disabled", + "Terminal" + ], + "x-oapi-codegen-extra-tags": { + "bson": "loopback" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.update": { + "additionalProperties": false, + "description": "Definition of module carrier editable parameters", + "minProperties": 1, + "properties": { + "loopback": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.parameters.loopback" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.dsc": { + "description": "Definition of module dsc object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.config" + }, + "state": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.state" + } + } + }, + "cm.module.linePtp.carrier.dscs": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "dscs" + } + }, + "cm.module.linePtp.carrier.dsc.config": { + "additionalProperties": false, + "description": "Definition of module dsc configurable parameters", + "properties": { + "usability": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.usability" + }, + "txEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.txEnabled" + }, + "rxEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.rxEnabled" + }, + "facPRBSGenEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.facPRBSGenEnabled" + }, + "facPRBSMonEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.facPRBSMonEnabled" + }, + "powerOffset": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.powerOffset" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.dsc.state": { + "description": "Definition of module dsc state object", + "properties": { + "dscAid": { + "$ref": "#/components/schemas/xr.carrier.dsc.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.carrier.dsc.parentAid" + }, + "cDsc": { + "$ref": "#/components/schemas/xr.carrier.dsc.cDsc" + }, + "usability": { + "$ref": "#/components/schemas/xr.carrier.dsc.usability" + }, + "txEnabled": { + "$ref": "#/components/schemas/xr.carrier.dsc.txEnabled" + }, + "rxEnabled": { + "$ref": "#/components/schemas/xr.carrier.dsc.rxEnabled" + }, + "txStatus": { + "$ref": "#/components/schemas/xr.carrier.dsc.txStatus" + }, + "rxStatus": { + "$ref": "#/components/schemas/xr.carrier.dsc.rxStatus" + }, + "powerOffset": { + "$ref": "#/components/schemas/xr.carrier.dsc.powerOffset" + }, + "facPRBSGenEnabled": { + "$ref": "#/components/schemas/xr.carrier.dsc.diagnostic.facPRBSGenEnabled" + }, + "facPRBSMonEnabled": { + "$ref": "#/components/schemas/xr.carrier.dsc.diagnostic.facPRBSMonEnabled" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.dsc.parameters.usability": { + "default": "usable", + "description": "Usability of this DSC. Configurable to control the allowed uses.\n * `usable` - DSC is usable for either PRBS or data.\n * `prbsOnly` - DSC is usable only for PRBS. This is done for optical power balancing reasons.\n * `reserved` - DSC is reserved and is not usable for either PRBS or data.\n", + "enum": [ + "usable", + "prbsOnly", + "reserved" + ], + "title": "Usability", + "type": "string", + "x-enum-varnames": [ + "Usable", + "PRBS only", + "Reserved" + ], + "x-oapi-codegen-extra-tags": { + "bson": "usability" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.dsc.parameters.txEnabled": { + "default": false, + "description": "Configurable to enable/disable Tx transmission on this DSC. \nWhen disabled, this prevents any traffic from going out of the DSC.\n", + "title": "TX Enabled", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "txEnabled" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.dsc.parameters.rxEnabled": { + "default": true, + "description": "Configurable to enable/disable the DSC to receive traffic.", + "title": "Rx Enabled", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "rxEnabled" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.dsc.parameters.facPRBSGenEnabled": { + "default": false, + "description": "Configurable to enable/disable facility PRBS test pattern generation", + "title": "Facility PRBS generation", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSGenEnabled" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.dsc.parameters.facPRBSMonEnabled": { + "default": false, + "description": "Configurable to enable/disable facility PRBS test pattern monitoring", + "title": "Facility PRBS monitoring", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSMonEnabled" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.dsc.parameters.powerOffset": { + "default": 0, + "description": "Power offset relative to the average DSC power.", + "format": "double", + "maximum": 6, + "minimum": -6, + "multipleOf": 0.1, + "title": "Power offset", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "powerOffset" + }, + "x-trafficAffecting": true + }, + "cm.module.linePtp.carrier.dsc.update": { + "additionalProperties": false, + "description": "Definition of module dsc editable parameters", + "minProperties": 1, + "properties": { + "usability": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.usability" + }, + "txEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.txEnabled" + }, + "rxEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.rxEnabled" + }, + "facPRBSGenEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.facPRBSGenEnabled" + }, + "facPRBSMonEnabled": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.facPRBSMonEnabled" + }, + "powerOffset": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dsc.parameters.powerOffset" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.dscg": { + "description": "Definition of module dscg object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscg.state" + } + } + }, + "cm.module.linePtp.carrier.dscgs": { + "items": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscg" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "dscgs" + } + }, + "cm.module.linePtp.carrier.dscg.state": { + "description": "Definition of module dscg state object", + "properties": { + "dscgAid": { + "$ref": "#/components/schemas/xr.carrier.dscg.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.carrier.dscg.parentAid" + }, + "txDSCs": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscg.txDSCs" + }, + "rxDSCs": { + "$ref": "#/components/schemas/cm.module.linePtp.carrier.dscg.rxDSCs" + } + }, + "type": "object" + }, + "cm.module.linePtp.carrier.dscg.txDSCs": { + "items": { + "$ref": "#/components/schemas/xr.carrier.dsc.aid" + }, + "maxItems": 16, + "minItems": 0, + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "txDSCs" + } + }, + "cm.module.linePtp.carrier.dscg.rxDSCs": { + "items": { + "$ref": "#/components/schemas/xr.carrier.dsc.aid" + }, + "maxItems": 16, + "minItems": 0, + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "rxDSCs" + } + }, + "cm.module.otu": { + "description": "Definition of module otu object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.module.otu.config" + }, + "state": { + "$ref": "#/components/schemas/cm.module.otu.state" + }, + "odus": { + "$ref": "#/components/schemas/cm.module.odus" + } + } + }, + "cm.module.otus": { + "items": { + "$ref": "#/components/schemas/cm.module.otu" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "otus" + } + }, + "cm.module.otu.config": { + "additionalProperties": false, + "description": "Definition of module otu configurable parameters", + "properties": { + "txTTI": { + "$ref": "#/components/schemas/cm.module.otu.parameters.txTTI" + }, + "expectedTTI": { + "$ref": "#/components/schemas/cm.module.otu.parameters.expectedTTI" + }, + "facPRBSGen": { + "$ref": "#/components/schemas/cm.module.otu.parameters.facPRBSGen" + }, + "facPRBSMon": { + "$ref": "#/components/schemas/cm.module.otu.parameters.facPRBSMon" + } + }, + "type": "object" + }, + "cm.module.otu.state": { + "description": "Definition of module otu state object", + "properties": { + "otuAid": { + "$ref": "#/components/schemas/xr.otu.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.otu.parentAid" + }, + "otuType": { + "$ref": "#/components/schemas/xr.otu.otuType" + }, + "rate": { + "$ref": "#/components/schemas/xr.otu.rate" + }, + "operStatus": { + "$ref": "#/components/schemas/xr.otu.operStatus" + }, + "txTTI": { + "$ref": "#/components/schemas/xr.otu.txTTI" + }, + "rxTTI": { + "$ref": "#/components/schemas/xr.otu.rxTTI" + }, + "expectedTTI": { + "$ref": "#/components/schemas/xr.otu.expectedTTI" + }, + "facPRBSGen": { + "$ref": "#/components/schemas/xr.otu.diagnostic.facPRBSGen" + }, + "facPRBSMon": { + "$ref": "#/components/schemas/xr.otu.diagnostic.facPRBSMon" + } + }, + "type": "object" + }, + "cm.module.otu.parameters.txTTI": { + "default": "", + "description": "Up to 64 byte string for transmitting as TTI.", + "maxLength": 64, + "title": "Transmit TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "txTTI" + } + }, + "cm.module.otu.parameters.expectedTTI": { + "default": "", + "description": "Up to 64 byte string of TTI that is expected to be received.", + "maxLength": 64, + "title": "Expected TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "expectedTTI" + } + }, + "cm.module.otu.parameters.facPRBSGen": { + "default": "disabled", + "description": "Enable/Disable facility PRBS test pattern generation", + "enum": [ + "enabled", + "disabled" + ], + "title": "Facility PRBS generation", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSGen" + }, + "x-trafficAffecting": true + }, + "cm.module.otu.parameters.facPRBSMon": { + "default": "disabled", + "description": "Enable/Disable facility PRBS test pattern monitoring", + "enum": [ + "enabled", + "disabled" + ], + "title": "Facility PRBS monitoring", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSMon" + }, + "x-trafficAffecting": true + }, + "cm.module.otu.update": { + "additionalProperties": false, + "description": "Definition of module otu editable parameters", + "minProperties": 1, + "properties": { + "txTTI": { + "$ref": "#/components/schemas/cm.module.otu.parameters.txTTI" + }, + "expectedTTI": { + "$ref": "#/components/schemas/cm.module.otu.parameters.expectedTTI" + }, + "facPRBSGen": { + "$ref": "#/components/schemas/cm.module.otu.parameters.facPRBSGen" + }, + "facPRBSMon": { + "$ref": "#/components/schemas/cm.module.otu.parameters.facPRBSMon" + } + }, + "type": "object" + }, + "cm.module.odu": { + "description": "Definition of module odu object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.module.odu.state" + } + } + }, + "cm.module.odus": { + "items": { + "$ref": "#/components/schemas/cm.module.odu" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "odus" + } + }, + "cm.module.odu.state": { + "description": "Definition of module odu state object", + "properties": { + "oduAid": { + "$ref": "#/components/schemas/xr.otu.odu.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.otu.odu.parentAid" + }, + "oduType": { + "$ref": "#/components/schemas/xr.otu.odu.oduType" + }, + "operStatus": { + "$ref": "#/components/schemas/xr.otu.odu.operStatus" + } + } + }, + "cm.module.ethernetClient": { + "description": "Definition of module ethernetClient object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.module.ethernetClient.config" + }, + "state": { + "$ref": "#/components/schemas/cm.module.ethernetClient.state" + }, + "acs": { + "$ref": "#/components/schemas/cm.module.ethernetClient.acs" + } + } + }, + "cm.module.ethernetClients": { + "items": { + "$ref": "#/components/schemas/cm.module.ethernetClient" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "ethernetClients" + } + }, + "cm.module.ethernetClient.config": { + "additionalProperties": false, + "description": "Definition of module ethernetClient configuration object", + "properties": { + "fecMode": { + "$ref": "#/components/schemas/cm.module.ethernetClient.parameters.fecMode" + }, + "loopbackType": { + "$ref": "#/components/schemas/cm.module.ethernetClient.parameters.loopbackType" + }, + "loopbackMode": { + "$ref": "#/components/schemas/cm.module.ethernetClient.parameters.loopbackMode" + }, + "lldp": { + "$ref": "#/components/schemas/cm.module.ethernetClient.config.lldp" + } + }, + "type": "object" + }, + "cm.module.ethernetClient.config.lldp": { + "additionalProperties": false, + "description": "Definition of module ethernetClient ethernetLLDP configurable parameters", + "properties": { + "adminStatus": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.adminStatus" + }, + "gccFwd": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.gccFwd" + }, + "hostRxDrop": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.hostRxDrop" + }, + "TTLUsage": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.TTLUsage" + }, + "clrStats": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.clrStats" + }, + "flushHostDb": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.flushHostDb" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "lldp" + } + }, + "cm.module.ethernetClient.state": { + "description": "Definition of module ethernetClient state parameters", + "properties": { + "clientIfAid": { + "$ref": "#/components/schemas/xr.ethernet.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ethernet.parentAid" + }, + "clientIfPortSpeed": { + "$ref": "#/components/schemas/xr.ethernet.portSpeed" + }, + "fecType": { + "$ref": "#/components/schemas/xr.ethernet.fecType" + }, + "fecMode": { + "$ref": "#/components/schemas/xr.ethernet.fecMode" + }, + "loopbackType": { + "$ref": "#/components/schemas/xr.ethernet.diagnostic.loopbackType" + }, + "loopbackMode": { + "$ref": "#/components/schemas/xr.ethernet.diagnostic.loopbackMode" + }, + "lldp": { + "$ref": "#/components/schemas/cm.module.ethernetClient.state.lldp" + } + }, + "type": "object" + }, + "cm.module.ethernetClient.state.lldp": { + "description": "Definition of module ethernetClient ethernetLLDP state parameters", + "properties": { + "lldpconfigAid": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.parentAid" + }, + "adminStatus": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.adminStatus" + }, + "gccFwd": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.gccFwd" + }, + "hostRxDrop": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.hostRxDrop" + }, + "TTLUsage": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.TTLUsage" + }, + "tooManyNeighbors": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.tooManyNeighbors" + }, + "clrStats": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.clrStats" + }, + "flushHostDb": { + "$ref": "#/components/schemas/xr.ethernet.lldpconfig.flushHostDb" + }, + "neighbors": { + "$ref": "#/components/schemas/cm.module.ethernetClient.state.lldp.neighbors" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "lldp" + } + }, + "cm.module.ethernetClient.state.lldp.neighbors": { + "items": { + "$ref": "#/components/schemas/cm.module.ethernetClient.state.lldp.neighbor" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "neighbors" + } + }, + "cm.module.ethernetClient.state.lldp.neighbor": { + "description": "Definition of module host neighbors state parameters", + "properties": { + "hostneighborAid": { + "$ref": "#/components/schemas/xr.ethernet.hostneighbors.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ethernet.hostneighbors.parentAid" + }, + "portSourceMAC": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.localPortSourceMAC" + }, + "chassisIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisIdSubtype" + }, + "chassisId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisId" + }, + "portIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portIdSubtype" + }, + "portId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portId" + }, + "portDescr": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portDescr" + }, + "sysName": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysName" + }, + "sysDescr": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysDescr" + }, + "sysTTL": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysTTL" + }, + "lldpPDU": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.lldpPDU" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "neighbor" + } + }, + "cm.module.ethernetClient.parameters.fecMode": { + "default": "enabled", + "description": "Forward error correction mode of operation", + "enum": [ + "enabled", + "disabled" + ], + "title": "Forward error correction mode", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "fecMode" + }, + "x-trafficAffecting": true + }, + "cm.module.ethernetClient.parameters.loopbackType": { + "default": "loopbackAndContinue", + "description": "Loopback type.\n* `loopbackAndContinue` - Signal is looped back and is also forwarded downstream.\n* `loopback` - Signal is looped back and LF maintenance signal is sent downstream.\n", + "enum": [ + "loopbackAndContinue", + "loopback" + ], + "title": "Loopback type", + "type": "string", + "x-enum-varnames": [ + "Loopback and continue", + "Loopback" + ], + "x-oapi-codegen-extra-tags": { + "bson": "loopbackType" + } + }, + "cm.module.ethernetClient.parameters.loopbackMode": { + "default": "disabled", + "description": "Post-FEC Loopback mode for the ethernet client.", + "enum": [ + "disabled", + "facility", + "terminal" + ], + "title": "Loopback mode", + "type": "string", + "x-enum-varnames": [ + "Disabled", + "Facility", + "Terminal" + ], + "x-oapi-codegen-extra-tags": { + "bson": "loopbackMode" + }, + "x-trafficAffecting": true + }, + "cm.module.ethernetClient.ethernetLLDP.parameters.adminStatus": { + "default": "disabled", + "description": "Administrative state to Enable/Disable LLDP in rxOnly mode.", + "enum": [ + "rxOnly", + "disabled" + ], + "title": "Admin state", + "type": "string", + "x-enum-varnames": [ + "RX only", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "adminStatus" + } + }, + "cm.module.ethernetClient.ethernetLLDP.parameters.gccFwd": { + "default": false, + "description": "Enable/Disable forwarding of untagged LLDP frames over GCC.\n * `true` - Enabled.\n * `false` - Disabled.\n", + "title": "Forward GCC", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "gccFwd" + } + }, + "cm.module.ethernetClient.ethernetLLDP.parameters.hostRxDrop": { + "default": false, + "description": "Enable/Disable LLDP drop in Rx direction of Ethernet Client ports.\n * `true`: - Enabled.\n * `false`: - Disabled.\n", + "title": "LLDP drop", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "hostRxDrop" + } + }, + "cm.module.ethernetClient.ethernetLLDP.parameters.TTLUsage": { + "default": true, + "description": "Enable/Disable usage of TTL values for flushing/starting LLDP internal flush timer.\n * `true`: - Enabled.\n * `false`: - Disabled.\n", + "title": "TTL usage", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "TTLUsage" + } + }, + "cm.module.ethernetClient.ethernetLLDP.parameters.clrStats": { + "default": false, + "description": "Action to clear LLDP statistics. Set to true to trigger the action. Server resets it to false when action is completed.", + "title": "Clear LLDP statistics", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "clrStats" + } + }, + "cm.module.ethernetClient.ethernetLLDP.parameters.flushHostDb": { + "default": false, + "description": "Action to flush the learned host system information. Set to true to trigger the action. Server resets it to false when action is completed.", + "title": "Flush neighbor information", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "flushHostDb" + } + }, + "cm.module.ethernetClient.update": { + "additionalProperties": false, + "description": "Definition of module ethernetClient editable object", + "minProperties": 1, + "properties": { + "fecMode": { + "$ref": "#/components/schemas/cm.module.ethernetClient.parameters.fecMode" + }, + "loopbackType": { + "$ref": "#/components/schemas/cm.module.ethernetClient.parameters.loopbackType" + }, + "loopbackMode": { + "$ref": "#/components/schemas/cm.module.ethernetClient.parameters.loopbackMode" + }, + "lldp": { + "$ref": "#/components/schemas/cm.module.ethernetClient.update.lldp" + } + }, + "type": "object" + }, + "cm.module.ethernetClient.update.lldp": { + "additionalProperties": false, + "description": "Definition of module ethernetClient lldp editable parameters", + "minProperties": 1, + "properties": { + "adminStatus": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.adminStatus" + }, + "gccFwd": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.gccFwd" + }, + "hostRxDrop": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.hostRxDrop" + }, + "TTLUsage": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.TTLUsage" + }, + "clrStats": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.clrStats" + }, + "flushHostDb": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ethernetLLDP.parameters.flushHostDb" + } + }, + "type": "object" + }, + "cm.module.ethernetClient.ac": { + "description": "Definition of module ethernetClient attachmentCircuit object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.module.ethernetClient.attachmentCircuit.state" + } + } + }, + "cm.module.ethernetClient.acs": { + "items": { + "$ref": "#/components/schemas/cm.module.ethernetClient.ac" + }, + "maxItems": 16, + "minItems": 0, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "acs" + } + }, + "cm.module.ethernetClient.attachmentCircuit.state": { + "description": "Definition of module ethernet client attachment circuit state parameters", + "properties": { + "attachmentCircuitAid": { + "$ref": "#/components/schemas/xr.ethernet.ac.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ethernet.ac.parentAid" + }, + "capacity": { + "$ref": "#/components/schemas/xr.ethernet.ac.capacity" + }, + "imc": { + "$ref": "#/components/schemas/xr.ethernet.ac.imc" + }, + "imcOuterVID": { + "$ref": "#/components/schemas/xr.ethernet.ac.imcOuterVID" + }, + "emc": { + "$ref": "#/components/schemas/xr.ethernet.ac.emc" + }, + "emcOuterVID": { + "$ref": "#/components/schemas/xr.ethernet.ac.emcOuterVID" + } + }, + "type": "object" + }, + "cm.module.localConnection": { + "description": "Definition of module localConnection object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.module.localConnection.state" + } + } + }, + "cm.module.localConnections": { + "items": { + "$ref": "#/components/schemas/cm.module.localConnection" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "localConnections" + } + }, + "cm.module.localConnection.state": { + "description": "Definition of module ethernetClient state parameters", + "properties": { + "lcAid": { + "$ref": "#/components/schemas/xr.lc.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.lc.parentAid" + }, + "direction": { + "$ref": "#/components/schemas/xr.lc.direction" + }, + "clientAid": { + "$ref": "#/components/schemas/xr.lc.clientAid" + }, + "dscgAid": { + "$ref": "#/components/schemas/xr.lc.dscgAid" + }, + "lineAid": { + "$ref": "#/components/schemas/xr.lc.lineAid" + }, + "remoteModuleId": { + "$ref": "#/components/schemas/xr.lc.remoteModuleId" + }, + "remoteClientId": { + "$ref": "#/components/schemas/xr.lc.remoteClientId" + } + } + }, + "errors": { + "properties": { + "errors": { + "description": "List of errors for a given request", + "items": { + "$ref": "#/components/schemas/cm.error" + }, + "type": "array" + } + }, + "type": "object" + }, + "cm.error": { + "description": "Error message.", + "minLength": 1, + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "title": "Error Message", + "type": "object" + }, + "cm.parameters.href": { + "description": "Resource HREF", + "title": "ResourceHREF", + "type": "string", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "href" + } + }, + "cm.parameters.rt": { + "description": "Resource Type or set of Resource Types", + "items": { + "maxLength": 64, + "type": "string" + }, + "minItems": 1, + "readOnly": true, + "title": "Resource Type", + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "rt" + } + }, + "cm.parameters.uuid": { + "description": "Object identifier", + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "title": "ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "id" + } + }, + "cm.parameters.labels": { + "additionalProperties": { + "maxLength": 64, + "minLength": 1, + "pattern": "^([A-Za-z0-9_\\-.,: ]*)$", + "type": "string" + }, + "description": "Assign key:value labels to objects", + "title": "Labels", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "labels" + } + }, + "xr.device.n": { + "description": "Friendly name of the device", + "maxLength": 64, + "readOnly": true, + "title": "Module name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleName" + } + }, + "xr.device.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleAid" + } + }, + "xr.configuration.configuredRole": { + "default": "auto", + "description": "Module role configured by user.\nPossible values:\n- auto: When role is automatically assigned by XR or by user via the Host interface\n- hub\n- leaf\n", + "enum": [ + "hub", + "leaf", + "auto" + ], + "title": "Configured Role", + "type": "string", + "x-enum-varnames": [ + "Hub", + "Leaf", + "Auto" + ], + "x-oapi-codegen-extra-tags": { + "bson": "configuredRole" + } + }, + "xr.configuration.currentRole": { + "default": "unknown", + "description": "Current module role\nPossible values:\n- unknown\n- hub\n- leaf\n", + "enum": [ + "hub", + "leaf", + "unknown" + ], + "readOnly": true, + "title": "Current Role", + "type": "string", + "x-enum-varnames": [ + "Hub", + "Leaf", + "Unknown" + ], + "x-oapi-codegen-extra-tags": { + "bson": "currentRole" + } + }, + "xr.configuration.roleStatus": { + "default": "scanning", + "description": "Transitional state when currentRole is unknown or user is changing currentRole to a new role.\nPossible values:\n- scanning\n- changeInProgress\n- ready\n", + "enum": [ + "scanning", + "changeInProgress", + "ready" + ], + "readOnly": true, + "title": "Role Status", + "type": "string", + "x-enum-varnames": [ + "Scanning", + "Change in progress", + "Ready" + ], + "x-oapi-codegen-extra-tags": { + "bson": "roleStatus" + } + }, + "xr.configuration.trafficMode": { + "default": "L1Mode", + "description": "Possible Values:\n- L1Mode: Allows transparent transport of client traffic between XR hub and leaf client ports\n- VTIMode: Allows transport of VLAN flows between an XR hub client port to 1 or more XR leaf client ports\n", + "enum": [ + "L1Mode", + "VTIMode" + ], + "title": "Traffic mode", + "type": "string", + "x-enum-varnames": [ + "L1 mode", + "VTI mode" + ], + "x-oapi-codegen-extra-tags": { + "bson": "trafficMode" + } + }, + "xr.configuration.serdesRate": { + "default": "25", + "description": "Rate of serdes lanes as configured by the Host device in Gbps", + "enum": [ + "undefined", + "25", + "50" + ], + "readOnly": true, + "title": "Serdes lane rate", + "type": "string", + "x-enum-varnames": [ + "Undefined", + "25", + "50" + ], + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "serdesRate" + } + }, + "xr.configuration.fiberConnectionMode": { + "description": "Possible Values:\n- single: only one fiber is connected for by-directional traffic\n- dual: separate fibers for transmit and receive\n", + "enum": [ + "single", + "dual" + ], + "title": "Fiber Mode", + "type": "string", + "x-enum-varnames": [ + "Single", + "Dual" + ], + "x-oapi-codegen-extra-tags": { + "bson": "fiberConnectionMode" + } + }, + "xr.configuration.tcMode": { + "default": true, + "description": "Enable/Disable IEEE 1588 Transparent Clock for VTI-mode.\n- true: Enabled\n- false: Disabled\n", + "title": "1588 Transparent Clock", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "tcMode" + } + }, + "xr.platform.pi": { + "description": "Unique UUID for the hardware platform calculated from the mac address", + "maxLength": 36, + "minLength": 36, + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "readOnly": true, + "title": "Platform UUID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "pi" + } + }, + "xr.platform.mnfv": { + "description": "Manufacturer's firmware version", + "maxLength": 64, + "readOnly": true, + "title": "Firmware version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnfv" + } + }, + "xr.platform.mnmn": { + "description": "Manufacturer name", + "maxLength": 64, + "readOnly": true, + "title": "Manufacturer", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnmn" + } + }, + "xr.platform.mnmo": { + "description": "Manufacturer's Model/Part number", + "maxLength": 64, + "readOnly": true, + "title": "Model number", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnmo" + } + }, + "xr.platform.mnhw": { + "description": "Platform Hardware Version", + "maxLength": 64, + "readOnly": true, + "title": "HW Version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnhw" + } + }, + "xr.platform.mndt": { + "description": "HW Manufacturing date", + "pattern": "([0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|2[0-9]|1[0-9]|0[1-9])", + "readOnly": true, + "title": "Manufacturing date", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mndt" + } + }, + "xr.platform.mnsel": { + "description": "Device Serial number", + "maxLength": 64, + "readOnly": true, + "title": "Serial number", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "serialNumber" + } + }, + "xr.platform.clei": { + "description": "Globally unique 10-character alphanumeric intelligent code identifying equipment in a structured naming format", + "readOnly": true, + "title": "CLEI Code", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clei" + } + }, + "xr.platform.macAddress": { + "description": "Device MAC Address", + "readOnly": true, + "title": "MAC address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "macAddress" + } + }, + "xr.platform.connectorType": { + "description": "Module connector type", + "enum": [ + "lcConnector" + ], + "readOnly": true, + "title": "Connector type", + "type": "string", + "x-enum-varnames": [ + "LC connector" + ], + "x-oapi-codegen-extra-tags": { + "bson": "connectorType" + } + }, + "xr.platform.formFactor": { + "description": "Module form factor", + "enum": [ + "cfp2-dco", + "qsfp-dd" + ], + "readOnly": true, + "title": "Form factor", + "type": "string", + "x-enum-varnames": [ + "CFP2-DCO", + "QSFP-DD" + ], + "x-oapi-codegen-extra-tags": { + "bson": "formFactor" + } + }, + "xr.device.piid": { + "description": "Protocol independent unique identifier for the Device that is immutable.", + "maxLength": 36, + "minLength": 36, + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "readOnly": true, + "title": "PIID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "piid" + } + }, + "xr.device.dmn": { + "properties": { + "language": { + "$ref": "#/components/schemas/xr.device.dmn.language" + }, + "value": { + "$ref": "#/components/schemas/xr.device.dmn.value" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "dmn" + } + }, + "xr.device.dmn.language": { + "description": "Format pattern according to IETF RFC 5646 (language tag).", + "pattern": "[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})", + "title": "Language", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "language" + } + }, + "xr.device.dmn.value": { + "description": "Vendor name", + "maxLength": 64, + "readOnly": true, + "title": "Vendor", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "value" + } + }, + "xr.device.sv": { + "description": "Software version.", + "maxLength": 64, + "readOnly": true, + "title": "Software version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "sv" + } + }, + "xr.device.icv": { + "description": "Device HW version.", + "maxLength": 64, + "readOnly": true, + "title": "Hardware version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "icv" + } + }, + "cm.parameters.parentId": { + "description": "Parent Object identifier", + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "title": "Parent ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "parentId" + } + }, + "xr.common.colId": { + "description": "Object identifier in the supporting collection.", + "readOnly": true, + "title": "Collection Id", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "colId" + } + }, + "xr.lineptp.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "linePtpAid" + } + }, + "xr.lineptp.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.lineptp.operStatus": { + "description": "Operational Status of line port.", + "enum": [ + "enabled", + "disabled" + ], + "readOnly": true, + "title": "Operational status", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "operStatus" + } + }, + "xr.controlplane.neighbor.macAddress": { + "description": "MAC address of the XR neighbor", + "readOnly": true, + "title": "MAC address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "macAddress" + } + }, + "xr.controlplane.neighbor.currentRole": { + "description": "Role of the XR neighbor", + "enum": [ + "hub", + "leaf", + "unknown" + ], + "readOnly": true, + "title": "Current role", + "type": "string", + "x-enum-varnames": [ + "Hub", + "Leaf", + "Unknown" + ], + "x-oapi-codegen-extra-tags": { + "bson": "currentRole" + } + }, + "xr.controlplane.neighbor.constellationFrequency": { + "description": "Carrier center frequency of the Hub module within the constellation.", + "readOnly": true, + "title": "Constellation frequency", + "type": "integer", + "x-unit": "MHz", + "x-oapi-codegen-extra-tags": { + "bson": "constellationFrequency" + } + }, + "xr.controlplane.neighbor.conState": { + "description": "Shows if the control plane towards this XR module is currently active or not", + "enum": [ + "active", + "inactive" + ], + "readOnly": true, + "title": "Connection Status", + "type": "string", + "x-enum-varnames": [ + "Active", + "Inactive" + ], + "x-oapi-codegen-extra-tags": { + "bson": "conState" + } + }, + "xr.controlplane.neighbor.lastConStateChange": { + "description": "Timestamp of last change in connectivity in date-time format pattern according to IETF RFC 3339.\nIf conState is inactive, this timestamp shows when connectivity was lost.\nIf conState is active this timestamp shows when connection was established.\n", + "format": "date-time", + "readOnly": true, + "title": "Update Time", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lastConStateChange" + } + }, + "xr.discovered.neighbor.macAddress": { + "description": "Device MAC address of the discovered XR neighbor", + "readOnly": true, + "title": "MAC address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "macAddress" + } + }, + "xr.discovered.neighbor.currentRole": { + "description": "Role of the discovered XR neighbor", + "enum": [ + "hub", + "leaf", + "unknown" + ], + "readOnly": true, + "title": "Current role", + "type": "string", + "x-enum-varnames": [ + "Hub", + "Leaf", + "Unknown" + ], + "x-oapi-codegen-extra-tags": { + "bson": "currentRole" + } + }, + "xr.discovered.neighbor.discoveredTime": { + "description": "Timestamp of latest discovered beacon message from this XR neighbor in date-time format pattern according to IETF RFC 3339.", + "format": "date-time", + "readOnly": true, + "title": "Discovery Time", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "discoveredTime" + } + }, + "xr.discovered.neighbor.constellationFrequency": { + "description": "Constellation frequency of the discovered XR neighbor. I.e. the frequency at which this neighbor was discovered.", + "readOnly": true, + "title": "Constellation Frequency", + "type": "integer", + "x-unit": "MHz", + "x-oapi-codegen-extra-tags": { + "bson": "constellationFrequency" + } + }, + "xr.carrier.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "carrierAid" + } + }, + "xr.carrier.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.lineptp.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.carrier.frequencyCtrl": { + "default": "xr", + "description": "Shows the ownership of the constellation frequency configuration.\nPossible Values:\n- xr: hubFrequency can also be configured by XR CM\n- host: host system where the module is inserted is the master of constellationFrequency configuration.\n", + "enum": [ + "xr", + "host" + ], + "readOnly": true, + "title": "Frequency control", + "type": "string", + "x-enum-varnames": [ + "XR", + "Host" + ], + "x-oapi-codegen-extra-tags": { + "bson": "frequencyCtrl" + } + }, + "xr.carrier.constellationFrequency": { + "description": "The center frequency in MHz of the Hub within the constellation. \nConfigurable on both Hub and Leaf modules when frequencyCtrl is \"xr\".\nPossible values:\n- Minimum: 191000000\n- Maximum: 196100000\nOr\n- Value '0': used for \"Undefined\"\n", + "readOnly": true, + "title": "Constellation Frequency", + "type": "integer", + "x-unit": "MHz", + "x-oapi-codegen-extra-tags": { + "bson": "constellationFrequency" + } + }, + "xr.carrier.operatingFrequency": { + "description": "Carrier center frequency.\nPossible values:\n- Minimum: 191000000\n- Maximum: 196100000\n Or\n- Value '0': used for \"Undefined\"\n", + "readOnly": true, + "title": "Operating frequency", + "type": "integer", + "x-unit": "MHz", + "x-oapi-codegen-extra-tags": { + "bson": "operatingFrequency" + } + }, + "xr.carrier.ncoFrequency": { + "description": "Nominal carrier central frequency overloaded in MHz. \nPossible values:\n- Minimum: 191000000\n- Maximum: 196100000\n Or\n- Value '0': used for \"Undefined\".\n", + "readOnly": true, + "title": "Nominal central frequency overloaded", + "type": "integer", + "x-unit": "MHz", + "x-oapi-codegen-extra-tags": { + "bson": "ncoFrequency" + } + }, + "xr.carrier.modulation": { + "default": "16QAM", + "description": "Constellation carrier signal modulation (applied to Hub and leaf modules).\nPossible values: '16QAM', 'QPSK' ' 8QAM'\n", + "enum": [ + "16QAM", + "QPSK", + "8QAM" + ], + "title": "Modulation", + "type": "string", + "x-enum-varnames": [ + "16QAM", + "QPSK", + "8QAM" + ], + "x-oapi-codegen-extra-tags": { + "bson": "modulation" + } + }, + "xr.carrier.capacity": { + "description": "Modulation and maximum digital subcarriers determine the capacity in Gbps.\nPossible values: [ 25,50,100,200,300,400 ]\n", + "enum": [ + 25, + 50, + 100, + 200, + 300, + 400 + ], + "readOnly": true, + "title": "Capacity", + "type": "integer", + "x-enum-varnames": [ + "25", + "50", + "100", + "200", + "300", + "400" + ], + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "capacity" + } + }, + "xr.carrier.clientPortMode": { + "default": "ethernet", + "description": "User can configure expected client port type", + "enum": [ + "ethernet", + "ethernetOtn" + ], + "title": "Client port mode", + "type": "string", + "x-enum-varnames": [ + "Ethernet", + "Ethernet or OTN" + ], + "x-oapi-codegen-extra-tags": { + "bson": "clientPortMode" + } + }, + "xr.carrier.baudRate": { + "description": "Baud rate in Giga-baud", + "readOnly": true, + "title": "Baud rate", + "type": "integer", + "x-unit": "GBd", + "x-oapi-codegen-extra-tags": { + "bson": "baudRate" + } + }, + "xr.carrier.maxAllowedDSCs": { + "description": "Number of digital subcarriers allowed to be used", + "enum": [ + 2, + 4, + 8, + 16 + ], + "readOnly": true, + "title": "Max number of digital subcarriers", + "type": "integer", + "x-enum-varnames": [ + "2", + "4", + "8", + "16" + ], + "x-oapi-codegen-extra-tags": { + "bson": "maxAllowedDSCs" + } + }, + "xr.carrier.txPowerTargetPerDsc": { + "default": -100, + "description": "Target power per DSC (applicable for all DSCs on the carrier) in dBm.\nPossible values:\n- Minimum: -35\n- Maximum: 0\n- Step: 0.1\n Or\n- Value '-100': used for \"Not configured\"\n", + "format": "double", + "maximum": 0, + "minimum": -100, + "multipleOf": 0.1, + "title": "Target power per DSC", + "type": "number", + "x-unit": "dBm", + "x-oapi-codegen-extra-tags": { + "bson": "txPowerTargetPerDsc" + } + }, + "xr.carrier.diagnostic.loopback": { + "default": "disabled", + "description": "Enable/Disable loopback", + "enum": [ + "disabled", + "terminal" + ], + "title": "Loopback", + "type": "string", + "x-enum-varnames": [ + "Disabled", + "Terminal" + ], + "x-oapi-codegen-extra-tags": { + "bson": "loopback" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dsc.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "dscAid" + } + }, + "xr.carrier.dsc.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.carrier.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.carrier.dsc.cDsc": { + "description": "Constellation/Hub DSC ID assigned to a Leaf module. \nIn case of a Hub module, it defaults to the DSC instance ID (e.g., 1 to 16 when Hub is a 400G module\n", + "title": "Constellation DSC", + "type": "integer" + }, + "xr.carrier.dsc.usability": { + "default": "usable", + "description": "Usability of this DSC. Configurable to control the allowed uses.\n * `usable` - DSC is usable for either PRBS or data.\n * `prbsOnly` - DSC is usable only for PRBS. This is done for optical power balancing reasons.\n * `reserved` - DSC is reserved and is not usable for either PRBS or data.\n", + "enum": [ + "usable", + "prbsOnly", + "reserved" + ], + "title": "Usability", + "type": "string", + "x-enum-varnames": [ + "Usable", + "PRBS only", + "Reserved" + ], + "x-oapi-codegen-extra-tags": { + "bson": "usability" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dsc.txEnabled": { + "default": false, + "description": "Configurable to enable/disable Tx transmission on this DSC. When disabled, this prevents any traffic from going out of the DSC.", + "title": "TX Enabled", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "txEnabled" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dsc.rxEnabled": { + "default": true, + "description": "Configurable to enable/disable the DSC to receive traffic.", + "title": "Rx Enabled", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "rxEnabled" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dsc.txStatus": { + "description": "Current DSC TX status.", + "enum": [ + "disabled", + "data", + "prbs" + ], + "readOnly": true, + "title": "TX status", + "type": "string", + "x-enum-varnames": [ + "Disabled", + "Data", + "PRBS" + ], + "x-oapi-codegen-extra-tags": { + "bson": "txStatus" + } + }, + "xr.carrier.dsc.rxStatus": { + "description": "Current DSC RX status.", + "enum": [ + "disabled", + "data", + "prbs" + ], + "readOnly": true, + "title": "RX status", + "type": "string", + "x-enum-varnames": [ + "Disabled", + "Data", + "PRBS" + ], + "x-oapi-codegen-extra-tags": { + "bson": "rxStatus" + } + }, + "xr.carrier.dsc.powerOffset": { + "default": 0, + "description": "Power offset relative to the average DSC power.", + "format": "double", + "maximum": 6, + "minimum": -6, + "multipleOf": 0.1, + "title": "Power offset", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "powerOffset" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dsc.diagnostic.facPRBSGenEnabled": { + "default": false, + "description": "Configurable to enable/disable facility PRBS test pattern generation", + "title": "Facility PRBS generation", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSGenEnabled" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dsc.diagnostic.facPRBSMonEnabled": { + "default": false, + "description": "Configurable to enable/disable facility PRBS test pattern monitoring", + "title": "Facility PRBS monitoring", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSMonEnabled" + }, + "x-trafficAffecting": true + }, + "xr.carrier.dscg.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "dscgAid" + } + }, + "xr.carrier.dscg.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.carrier.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.otu.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "otuAid" + } + }, + "xr.otu.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.carrier.dscg.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.otu.otuType": { + "description": "OTU Type", + "enum": [ + "OTUCni", + "OTUCn", + "OTUCni-M", + "OTU4" + ], + "readOnly": true, + "title": "OTU type", + "type": "string", + "x-enum-varnames": [ + "OTUCni", + "OTUCn", + "OTUCni-M", + "OTU4" + ], + "x-oapi-codegen-extra-tags": { + "bson": "otuType" + } + }, + "xr.otu.rate": { + "description": "Rate of the OTU.", + "enum": [ + 25, + 50, + 100, + 200, + 400 + ], + "readOnly": true, + "title": "Rate", + "type": "integer", + "x-enum-varnames": [ + "25", + "50", + "100", + "200", + "400" + ], + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "rate" + } + }, + "xr.otu.operStatus": { + "description": "Operational Status of OTU.", + "enum": [ + "enabled", + "disabled" + ], + "readOnly": true, + "title": "Operational status", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "operStatus" + } + }, + "xr.otu.txTTI": { + "default": "", + "description": "Up to 64 byte string for transmitting as TTI.", + "maxLength": 64, + "title": "Transmit TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "txTTI" + } + }, + "xr.otu.rxTTI": { + "description": "Up to 64 byte string of received TTI.", + "maxLength": 64, + "readOnly": true, + "title": "Received TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "rxTTI" + } + }, + "xr.otu.expectedTTI": { + "default": "", + "description": "Up to 64 byte string of TTI that is expected to be received.", + "maxLength": 64, + "title": "Expected TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "expectedTTI" + } + }, + "xr.otu.diagnostic.facPRBSGen": { + "default": "disabled", + "description": "Enable/Disable facility PRBS test pattern generation", + "enum": [ + "enabled", + "disabled" + ], + "title": "Facility PRBS generation", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSGen" + }, + "x-trafficAffecting": true + }, + "xr.otu.diagnostic.facPRBSMon": { + "default": "disabled", + "description": "Enable/Disable facility PRBS test pattern monitoring", + "enum": [ + "enabled", + "disabled" + ], + "title": "Facility PRBS monitoring", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSMon" + }, + "x-trafficAffecting": true + }, + "xr.otu.odu.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "oduAid" + } + }, + "xr.otu.odu.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.carrier.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.otu.odu.oduType": { + "description": "ODU type", + "enum": [ + "ODUCni", + "ODUflexi", + "ODUCni-M", + "ODU4i" + ], + "readOnly": true, + "title": "ODU type", + "type": "string", + "x-enum-varnames": [ + "ODUCni", + "ODUflexi", + "ODUCni-M", + "ODU4i" + ], + "x-oapi-codegen-extra-tags": { + "bson": "oduType" + } + }, + "xr.otu.odu.operStatus": { + "description": "Operational Status of ODU.", + "enum": [ + "enabled", + "disabled" + ], + "readOnly": true, + "title": "Operational status", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "operStatus" + } + }, + "xr.ethernet.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clientIfAid" + } + }, + "xr.ethernet.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.ethernet.portSpeed": { + "description": "Ethernet port speed in Gbps", + "enum": [ + 100, + 400, + 200, + 50, + 25 + ], + "readOnly": true, + "title": "Port speed", + "type": "integer", + "x-enum-varnames": [ + "100", + "400", + "200", + "50", + "25" + ], + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "clientIfPortSpeed" + } + }, + "xr.ethernet.fecType": { + "description": "Automatically set by the module based on SerDes and Port configuration.", + "enum": [ + "KR4", + "KP4" + ], + "readOnly": true, + "title": "Fec type", + "type": "string", + "x-enum-varnames": [ + "KR4", + "KP4" + ], + "x-oapi-codegen-extra-tags": { + "bson": "fecType" + } + }, + "xr.ethernet.fecMode": { + "default": "enabled", + "description": "Forward error correction mode of operation", + "enum": [ + "enabled", + "disabled" + ], + "title": "Forward error correction mode", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "fecMode" + }, + "x-trafficAffecting": true + }, + "xr.ethernet.diagnostic.loopbackType": { + "default": "loopbackAndContinue", + "description": "Loopback type.\n- 'loopbackAndContinue': Signal is looped back and is also forwarded downstream.\n- 'loopback': Signal is looped back and LF maintenance signal is sent downstream.\n", + "enum": [ + "loopbackAndContinue", + "loopback" + ], + "title": "Loopback type", + "type": "string", + "x-enum-varnames": [ + "Loopback and continue", + "Loopback" + ], + "x-oapi-codegen-extra-tags": { + "bson": "loopbackType" + } + }, + "xr.ethernet.diagnostic.loopbackMode": { + "default": "disabled", + "description": "Post-FEC Loopback mode for the ethernet client.", + "enum": [ + "disabled", + "facility", + "terminal" + ], + "title": "Loopback mode", + "type": "string", + "x-enum-varnames": [ + "Disabled", + "Facility", + "Terminal" + ], + "x-oapi-codegen-extra-tags": { + "bson": "loopbackMode" + }, + "x-trafficAffecting": true + }, + "xr.ethernet.lldpconfig.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lldpconfigAid" + } + }, + "xr.ethernet.lldpconfig.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.ethernet.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.ethernet.lldpconfig.adminStatus": { + "default": "disabled", + "description": "Administrative state to Enable/Disable LLDP in rxOnly mode.", + "enum": [ + "rxOnly", + "disabled" + ], + "title": "Administrative State", + "type": "string", + "x-enum-varnames": [ + "RX only", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "adminStatus" + } + }, + "xr.ethernet.lldpconfig.gccFwd": { + "default": false, + "description": "Enable/Disable forwarding of untagged LLDP frames over GCC.\n * `true` - Enabled.\n * `false` - Disabled.\n", + "title": "Forward GCC", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "gccFwd" + } + }, + "xr.ethernet.lldpconfig.hostRxDrop": { + "default": false, + "description": "Enable/Disable LLDP drop in Rx direction of Ethernet Client ports.\n * `true`: - Enabled.\n * `false`: - Disabled.\n", + "title": "LLDP drop", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "hostRxDrop" + } + }, + "xr.ethernet.lldpconfig.TTLUsage": { + "default": true, + "description": "Enable/Disable usage of TTL values for flushing/starting LLDP internal flush timer.\n * `true`: - Enabled.\n * `false`: - Disabled.\n", + "title": "TTL usage", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "TTLUsage" + } + }, + "xr.ethernet.lldpconfig.tooManyNeighbors": { + "description": "Indication that this LLDP Agent has too many discovered neighbors.", + "readOnly": true, + "title": "Too many neighbors", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "tooManyNeighbors" + } + }, + "xr.ethernet.lldpconfig.clrStats": { + "default": false, + "description": "Action to clear LLDP statistics.\nSet to true to trigger the action.\nServer resets it to false when action is completed.\n", + "title": "Clear LLDP statistics", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "clrStats" + } + }, + "xr.ethernet.lldpconfig.flushHostDb": { + "default": false, + "description": "Action to flush the learned host system information.\nSet to true to trigger the action.\nServer resets it to false when action is completed.\n", + "title": "Flush neighbor information", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "flushHostDb" + } + }, + "xr.ethernet.hostneighbors.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "hostneighborAid" + } + }, + "xr.ethernet.hostneighbors.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.ethernet.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.ethernet.neighbor.localPortSourceMAC": { + "description": "Neighbor MAC addres", + "readOnly": true, + "title": "MAC address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "portSourceMAC" + } + }, + "xr.ethernet.neighbor.chassisIdSubtype": { + "default": "macAddress", + "description": "Encoding of chassisId within LLDP data.", + "enum": [ + "reserved", + "chassisComponent", + "interfaceAlias", + "portComponent", + "macAddress", + "networkAddress", + "interfaceName", + "local" + ], + "readOnly": true, + "title": "LLDP Chassis ID encoding", + "type": "string", + "x-enum-varnames": [ + "Reserved", + "Chassis component", + "Interface alias", + "Port component", + "MAC address", + "Network address", + "Interface name", + "Locally assigned" + ], + "x-oapi-codegen-extra-tags": { + "bson": "chassisIdSubtype" + } + }, + "xr.ethernet.neighbor.chassisId": { + "description": "Host chassis ID within LLDP data.", + "readOnly": true, + "title": "LLDP Chassis ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "chassisId" + } + }, + "xr.ethernet.neighbor.portIdSubtype": { + "default": "macAddress", + "description": "Encoding of portId within LLDP data.", + "enum": [ + "interfaceAlias", + "portComponent", + "macAddress", + "networkAddress", + "interfaceName", + "agentCircuitId", + "local" + ], + "readOnly": true, + "title": "LLDP Port ID encoding", + "type": "string", + "x-enum-varnames": [ + "Interface alias", + "Port component", + "MAC address", + "Network address", + "Interface name", + "Agent circuit ID", + "Locally assigned" + ], + "x-oapi-codegen-extra-tags": { + "bson": "portIdSubtype" + } + }, + "xr.ethernet.neighbor.portId": { + "description": "Host port ID within LLDP data.", + "readOnly": true, + "title": "LLDP Port ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "portId" + } + }, + "xr.ethernet.neighbor.portDescr": { + "description": "Port Description of Neighbor within LLDP data.", + "readOnly": true, + "title": "LLDP Port description", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "portDescr" + } + }, + "xr.ethernet.neighbor.sysName": { + "description": "Host System Name within LLDP data.", + "readOnly": true, + "title": "LLDP System Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "sysName" + } + }, + "xr.ethernet.neighbor.sysDescr": { + "description": "Host System description within LLDP data.", + "readOnly": true, + "title": "LLDP System Description", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "sysDescr" + } + }, + "xr.ethernet.neighbor.sysTTL": { + "description": "LLDP TTL (time to live) of Neighbor, in seconds", + "readOnly": true, + "title": "Neighbor LLDP TTL", + "type": "integer", + "x-unit": "s", + "x-oapi-codegen-extra-tags": { + "bson": "sysTTL" + } + }, + "xr.ethernet.neighbor.lldpPDU": { + "description": "Complete LLDP PDU received from this Neighbor, to enable external analysis and extraction of additional TLVs.", + "readOnly": true, + "title": "LLDP PDU", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lldpPDU" + } + }, + "xr.ethernet.ac.aid": { + "description": "Attachment Circuit Access Identifier (AID) - unique instance within a xr.ethernet resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "attachmentCircuitAid" + } + }, + "xr.ethernet.ac.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.ethernet.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.ethernet.ac.capacity": { + "description": "Capacity of the attachment circuit expressed in multiples of 25Gbps.", + "maximum": 16, + "minimum": 1, + "title": "Rate", + "type": "integer", + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "capacity" + } + }, + "xr.ethernet.ac.imc": { + "description": "Ingress match criteria of the AC for traffic coming from the host", + "enum": [ + "matchAll", + "matchOuterVID", + "none" + ], + "title": "Ingress Match Criteria", + "type": "string", + "x-enum-varnames": [ + "Match all", + "Match outer VLAN Id", + "None" + ], + "x-oapi-codegen-extra-tags": { + "bson": "imc" + } + }, + "xr.ethernet.ac.imcOuterVID": { + "description": "String format listing of one or more individual VLAN IDs separated by \"&\" and/or ranges of VLAN IDs connected with \"&&\". For example \"10 & 20 & 50 && 100\" to represent the 52 VLAN IDs 10, 20 and 50-100.", + "pattern": "((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&\\& (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9]))* | ((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&)* | (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])", + "title": "Ingress Match Criteria VLAN IDs", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "imcOuterVID" + } + }, + "xr.ethernet.ac.emc": { + "description": "Egress match criteria of the AC for traffic going out to the host", + "enum": [ + "matchAll", + "matchOuterVID", + "none" + ], + "title": "Egress Match Criteria", + "type": "string", + "x-enum-varnames": [ + "Match all", + "Match outer VLAN Id", + "None" + ], + "x-oapi-codegen-extra-tags": { + "bson": "emc" + } + }, + "xr.ethernet.ac.emcOuterVID": { + "description": "String format listing of one or more individual VLAN IDs separated by \"&\" and/or ranges of VLAN IDs connected with \"&&\". For example \"10 & 20 & 50 && 100\" to represent the 52 VLAN IDs 10, 20 and 50-100.", + "pattern": "((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&\\& (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9]))* | ((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&)* | (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])", + "title": "Egress Match Criteria VLAN IDs", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "emcOuterVID" + } + }, + "xr.lc.aid": { + "description": "Access Identifier (AID) of a local connection", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lcAid" + } + }, + "xr.lc.parentAid": { + "items": { + "$ref": "#/components/schemas/xr.common.aid" + }, + "maxItems": 2, + "minItems": 2, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.common.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string" + }, + "xr.lc.direction": { + "default": "txRx", + "description": "Directionality of the local connection. \nPossible values:\n- 'txRx': Both Transmit (Client to Line) and Receive (Line to Client) direction \n- 'tx': Client to Line direction only. \n- 'rx': Line to Client direction only.\n", + "enum": [ + "txRx", + "tx", + "rx" + ], + "title": "Directionality of the LC.", + "type": "string", + "x-enum-varnames": [ + "Tx and RX", + "TX only", + "RX only" + ], + "x-oapi-codegen-extra-tags": { + "bson": "direction" + } + }, + "xr.lc.clientAid": { + "description": "Points to the AID of the connected client side resource of the LC. \nThis could be an ethernet resource or a specific attachment circuit on an ethernet resource.\n", + "title": "Client side AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clientAid" + } + }, + "xr.lc.dscgAid": { + "description": "Points to the AID of the DSCG which is used at the optical layer at the line side. This is entered as part of LC creation.", + "title": "DSCG AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "dscgAid" + } + }, + "xr.lc.lineAid": { + "description": "Points to the AID of the connected LO-ODU resource at the line side of the LC.", + "readOnly": true, + "title": "Line side AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lineAid" + } + }, + "xr.lc.remoteModuleId": { + "description": "Remote service endpoint module ID. Set by Host device as part of service creation.", + "readOnly": true, + "title": "Remote module ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "remoteModuleId" + } + }, + "xr.lc.remoteClientId": { + "description": "Remote service endpoint client resource AID. Set by Host device as part of service creation.", + "readOnly": true, + "title": "Remote module Client AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "remoteClientId" + } + }, + "cm.device": { + "description": "Device data definition for onboarding tool", + "example": { + "href": "/devices/02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "rt": [ + "cm.device" + ], + "id": "02dbd2b0-3baf-43f0-51c8-5da9498709e4", + "config": { + "status": "onboarded" + }, + "state": { + "moduleName": "XR LEAF 1", + "piid": "abb81108-8bbf-4222-9bf3-0a6bbb75ac65", + "dmn": { + "language": "en", + "value": "Infinera" + }, + "ownershipStatus": "owned", + "status": "onboarded", + "online": true + } + }, + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.device.config" + }, + "state": { + "$ref": "#/components/schemas/cm.device.state" + } + }, + "type": "object" + }, + "cm.device.config": { + "additionalProperties": false, + "description": "Configurable device parameters", + "properties": { + "status": { + "$ref": "#/components/schemas/cm.device.config.parameters.status" + } + }, + "type": "object" + }, + "cm.device.state": { + "description": "Definition of device state parameters", + "properties": { + "moduleName": { + "$ref": "#/components/schemas/xr.device.n" + }, + "piid": { + "$ref": "#/components/schemas/xr.device.piid" + }, + "dmn": { + "$ref": "#/components/schemas/xr.device.dmn" + }, + "ownership": { + "$ref": "#/components/schemas/cm.device.parameters.ownershipStatus" + }, + "status": { + "$ref": "#/components/schemas/cm.device.state.parameters.status" + }, + "online": { + "$ref": "#/components/schemas/cm.device.parameters.online" + } + }, + "type": "object" + }, + "cm.device.parameters.ownershipStatus": { + "description": "Device ownership status\nPossible values:\n- 'readytobeowned': The device is discovered and ready to be owned\n- 'owned': Device is owned by this onboard tool user\n- 'ownedbyother': Device is owned by another user\n- 'unknown': Device is unsecure or status cannot be obtained\n", + "enum": [ + "readytobeowned", + "owned", + "ownedbyother", + "unknown" + ], + "readOnly": true, + "title": "Status", + "type": "string", + "x-enum-varnames": [ + "Ready to be owned", + "Owned", + "Owned by other", + "Unknown" + ] + }, + "cm.device.parameters.online": { + "description": "Indicates if device is currently reachable", + "readOnly": true, + "title": "Online", + "type": "boolean" + }, + "cm.device.config.parameters.status": { + "description": "Device onboard status configuration", + "enum": [ + "onboarded", + "offboarded" + ], + "title": "Status", + "type": "string", + "x-enum-varnames": [ + "Onboarded", + "Offboarded" + ] + }, + "cm.device.state.parameters.status": { + "description": "Device onboard status state", + "enum": [ + "discovered", + "onboardPending", + "onboarded", + "onboardFailed", + "offboardPending", + "offboardFailed", + "offboarded" + ], + "readOnly": true, + "title": "Status", + "type": "string", + "x-enum-varnames": [ + "Discovered", + "Onboard pending", + "Onboarded", + "Onboard failed", + "Offboard pending", + "Offboard failed", + "Offboarded" + ] + }, + "cm.device.updateRequest": { + "additionalProperties": false, + "description": "Object used in the request body of PUT requests in /devices endpoint.\nContains the device identifier and its onboard status.\n", + "properties": { + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.device.update" + } + }, + "required": [ + "config", + "id" + ], + "type": "object" + }, + "cm.device.update": { + "additionalProperties": false, + "description": "Configurable device parameters", + "minProperties": 1, + "properties": { + "status": { + "$ref": "#/components/schemas/cm.device.config.parameters.status" + } + }, + "type": "object" + }, + "cm.sw.action": { + "description": "Definition of CM software action requests", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.sw.action.config" + }, + "state": { + "$ref": "#/components/schemas/cm.sw.action.state" + }, + "moduleActions": { + "$ref": "#/components/schemas/cm.sw.moduleActions" + } + } + }, + "cm.sw.action.config": { + "additionalProperties": false, + "description": "Definition of software action configuration parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "selectors": { + "$ref": "#/components/schemas/cm.sw.action.config.selectors" + }, + "operations": { + "$ref": "#/components/schemas/cm.sw.action.config.operations" + } + }, + "type": "object" + }, + "cm.sw.action.config.selectors": { + "description": "List of software action target modules.\nModules can be specified individually (via module ID), per constellation, per NDU or per host.\n", + "items": { + "$ref": "#/components/schemas/cm.sw.action.config.selector" + }, + "minItems": 1, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "selectors" + } + }, + "cm.sw.action.config.selector": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "moduleIds": { + "$ref": "#/components/schemas/cm.sw.action.config.selector.moduleIds" + }, + "nduIds": { + "$ref": "#/components/schemas/cm.sw.action.config.selector.nduIds" + } + }, + "type": "object" + }, + "cm.sw.action.config.selector.moduleIds": { + "items": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "minItems": 1, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIds" + } + }, + "cm.sw.action.config.selector.nduIds": { + "items": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "minItems": 1, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "nduIds" + } + }, + "cm.sw.action.config.operations": { + "description": "List of software actions to be executed on target modules.\nPossible values:\n- 'clearBank' \n- 'validateUrl'\n- 'download'\n- 'prepareUpgrade'\n- 'commit'\n- 'abort' \nIf multiple modules are target, action is executed in parallel for different modules.\nIf multiple operations are defined, they are executed per module with the following priority:\n- 1: 'abort'\n- 2: 'activate' with 'rollback' option\n- 3: 'clearBank'\n- 4: 'validateUrl'\n- 5: 'download'\n- 6: 'prepareUpgrade'\n- 8: 'activate' with 'apply' option\nIf an operation fails , remaining module operations are aborted.\nIf an 'abort' operation is executed, remaining operations for that module are aborted.\nIf an 'activate' with 'rollback' option is executed, remaining operations for that module are aborted.\n", + "items": { + "$ref": "#/components/schemas/cm.sw.action.config.operation" + }, + "minItems": 1, + "title": "Actions", + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "operations" + } + }, + "cm.sw.action.config.operation": { + "additionalProperties": false, + "maxProperties": 1, + "minProperties": 1, + "properties": { + "clearBank": { + "$ref": "#/components/schemas/cm.sw.action.config.operation.clearBank" + }, + "validateUrl": { + "$ref": "#/components/schemas/cm.sw.action.config.operation.validateUrl" + }, + "download": { + "$ref": "#/components/schemas/cm.sw.action.config.operation.download" + }, + "prepareUpgrade": { + "$ref": "#/components/schemas/cm.sw.action.config.operation.prepareUpgrade" + }, + "activate": { + "$ref": "#/components/schemas/cm.sw.action.config.operation.activate" + }, + "abort": { + "$ref": "#/components/schemas/cm.sw.action.config.operation.abort" + } + }, + "type": "object" + }, + "cm.sw.action.config.operation.clearBank": { + "description": "Operation to delete the software image and associated configuration from the inactive bank.", + "enum": [ + true + ], + "title": "clear", + "type": "boolean", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "clearBank" + } + }, + "cm.sw.action.config.operation.validateUrl": { + "additionalProperties": false, + "description": "Operation to validate that the software image file is available at specified location.", + "minProperties": 1, + "properties": { + "swURL": { + "$ref": "#/components/schemas/cm.sw.action.parameters.swURL" + } + }, + "title": "validate", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "validateUrl" + } + }, + "cm.sw.action.config.operation.download": { + "additionalProperties": false, + "description": "Operation to executes the download of the software image to the upgrade bank.", + "minProperties": 1, + "properties": { + "swURL": { + "$ref": "#/components/schemas/cm.sw.action.parameters.swURL" + } + }, + "title": "download", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "download" + } + }, + "cm.sw.action.config.operation.prepareUpgrade": { + "description": "Operation to classify the upgrade impact (i.e., the impact of executing the software in the upgrade bank).\nResult is available on upgradeClassification property of the respective module swCtrl object.\n", + "enum": [ + true + ], + "title": "clear", + "type": "boolean", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "prepareUpgrade" + } + }, + "cm.sw.action.config.operation.activate": { + "additionalProperties": false, + "description": "Operation to execute software image and commit it upon successful module restart.\nIf executed with 'apply' option, execution is done over the upgrade bank image\n(note that after commit, the former upgrade bank becomes active bank and the former active bank becomes previous bank).\nIf executed with 'rollback' option, execution is done over the previous active bank image\n(note that no commit is executed after module restart)\n", + "minProperties": 1, + "properties": { + "option": { + "$ref": "#/components/schemas/cm.sw.action.parameters.activateOptions" + } + }, + "title": "clear", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "activate" + } + }, + "cm.sw.action.config.operation.abort": { + "description": "Operation to abort module current action (if any) and clear pending operations.", + "enum": [ + true + ], + "title": "Abort", + "type": "boolean", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "abort" + } + }, + "cm.sw.action.state": { + "description": "Definition of module state object", + "properties": { + "lifecycleState": { + "$ref": "#/components/schemas/cm.sw.action.state.parameters.lifecycleState" + } + } + }, + "cm.sw.action.parameters.swURL": { + "description": "Source of software package for download to upgrade bank.", + "format": "uri", + "maxLength": 255, + "title": "Software URL", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "swURL" + } + }, + "cm.sw.action.parameters.activateOptions": { + "description": "Activate operation options.\nPossible values:\n- 'apply': Activation is done over the upgrade bank image and is committed upon successful module restart.\n- 'rollback': Activation is done over the previous active bank image and no commit is issue upon module restart.\n", + "enum": [ + "apply", + "rollback" + ], + "title": "Activate option", + "type": "string", + "x-enum-varnames": [ + "Apply", + "Rollback" + ], + "x-oapi-codegen-extra-tags": { + "bson": "option" + } + }, + "cm.sw.action.state.parameters.lifecycleState": { + "description": "Provides the aggregated status of a software module action.\nPossible values:\n- 'pending': This state occurs when all module operations related to this request are not yet created or in pending state.\n- 'executing': This state occurs when all module operations related to this request are currently under execution.\n- 'partiallyExecuted': This state may occur when at least one module operation related to this request is in executed state.\n- 'executed': This state occurs when all module operations related to this request are in executed state.\n- 'partiallyFailed': This state may occur when at least one module operation related to this request is in failed state.\n- 'failed': This state occurs when all module operations related to this request are in failed state.\n- 'deleted': This state occurs when an action is removed.\n", + "enum": [ + "pending", + "executing", + "partiallyExecuted", + "executed", + "partiallyFailed", + "failed", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending", + "Executing", + "Partially executed", + "Executed", + "Partially failed", + "Failed", + "Deleted" + ] + }, + "cm.sw.action.create": { + "additionalProperties": false, + "description": "Software action creation parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "selectors": { + "$ref": "#/components/schemas/cm.sw.action.config.selectors" + }, + "operations": { + "$ref": "#/components/schemas/cm.sw.action.config.operations" + } + }, + "required": [ + "operations", + "selectors" + ], + "type": "object" + }, + "cm.sw.moduleAction": { + "description": "Definition of CM operations resulting from a software action request", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "state": { + "$ref": "#/components/schemas/cm.sw.moduleAction.state" + } + }, + "title": "Operations" + }, + "cm.sw.moduleActions": { + "items": { + "$ref": "#/components/schemas/cm.sw.moduleAction" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "moduleActions" + } + }, + "cm.sw.moduleAction.state": { + "description": "Definition of moduleAction state object", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/xr.device.di" + }, + "action": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action" + }, + "actionDate": { + "$ref": "#/components/schemas/cm.sw.moduleAction.parameters.actionDate" + }, + "actionSource": { + "$ref": "#/components/schemas/cm.sw.moduleAction.parameters.actionSource" + }, + "moduleSwmStatus": { + "$ref": "#/components/schemas/cm.sw.moduleAction.parameters.moduleSwmStatus" + }, + "actionResult": { + "$ref": "#/components/schemas/cm.sw.moduleAction.state.actionResult" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.sw.moduleAction.parameters.lifecycleState" + } + } + }, + "cm.sw.moduleAction.action": { + "description": "Definition of module software operations", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "wipeoutBank": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.wipeoutBank" + }, + "validateSwUrl": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.validateSwUrl" + }, + "download": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.download" + }, + "classifyUpgradeImpact": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.classifyUpgradeImpact" + }, + "execute": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.execute" + }, + "commit": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.commit" + }, + "abort": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.abort" + }, + "rollback": { + "$ref": "#/components/schemas/cm.sw.moduleAction.action.rollback" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "action" + } + }, + "cm.sw.moduleAction.action.wipeoutBank": { + "additionalProperties": false, + "description": "Action to delete the SW and associated configuration in this Bank. Set to true to trigger the action..\nUpon completion, the module cm.sw.moduleAction.actionResult 'result' parameter is updated.\n", + "enum": [ + true + ], + "type": "object", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "wipeoutBank" + } + }, + "cm.sw.moduleAction.action.validateSwUrl": { + "additionalProperties": false, + "description": "Action to validate software image location.\nUpon completion, the module cm.swCtrl.state.actionResult 'moduleClassification' and 'result' parameters is updated.\n", + "properties": { + "source": { + "$ref": "#/components/schemas/cm.sw.moduleAction.parameters.source" + } + }, + "required": [ + "source" + ], + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "validateSwUrl" + } + }, + "cm.sw.moduleAction.action.download": { + "additionalProperties": false, + "description": "Action to download software image to upgrade bank.\nUpon execution, the module cm.swCtrl.config.swURL parameter is updated to the source URL and an URL validation is executed. \nDuring execution, the module cm.swCtrl.state.status parameter is updated to [1] 'Downloading'.\nDuring execution, the module cm.swCtrl.state.downloadProgress parameter is updated to reflect the download process.\nUpon completion, the module cm.sw.moduleAction.actionResult 'moduleClassification' and 'result' parameters are updated.\n", + "properties": { + "source": { + "$ref": "#/components/schemas/cm.sw.moduleAction.parameters.source" + } + }, + "required": [ + "source" + ], + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "download" + } + }, + "cm.sw.moduleAction.action.classifyUpgradeImpact": { + "additionalProperties": false, + "description": "Action to validate the software image in upgrade bank.\nUpon completion, the module cm.sw.moduleAction.actionResult 'upgradeClassification' and 'result' parameters are updated.\n", + "enum": [ + true + ], + "type": "object", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "classifyUpgradeImpact" + } + }, + "cm.sw.moduleAction.action.execute": { + "additionalProperties": false, + "description": "Action to execute software in upgradeBank.\nUpon completion, the module cm.sw.moduleAction.actionResult 'result' parameter is updated.\n", + "enum": [ + true + ], + "type": "object", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "executeSwImage" + } + }, + "cm.sw.moduleAction.action.commit": { + "additionalProperties": false, + "description": "Action to commit software in upgradeBank. \nAfter restart, previous active bank becomes inactive and previous bank, the upgrade bank becomes active bank.\nUpon completion, the module cm.sw.moduleAction.actionResult 'result' parameter is updated.\n", + "enum": [ + true + ], + "type": "object", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "commitSwImage" + } + }, + "cm.sw.moduleAction.action.abort": { + "additionalProperties": false, + "description": "Action to abort current upgrade process. \nUpon completion, the module cm.sw.moduleAction.actionResult 'result' parameter is updated.\n", + "enum": [ + true + ], + "type": "object", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "abortSwUpgrade" + } + }, + "cm.sw.moduleAction.action.rollback": { + "additionalProperties": false, + "description": "Action to fall back to previous running bank. \nUpon completion, the module cm.sw.moduleAction.actionResult 'result' parameter is updated.\n", + "enum": [ + true + ], + "type": "object", + "x-enum-varnames": [ + "True" + ], + "x-oapi-codegen-extra-tags": { + "bson": "rollback" + } + }, + "cm.sw.moduleAction.state.actionResult": { + "description": "Action' result as reported by module.\n'downloadProgress' property is only applicable to 'download' action\n'upgradeClassification' property is only applicable to 'classifyUpgradeImpact' action\n", + "properties": { + "downloadProgress": { + "$ref": "#/components/schemas/cm.sw.moduleAction.actionResult.parameters.downloadProgress" + }, + "moduleClassification": { + "$ref": "#/components/schemas/cm.sw.moduleAction.actionResult.parameters.moduleClassification" + }, + "upgradeClassification": { + "$ref": "#/components/schemas/cm.sw.moduleAction.actionResult.parameters.upgradeClassification" + }, + "result": { + "$ref": "#/components/schemas/cm.sw.moduleAction.actionResult.parameters.result" + } + }, + "readOnly": true, + "title": "Action result", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "actionResult" + } + }, + "cm.sw.moduleAction.parameters.source": { + "description": "Software image URL", + "title": "Source", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "source" + } + }, + "cm.sw.moduleAction.parameters.actionDate": { + "description": "Timestamp in date-time format pattern according to IETF RFC 3339.", + "format": "date-time", + "readOnly": true, + "title": "Action Date", + "type": "string" + }, + "cm.sw.moduleAction.parameters.actionSource": { + "description": "Defines the source of the module action request.\nPossible values:\n- '0': NA\n- '1': CM\n- '2': Host\n", + "enum": [ + 0, + 1, + 2 + ], + "readOnly": true, + "title": "Action Source", + "type": "integer", + "x-enum-varnames": [ + "Not applicable", + "IPM", + "Host" + ] + }, + "cm.sw.moduleAction.parameters.moduleSwmStatus": { + "description": "State of ongoing download or upgrade procedure. \nWhen no upgrade procedure is in progress the status is Idle.\nPossible values:\n- '0': Idle\n- '1': Downloading\n- '2': Executing\n- '3': Restarting\n- '4': runningNotCommitted\n- '5': Committing\n- '6': Reverting\n- '7': Falling Back\n", + "readOnly": true, + "title": "Status", + "type": "integer" + }, + "cm.sw.moduleAction.actionResult.parameters.downloadProgress": { + "description": "Percentage of SW package download, 0-100, when download is in progress.\n", + "readOnly": true, + "title": "Download progress", + "type": "integer" + }, + "cm.sw.moduleAction.actionResult.parameters.moduleClassification": { + "description": "Classification of the module so a client can identify which XR Deliverable Packages are suitable for it.", + "maxLength": 40, + "readOnly": true, + "title": "Module classification", + "type": "string" + }, + "cm.sw.moduleAction.actionResult.parameters.upgradeClassification": { + "description": "Classification of upgrade impact of executing the software in upgradeBank. \nResult of swm Action to classify upgrade impact.\nPossible values:\n- '0': Upgrade not classified yet\n- '1': Upgrade classification failed\n- '2': Configuration cannot be migrated\n- '3': Service affecting upgrade\n- '4': Non-service affecting upgrade\n", + "readOnly": true, + "title": "Upgrade classification", + "type": "integer" + }, + "cm.sw.moduleAction.actionResult.parameters.result": { + "description": "Result of the last completed swm Action.\nEither successfully or reason for failure.\nResult is Unknown during the execution of an action.\nPossible value:\n- '0': Unknown\n- '1': Success\n- '2': Fail -Invalid or unreachable software URL\n- '3': Fail -Not Enough RAM\n- '4': Fail -Not Enough Flash\n- '5': Fail -Connection Lost\n- '6': Fail -SW validation failure\n- '7': Wrong SW For Module\n- '8': Validating\n- '9': Downloading\n- '10': Upgrade Classificating\n- '21': Activate Fail - Connection Lost\n- '22': Activate Fail - SW execute failure\n- '23': Activate Fail - Commit failure\n- '24': Executing software in upgradeBank\n- '25': Committing software in upgradeBank\n- '25': Falling back - Execute software in previous Bank\n- '30': Aborting\n", + "readOnly": true, + "title": "Action Result", + "type": "integer" + }, + "cm.sw.moduleAction.parameters.lifecycleState": { + "description": "Provides the status of a software module action.\nPossible values:\n- 'pending': This state occurs when the module configuration was not yet sent to the module.\n- 'executing': This state occurs when the module configuration was sent to the module and is currently under execution.\n- 'executed': This state occurs when the module configuration was already executed and reported finished.\n- 'failed': This state occurs when the module configuration was rejected by the module.\n- 'deleted': This state occurs when a moduleAction is removed.\n", + "enum": [ + "pending", + "executing", + "executed", + "failed", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending", + "Executing", + "Executed", + "Failed", + "Deleted" + ] + }, + "cm.sw.ctrl": { + "description": "Definition of CM module/ndu software control object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "state": { + "$ref": "#/components/schemas/cm.sw.ctrl.state" + }, + "swBanks": { + "$ref": "#/components/schemas/cm.sw.banks" + } + } + }, + "cm.sw.ctrl.state": { + "description": "Definition of module/ndu software bank state parameters", + "properties": { + "deviceType": { + "$ref": "#/components/schemas/cm.parameters.deviceType" + }, + "deviceId": { + "$ref": "#/components/schemas/cm.parameters.deviceId" + }, + "deviceName": { + "$ref": "#/components/schemas/xr.device.n" + }, + "deviceLabels": { + "$ref": "#/components/schemas/cm.parameters.labels" + }, + "activeBank": { + "$ref": "#/components/schemas/xr.swmctrl.activeBank" + }, + "committedBank": { + "$ref": "#/components/schemas/xr.swmctrl.committedBank" + }, + "previousActiveBank": { + "$ref": "#/components/schemas/xr.swmctrl.previousActiveBank" + }, + "status": { + "$ref": "#/components/schemas/xr.swmctrl.swmStatus" + }, + "latestAction": { + "$ref": "#/components/schemas/cm.sw.ctrl.state.latestAction" + }, + "latestStatusChangedTime": { + "$ref": "#/components/schemas/xr.swmctrl.latestStatusChangedTime" + } + } + }, + "cm.sw.ctrl.state.latestAction": { + "description": "Module latest action parameters", + "properties": { + "timestamp": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMActionDateTime" + }, + "action": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMAction" + }, + "source": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMActionSource" + }, + "bank": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMActionUpgradeBank" + }, + "swUrl": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMActionSWURL" + }, + "revertTimeout": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMActionRevertTimeout" + }, + "downloadProgress": { + "$ref": "#/components/schemas/xr.swmctrl.recentDownloadProgress" + }, + "upgradeClassification": { + "$ref": "#/components/schemas/xr.swmctrl.recentUpgradeClassification" + }, + "result": { + "$ref": "#/components/schemas/xr.swmctrl.recentSWMActionResult" + } + } + }, + "cm.sw.bank": { + "description": "Definition of xr-network object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.sw.bank.state" + } + } + }, + "cm.sw.banks": { + "items": { + "$ref": "#/components/schemas/cm.sw.bank" + }, + "maxItems": 2, + "minItems": 2, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "swBanks" + } + }, + "cm.sw.bank.state": { + "description": "Definition of module software bank state parameters", + "properties": { + "version": { + "$ref": "#/components/schemas/xr.swmbank.version" + }, + "bankStatus": { + "$ref": "#/components/schemas/cm.sw.bank.state.bankStatus" + }, + "imageStatus": { + "$ref": "#/components/schemas/cm.sw.bank.state.imageStatus" + }, + "configCompVersion": { + "$ref": "#/components/schemas/xr.swmbank.configCompVersion" + }, + "configDataSentry": { + "$ref": "#/components/schemas/xr.swmbank.configDataSentry" + }, + "imageActivationHistory": { + "$ref": "#/components/schemas/cm.sw.bank.state.imageActivationHistory" + }, + "imageConfiguration": { + "$ref": "#/components/schemas/cm.sw.bank.state.imageConfiguration" + }, + "action": { + "$ref": "#/components/schemas/xr.swmbank.action" + } + } + }, + "cm.sw.bank.state.bankStatus": { + "description": "Indicates the software bank status\nPossible values:\n- 'empty': Software bank image is empty\n- 'installing': Software image is under installation\n- 'installed': Software image is installed in the bank\n- 'invalid': Signature of the software in this bank is invalid\n", + "enum": [ + "empty", + "installing", + "installed", + "invalid" + ], + "readOnly": true, + "title": "Bank status", + "type": "string", + "x-enum-varnames": [ + "Empty", + "Installing", + "Installed", + "Invalid" + ] + }, + "cm.sw.bank.state.imageStatus": { + "description": "Indicates the software image status in the bank\nPossible values:\n- 'notApplicable': Bank is empty\n- 'inactive': Software image is currently\n- 'running':\n- 'runningNotCommitted'\n", + "enum": [ + "notApplicable", + "inactive", + "running", + "runningNotCommitted" + ], + "readOnly": true, + "title": "Image status", + "type": "string", + "x-enum-varnames": [ + "Not applicable", + "Inactive", + "Running", + "Running not committed" + ] + }, + "cm.sw.bank.state.imageActivationHistory": { + "description": "Indicates the software image status in the bank\nPossible values:\n- 'notApplicable': Software image in the bank was never activated\n- 'failed': Software image latest activation failed\n- 'succeed': Software image latest activation succeed\n", + "enum": [ + "notApplicable", + "failed", + "succeed" + ], + "readOnly": true, + "title": "Image status", + "type": "string", + "x-enum-varnames": [ + "Not applicable", + "Failed", + "Succeed" + ] + }, + "cm.sw.bank.state.imageConfiguration": { + "description": "Indicates the software image status in the bank\nPossible values:\n- 'notApplicable': Software image is invalid or not present.\n- 'none': Software in this bank has no associated config data.\n- 'upgradeNotClassified': Software in this bank has associated config data but upgrade classification was not executed.\n- 'upgradeClassificationFailed': Software upgrade classification failed.\n- 'invalidUpgradeConfiguration': Software configuration cannot be migrated.\n- 'validUpgradeServiceAffecting': Software configuration is valid and upgrade is service affecting.\n- 'validUpgradeNonServiceAffecting': Software configuration is valid and upgrade is non-service affecting.\n- 'validRunning': Software configuration is valid and applied.\n", + "enum": [ + "notApplicable", + "none", + "upgradeNotClassified", + "upgradeClassificationFailed", + "invalidUpgradeConfiguration", + "validUpgradeServiceAffecting", + "validUpgradeNonServiceAffecting", + "validRunning" + ], + "readOnly": true, + "title": "Image status", + "type": "string", + "x-enum-varnames": [ + "Not applicable", + "None", + "Upgrade not classified", + "Upgrade classification failed", + "Invalid upgrade configuration", + "Valid upgrade service affecting", + "Valid upgrade non service affecting", + "Valid running" + ] + }, + "cm.resource": { + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + } + }, + "type": "object" + }, + "cm.parameters.name": { + "description": "User defined object name.\n", + "maxLength": 64, + "pattern": "^([A-Za-z0-9_\\-.,: ]*)$", + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "xr.device.di": { + "description": "Device identifier.", + "readOnly": true, + "title": "Device identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleId" + } + }, + "cm.parameters.deviceType": { + "description": "Device type\nPossible values:\n- 'ndu'\n- 'moduleHub'\n- 'moduleLeaf'\n- 'moduleUnknown\n", + "enum": [ + "ndu", + "moduleHub", + "moduleLeaf", + "moduleUnknown" + ], + "readOnly": true, + "type": "string", + "x-enum-varnames": [ + "NDU", + "Hub", + "Leaf", + "Unknown" + ], + "x-oapi-codegen-extra-tags": { + "bson": "deviceType" + } + }, + "cm.parameters.deviceId": { + "description": "Object identifier", + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "title": "ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "deviceId" + } + }, + "xr.swmctrl.activeBank": { + "description": "Bank ID of currently active running SW.", + "readOnly": true, + "title": "Running SW bank", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "activeBank" + } + }, + "xr.swmctrl.committedBank": { + "description": "Bank ID of currently committed SW. \n0 = NoValue, 1 = A, 2 = B. \nThis will be the Bank to be used at startup.\n", + "readOnly": true, + "title": "Module Classification", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "committedBank" + } + }, + "xr.swmctrl.previousActiveBank": { + "description": "Bank ID of the previously Active Bank before the currently running SW. 0 is used for N/A.", + "readOnly": true, + "title": "Previous SW bank", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "previousActiveBank" + } + }, + "xr.swmctrl.swmStatus": { + "description": "State of ongoing download or upgrade procedure.\nWhen no upgrade procedure is in progress the status is Idle.\n- '0': Idle\n- '1': Downloading\n- '2': Executing\n- '3': Restarting\n- '4': runningNotCommitted\n- '5': Committing\n- '6': Reverting\n- '7': Falling Back\n", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "readOnly": true, + "type": "integer", + "x-enum-varnames": [ + "Idle", + "Downloading", + "Executing", + "Restarting", + "runningNotCommitted", + "Committing", + "Reverting", + "Falling Back" + ], + "x-oapi-codegen-extra-tags": { + "bson": "status" + } + }, + "xr.swmctrl.latestStatusChangedTime": { + "description": "Timestamp of last sw change in date-time format pattern according to IETF RFC 3339.\nEmpty if there is no image in the bank.\n", + "format": "date-time", + "readOnly": true, + "title": "Request Date", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "latestChangedDate" + } + }, + "xr.swmctrl.recentSWMActionDateTime": { + "format": "date-time", + "readOnly": true, + "title": "Action Date Time", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "timestamp" + } + }, + "xr.swmctrl.recentSWMAction": { + "default": 0, + "description": "Software Management Action. \nSet to a non-zero value to trigger the different SWM actions.\n- '0': No Action\n- '1': Validate swURL\n- '2': Start software download to upgradeBank\n- '3': Classify upgrade impact. I.e. the impact of executing the software in upgradeBank. Result is seen on upgradeClassification property.\n- '4': Execute software in upgradeBank\n- '5': Commit software in runningBank\n- '6': Execute software in previousBank (Fallback)\n- '7': Abort\n", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "readOnly": true, + "title": "SWM Action", + "type": "integer", + "x-enum-varnames": [ + "No Action", + "Validate swURL", + "Start software download to upgradeBank", + "Classify upgrade impact.", + "Execute software in upgradeBank", + "Commit software in runningBank", + "Execute software in previousBank (Fallback)", + "Abort" + ], + "x-oapi-codegen-extra-tags": { + "bson": "action" + } + }, + "xr.swmctrl.recentSWMActionSource": { + "description": "- 0: NA \n- 1: CM \n- 2: Host\n", + "enum": [ + 0, + 1, + 2 + ], + "readOnly": true, + "type": "integer", + "x-enum-varnames": [ + "Not applicable", + "CM", + "Host" + ], + "x-oapi-codegen-extra-tags": { + "bson": "source" + } + }, + "xr.swmctrl.recentSWMActionUpgradeBank": { + "default": 0, + "description": "Bank ID used for swm Actions. \nInactive bank ID is used if not set.\n", + "maximum": 2, + "minimum": 0, + "readOnly": true, + "title": "Upgrade SW bank", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "bank" + } + }, + "xr.swmctrl.recentSWMActionSWURL": { + "default": "", + "description": "Source of software package for download to upgradebank. \nSet to empty if it is not applicable for the recent SWM cction.\n", + "format": "uri", + "maxLength": 255, + "readOnly": true, + "title": "SW URL", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "swUrl" + } + }, + "xr.swmctrl.recentSWMActionRevertTimeout": { + "default": 120, + "description": "Seconds until automatic revert to previousBank after executing new SW, unless the new SW is committed. 0 used for no revert. Set to empty if it is not applicable for the recent SWM action.", + "readOnly": true, + "title": "Revert timeout", + "type": "integer", + "x-unit": "s", + "x-oapi-codegen-extra-tags": { + "bson": "revertTimeout" + } + }, + "xr.swmctrl.recentDownloadProgress": { + "description": "Percentage of SW package download, 0-100, when download is in progress. \n255 is used for \"N/A\" when no download is in progress. \nSet to empty if it is not applicable for the recent SWM action.\n", + "readOnly": true, + "title": "Download progress", + "type": "integer", + "x-unit": "%", + "x-oapi-codegen-extra-tags": { + "bson": "downloadProgress" + } + }, + "xr.swmctrl.recentUpgradeClassification": { + "description": "Classification of upgrade impact of executing the software in upgradeBank. \nResult of swmAction to classify upgrade impact. \nSet to empty if it is not applicable for the recent SWM action.\nPossible values:\n- '0': Upgrade not classified yet\n- '1': Upgrade classification failed\n- '2': Configuration cannot be migrated\n- '3': Service affecting upgrade\n- '4': Non-service affecting upgrade\n", + "readOnly": true, + "title": "Upgrade classification", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "upgradeClassification" + } + }, + "xr.swmctrl.recentSWMActionResult": { + "description": "Result of the last completed swmAction. \nEither successfull or reason for failure.\nResult is Unknown during the execution of an SWM action and can be monitored to see both when an SWM action is completed and the result.\nPossible values:\n- '0': Unknown\n- '1': Success. The last SWM action was run successfully.\n- '2': Invalid or unreachable software URL. \n- '3': Not Enough RAM \n- '4': Not Enough Flash\n- '5': Connection Lost\n- '6': SW validation failure\n- '7': SW execute failure\n- '8': Commit failure\n- '9': Wrong SW For Module.\n", + "readOnly": true, + "title": "Last Action Result", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "result" + } + }, + "xr.swmbank.version": { + "description": "Version of the SW deliverable stored in this bank.", + "maxLength": 20, + "readOnly": true, + "title": "Version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "version" + } + }, + "xr.swmbank.configCompVersion": { + "description": "This is compiled into the SW. \nSee Migration above for details Divided into Major Minor Version. \n0xFFFFFFFF = n/a, i.e. there is no data\n", + "readOnly": true, + "title": "Configuration Compatibility Version", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "configCompVersion" + } + }, + "xr.swmbank.configDataSentry": { + "description": "Incremented at every change of user configuration. \nThis refers to the data stored in association with this specific version. \n0xFFFFFFFF = n/a, i.e. there is no data.\n", + "readOnly": true, + "title": "Configuration Data Sentry", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "configDataSentry" + } + }, + "xr.swmbank.action": { + "description": "Bank operation.\nPossible values:\n- 'none'\n- 'wipeout': Action to delete the SW and associated configuration in this Bank. Set to true to trigger the action.\n", + "enum": [ + "wipeout", + "none" + ], + "title": "Action", + "type": "string", + "x-enum-varnames": [ + "Wipeout", + "None" + ], + "x-oapi-codegen-extra-tags": { + "bson": "action" + } + }, + "cm.network-connection": { + "description": "Definition of network connection", + "example": { + "href": "/network-connections/d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "rt": [ + "cm.network-connection" + ], + "id": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "name": "connection 01: Sunnyvale <> San Jose", + "serviceMode": "portMode", + "labels": { + "region": "West Coast" + } + }, + "state": { + "name": "connection 01: Sunnyvale <> San Jose", + "createdBy": "cm", + "lifecycleState": "configured", + "operationalStatus": "enabled", + "labels": { + "region": "West Coast" + } + }, + "endpoints": [ + { + "href": "/network-connections/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/endpoints/9d37cb82-e7e3-45f0-bf9d-0a9f9b7ffd72", + "rt": [ + "cm.network-connection.endpoint" + ], + "id": "9d37cb82-e7e3-45f0-bf9d-0a9f9b7ffd72", + "parentId": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "selector": { + "ifSelectorByHostPortId": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:2" + } + } + }, + "state": { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:2", + "portSourceMAC": "28:c0:da:3e:3e:44" + }, + "moduleIf": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "3c:2c:99:c0:89:00", + "moduleSerialNumber": "12345678900", + "moduleRole": "hub", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T2", + "moduleClientIfPortSpeed": 100 + } + } + }, + { + "href": "/network-connections/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/endpoints/bc8079be-8b19-4f28-a47e-9b30c8fe41f6", + "rt": [ + "cm.network-connection.endpoint" + ], + "id": "bc8079be-8b19-4f28-a47e-9b30c8fe41f6", + "parentId": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "selector": { + "ifSelectorByHostPortId": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + } + }, + "state": { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "28:c0:da:3e:3e:44" + }, + "moduleIf": { + "moduleId": "37fb48e6-bc3f-4f98-766c-5e8fdc7d0335", + "moduleName": "XR Device", + "moduleMAC": "2b-d3-3f-e4-77-c2", + "moduleSerialNumber": "12345678901", + "moduleClientIfAid": "XR T1", + "role": "leaf" + }, + "bandwidth": 100, + "policy": { + "ingressMatchCriteria": "matchAll", + "ingressMatchOuterVlanId": "", + "egressMatchCriteria": "matchAll", + "egressMatchOuterVlanId": "" + } + } + } + ], + "localConnections": [ + { + "href": "/network-connections/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/local-connections/138ffcf5-5e77-4121-9e84-9fb9e677cbc4", + "rt": [ + "cm.network-connection.localConnection" + ], + "id": "138ffcf5-5e77-4121-9e84-9fb9e677cbc4", + "parentId": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "moduleId": "37fb48e6-bc3f-4f98-766c-5e8fdc7d0335", + "clientAid": "XR T1", + "dscgAid": "XR-L1-C1-DSCG1", + "directionality": "biDir" + }, + "state": { + "lcColId": 1, + "aid": "XR-T1,XR-L1-C1-ODUCni-1-ODUji-1", + "directionality": "biDir", + "moduleId": "37fb48e6-bc3f-4f98-766c-5e8fdc7d0335", + "moduleMAC": "2b-d3-3f-e4-77-c2", + "clientAid": "XR-T1", + "lineAid": "XR-L1-C1-ODUCni-1-ODUji-1", + "dscgAid": "XR-L1-C1-DSCG1", + "remoteModuleMAC": "3c:2c:99:c0:89:00", + "remoteClientAid": "XR T2" + } + }, + { + "href": "/network-connections/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/local-connections/92c8cd71-4d8b-412f-90b4-de4ec3448eb2", + "rt": [ + "cm.network-connection.localConnection" + ], + "id": "92c8cd71-4d8b-412f-90b4-de4ec3448eb2", + "parentId": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "clientAid": "XR T2", + "dscgAid": "XR-L1-C1-DSCG1", + "directionality": "biDir" + }, + "state": { + "lcColId": 1, + "aid": "XR-T2,XR-L1-C1-ODUCni-1-ODUji-1", + "directionality": "biDir", + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleMAC": "2b-d3-3f-e4-77-c2", + "clientAid": "XR-T2", + "lineAid": "XR-L1-C1-ODUCni-1-ODUji-1", + "dscgAid": "XR-L1-C1-DSCG1", + "remoteModuleMAC": "3c:2c:99:c0:89:00", + "remoteClientAid": "XR T2" + } + } + ] + }, + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.network-connection.config" + }, + "state": { + "$ref": "#/components/schemas/cm.network-connection.state" + }, + "endpoints": { + "$ref": "#/components/schemas/cm.network-connection.endpoints" + }, + "lcs": { + "$ref": "#/components/schemas/cm.network-connection.local-connections" + } + }, + "type": "object" + }, + "cm.network-connection.config": { + "additionalProperties": false, + "description": "Definition of network connection configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "serviceMode": { + "$ref": "#/components/schemas/cm.network-connection.parameters.serviceMode" + }, + "mc": { + "$ref": "#/components/schemas/cm.network-connection.parameters.mc" + }, + "outerVID": { + "$ref": "#/components/schemas/cm.network-connection.parameters.outerVID" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.network-connection.state": { + "description": "Definition of network connection state parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "serviceMode": { + "$ref": "#/components/schemas/cm.network-connection.parameters.serviceMode" + }, + "createdBy": { + "$ref": "#/components/schemas/cm.network-connection.parameters.createdBy" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.network-connection.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + }, + "operationalStatus": { + "$ref": "#/components/schemas/cm.network-connection.parameters.operationalStatus" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.network-connection.parameters.serviceMode": { + "default": "portMode", + "description": "Provides the network connection type.\nPossible values:\n- 'portMode': Provides transparent transport of Ethernet or OTN traffic between XR hub and leaf client ports\n- 'vtiP2mpMode': Provides transport of VLAN flows between XR hub and leaf client ports where downstream traffic and bandwidth from Hub module can be shared by multiple Leaf modules\n- 'vtiP2pSymmetric': Provides transport of VLAN flows between XR hub and leaf client ports using a symmetric P2P bidirectional (upstream and downstream) flow between a Hub and a Leaf module\n- 'vtiP2pAsymmetric': Provides transport of VLAN flows between XR hub and leaf client ports using an asymmetric P2P bidirectional (upstream and downstream) flow between a Hub and a Leaf module\n", + "enum": [ + "portMode", + "vtiP2mpMode", + "vtiP2pSymmetric", + "vtiP2pAsymmetric" + ], + "title": "Service Mode", + "type": "string", + "x-enum-varnames": [ + "Port mode", + "VTI P2MP mode", + "VTI P2MP symmetric", + "VTI P2MP asymmetric" + ], + "x-oapi-codegen-extra-tags": { + "bson": "serviceMode" + } + }, + "cm.network-connection.parameters.createdBy": { + "description": "Indicates whether network-connection orchestration should be done through CM interface or through Host interface\nPossible values: 'host', 'cm'\n- 'host': Created through host interface and discovered by CM\n Cannot be edited or deleted through CM interface\n- 'cm': Created through CM interface\n Can be edited or deleted through CM interface\n", + "enum": [ + "host", + "cm" + ], + "readOnly": true, + "title": "Created by", + "type": "string", + "x-enum-varnames": [ + "Host", + "IPM" + ], + "x-oapi-codegen-extra-tags": { + "bson": "createdBy" + } + }, + "cm.network-connection.parameters.lifecycleState": { + "description": "Provides the configuration status of a network connection.\nPossible values:\n- 'pendingConfiguration': This state occurs when one of the network connection modules is pending configuration or pending deletion.\n- 'configured': This state occurs when all network connection modules are configured.\n- 'configurationFailed': This state may occur when at least a configuration of a module from this network connection failed or timeout.\n- 'pendingDeletion': This state may occur when a request to delete this network connection is being processed.\n- 'deletionFailed': This state may occur when at least a removal of a module from this network connection failed or timeout.\n- 'networkConflict': This state may occur when there is a conflict in a network connection module configuration.\n- 'deleted': This state occurs when a network connection is removed.\n", + "enum": [ + "pendingConfiguration", + "configured", + "configurationFailed", + "pendingDeletion", + "deletionFailed", + "networkConflict", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending configuration", + "Configured", + "Configuration failed", + "Pending deletion", + "Deletion failed", + "Network conflict", + "Deleted" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleState" + } + }, + "cm.network-connection.parameters.operationalStatus": { + "description": "Operational Status.", + "enum": [ + "enabled", + "disabled" + ], + "readOnly": true, + "title": "Operational status", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "operationalStatus" + } + }, + "cm.network-connection.parameters.mc": { + "description": "Match Criteria applied to the packets received from network side before sending to the client side.\nPossible Values:\n- 'matchAll': All packets from the associated client interface\n- 'matchOuterVID': Based on outer VLAN ID\n- 'none'\n", + "enum": [ + "matchAll", + "matchOuterVID", + "none" + ], + "type": "string", + "x-enum-varnames": [ + "Match all", + "Match outer VLAN Id", + "None" + ], + "x-oapi-codegen-extra-tags": { + "bson": "mc" + } + }, + "cm.network-connection.parameters.outerVID": { + "description": "String format listing of one or more individual VLAN IDs separated by \"&\" and/or ranges of VLAN IDs connected with \"&&\". \nExample \"10 & 20 & 50 && 100\" represents the VLAN IDs 10, 20 and 50-100.\n", + "pattern": "((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&\\& (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9]))* | ((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&)* | (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])", + "title": "Match Criteria VLAN IDs", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "outerVID" + } + }, + "cm.network-connection.create": { + "additionalProperties": false, + "description": "Definition of network connection creation parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "serviceMode": { + "$ref": "#/components/schemas/cm.network-connection.parameters.serviceMode" + }, + "mc": { + "$ref": "#/components/schemas/cm.network-connection.parameters.mc" + }, + "outerVID": { + "$ref": "#/components/schemas/cm.network-connection.parameters.outerVID" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + }, + "endpoints": { + "items": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.create" + }, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "endpoints", + "name", + "serviceMode" + ], + "type": "object" + }, + "cm.network-connection.update": { + "additionalProperties": false, + "description": "Definition of network connection configurable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "serviceMode": { + "$ref": "#/components/schemas/cm.network-connection.parameters.serviceMode" + }, + "mc": { + "$ref": "#/components/schemas/cm.network-connection.parameters.mc" + }, + "outerVID": { + "$ref": "#/components/schemas/cm.network-connection.parameters.outerVID" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.network-connection.endpoint": { + "description": "Definition of network connection endpoint object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "config": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.config" + }, + "state": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.state" + }, + "acs": { + "$ref": "#/components/schemas/cm.network-connection.acs" + } + } + }, + "cm.network-connection.endpoints": { + "description": "List of network connection endpoints", + "items": { + "$ref": "#/components/schemas/cm.network-connection.endpoint" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "endpoints" + } + }, + "cm.network-connection.endpoint.config": { + "additionalProperties": false, + "description": "Definition of network connection endpoint configurable parameters", + "properties": { + "selector": { + "$ref": "#/components/schemas/cm.selectors.ifSelector" + }, + "capacity": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.parameters.capacity" + } + }, + "type": "object" + }, + "cm.network-connection.endpoint.state": { + "description": "Definition of network-connection endpoint state object", + "properties": { + "hostPort": { + "$ref": "#/components/schemas/cm.interface.hostPort" + }, + "moduleIf": { + "$ref": "#/components/schemas/cm.interface.moduleIf" + }, + "capacity": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.parameters.capacity" + } + } + }, + "cm.network-connection.endpoint.parameters.capacity": { + "description": "Client to network capacity of the attachment circuit.\nPossible values are defined in multiples of 25Gbps up to maximum module rate.\n", + "title": "Capacity", + "type": "integer", + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "capacity" + } + }, + "cm.network-connection.endpoint.create": { + "additionalProperties": false, + "description": "Definition of network connection endpoint creation parameters", + "properties": { + "selector": { + "$ref": "#/components/schemas/cm.selectors.ifSelector" + }, + "capacity": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.parameters.capacity" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "cm.network-connection.endpoint.update": { + "additionalProperties": false, + "description": "Definition of network connection endpoint editable parameters", + "properties": { + "capacity": { + "$ref": "#/components/schemas/cm.network-connection.endpoint.parameters.capacity" + } + }, + "required": [ + "capacity" + ], + "type": "object" + }, + "cm.network-connection.ac": { + "description": "Attachment circuit", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentIds": { + "$ref": "#/components/schemas/cm.parameters.parentIds" + }, + "config": { + "$ref": "#/components/schemas/cm.network-connection.ac.config" + }, + "state": { + "$ref": "#/components/schemas/cm.network-connection.ac.state" + } + }, + "type": "object" + }, + "cm.network-connection.acs": { + "description": "List of attachment circuits", + "items": { + "$ref": "#/components/schemas/cm.network-connection.ac" + }, + "maxItems": 2, + "minItems": 1, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "acs" + } + }, + "cm.network-connection.ac.config": { + "description": "Definition attachment circuit configurable parameters", + "properties": { + "capacity": { + "$ref": "#/components/schemas/cm.network-connection.ac.parameters.capacity" + }, + "imc": { + "$ref": "#/components/schemas/cm.network-connection.ac.parameters.imc" + }, + "imcOuterVID": { + "$ref": "#/components/schemas/cm.network-connection.ac.parameters.imcOuterVID" + }, + "emc": { + "$ref": "#/components/schemas/cm.network-connection.ac.parameters.emc" + }, + "emcOuterVID": { + "$ref": "#/components/schemas/cm.network-connection.ac.parameters.emcOuterVID" + } + }, + "type": "object" + }, + "cm.network-connection.ac.state": { + "description": "Definition of the attachment circuit state parameters.", + "properties": { + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "capacity": { + "$ref": "#/components/schemas/xr.ethernet.ac.capacity" + }, + "imc": { + "$ref": "#/components/schemas/xr.ethernet.ac.imc" + }, + "imcOuterVID": { + "$ref": "#/components/schemas/xr.ethernet.ac.imcOuterVID" + }, + "emc": { + "$ref": "#/components/schemas/xr.ethernet.ac.emc" + }, + "emcOuterVID": { + "$ref": "#/components/schemas/xr.ethernet.ac.emcOuterVID" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.network-connection.ac.parameters.lifecycleState" + } + }, + "type": "object" + }, + "cm.network-connection.ac.parameters.capacity": { + "description": "Client to network capacity of the attachment circuit.\nPossible values are defined in multiples of 25Gbps up to maximum module rate.\n", + "title": "Capacity", + "type": "integer", + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "capacity" + } + }, + "cm.network-connection.ac.parameters.imc": { + "description": "Ingress Match Criteria applied to the packets received from client port before sending to the network side.\nPossible Values:\n- 'matchAll': All packets from the associated client interface\n- 'matchOuterVID': Based on outer VLAN ID\n- 'none'\n", + "enum": [ + "matchAll", + "matchOuterVID", + "none" + ], + "type": "string", + "x-enum-varnames": [ + "Match all", + "Match outer VLAN Id", + "None" + ], + "x-oapi-codegen-extra-tags": { + "bson": "imc" + } + }, + "cm.network-connection.ac.parameters.emc": { + "description": "Egress Match Criteria applied to the packets received from network side before sending to the client side.\nPossible Values:\n- 'matchAll': All packets from the associated client interface\n- 'matchOuterVID': Based on outer VLAN ID\n- 'none'\n", + "enum": [ + "matchAll", + "matchOuterVID", + "none" + ], + "type": "string", + "x-enum-varnames": [ + "Match all", + "Match outer VLAN Id", + "None" + ], + "x-oapi-codegen-extra-tags": { + "bson": "emc" + } + }, + "cm.network-connection.ac.parameters.imcOuterVID": { + "description": "String format listing of one or more individual VLAN IDs separated by \"&\" and/or ranges of VLAN IDs connected with \"&&\".\nExample \"10 & 20 & 50 && 100\" represents the VLAN IDs 10, 20 and 50-100.\n", + "pattern": "((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&\\& (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9]))* | ((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&)* | (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])", + "title": "Ingress Match Criteria VLAN IDs", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "imcOuterVID" + } + }, + "cm.network-connection.ac.parameters.emcOuterVID": { + "description": "String format listing of one or more individual VLAN IDs separated by \"&\" and/or ranges of VLAN IDs connected with \"&&\". \nExample \"10 & 20 & 50 && 100\" represents the VLAN IDs 10, 20 and 50-100.\n", + "pattern": "((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&\\& (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9]))* | ((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])\\&)* | (409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|[1-9])", + "title": "Egress Match Criteria VLAN IDs", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "emcOuterVID" + } + }, + "cm.network-connection.ac.parameters.lifecycleState": { + "description": "Provides the configuration status of an attachment circuit.\nPossible values:\n- 'pendingConfiguration': This state occurs when the module ac configuration is required.\n- 'configured': This state occurs when the module is configured in the network according to its ac requirements.\n- 'configurationFailed': This state occurs when the module ac configuration failed or timeout.\n- 'pendingDeletion': This state occurs when the module shall be removed from the current network-connection.\n- 'deletionFailed': This state occurs when the configuration to remove the module from the network-connection failed or timeout.\n- 'networkConflict': The current module configuration does not match the request or was already a member of other existing network-connection.\n- 'deleted': This state occurs when the current module is removed from the network-connection.\n", + "title": "Lifecycle State" + }, + "cm.network-connection.local-connection": { + "description": "Cross-connection between ethernet interface and optical line interface within a device", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentIds": { + "$ref": "#/components/schemas/cm.parameters.parentIds" + }, + "config": { + "$ref": "#/components/schemas/cm.network-connection.local-connection.config" + }, + "state": { + "$ref": "#/components/schemas/cm.network-connection.local-connection.state" + } + }, + "type": "object" + }, + "cm.network-connection.local-connections": { + "description": "List of local connections", + "items": { + "$ref": "#/components/schemas/cm.network-connection.local-connection" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "lcs" + } + }, + "cm.network-connection.local-connection.config": { + "additionalProperties": false, + "description": "Definition of local-connection configurable parameters", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/cm.network-connection.local-connection.parameters.moduleId" + }, + "clientAid": { + "$ref": "#/components/schemas/cm.network-connection.local-connection.parameters.clientAid" + }, + "dscgAid": { + "$ref": "#/components/schemas/cm.network-connection.local-connection.parameters.dscgAid" + }, + "direction": { + "$ref": "#/components/schemas/cm.network-connection.local-connection.parameters.direction" + } + }, + "type": "object" + }, + "cm.network-connection.local-connection.state": { + "description": "Definition of network-connection state parameters", + "properties": { + "lcAid": { + "$ref": "#/components/schemas/xr.lc.aid" + }, + "colId": { + "$ref": "#/components/schemas/xr.common.colId" + }, + "direction": { + "$ref": "#/components/schemas/xr.lc.direction" + }, + "moduleId": { + "$ref": "#/components/schemas/xr.device.di" + }, + "macAddress": { + "$ref": "#/components/schemas/xr.platform.macAddress" + }, + "clientAid": { + "$ref": "#/components/schemas/xr.lc.clientAid" + }, + "lineAid": { + "$ref": "#/components/schemas/xr.lc.lineAid" + }, + "dscgAid": { + "$ref": "#/components/schemas/xr.lc.dscgAid" + }, + "remoteModuleId": { + "$ref": "#/components/schemas/xr.lc.remoteModuleId" + }, + "remoteClientAid": { + "$ref": "#/components/schemas/xr.lc.remoteClientId" + } + }, + "type": "object" + }, + "cm.network-connection.local-connection.parameters.moduleId": { + "description": "Module identifier", + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "title": "ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleId" + } + }, + "cm.network-connection.local-connection.parameters.clientAid": { + "description": "Access Identifier (AID) within module and client interface collection.", + "maxLength": 64, + "title": "Client AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clientAid" + } + }, + "cm.network-connection.local-connection.parameters.dscgAid": { + "description": "Access Identifier (AID) within module and DSCG collection.", + "maxLength": 64, + "title": "DSCG AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "dscgAid" + } + }, + "cm.network-connection.local-connection.parameters.direction": { + "description": "Directionality of the local connection. \nPossible values:\n- 'txRx': Both Transmit (Client to Line) and Receive (Line to Client) direction \n- 'tx': Client to Line direction only. \n- 'rx': Line to Client direction only.\n", + "enum": [ + "txRx", + "tx", + "rx" + ], + "title": "Directionality of the LC.", + "type": "string", + "x-enum-varnames": [ + "TX and RX", + "TX only", + "RX only" + ], + "x-oapi-codegen-extra-tags": { + "bson": "direction" + } + }, + "cm.parameters.lifecycleStateCause": { + "description": "Detailed information regarding the object lifecycle state.", + "properties": { + "action": { + "$ref": "#/components/schemas/cm.lifecycleStateCause.parameters.action" + }, + "timestamp": { + "$ref": "#/components/schemas/cm.lifecycleStateCause.parameters.timestamp" + }, + "traceId": { + "$ref": "#/components/schemas/cm.lifecycleStateCause.parameters.traceId" + }, + "errors": { + "items": { + "$ref": "#/components/schemas/cm.error" + }, + "type": "array" + } + }, + "title": "Lifecycle State Cause", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleStateCause" + } + }, + "cm.lifecycleStateCause.parameters.action": { + "description": "Internal id of the action that triggered the current lifecycle state change.", + "readOnly": true, + "title": "Action", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "action" + } + }, + "cm.lifecycleStateCause.parameters.timestamp": { + "description": "Timestamp of the action that triggered the current lifecycle state change in date-time format pattern according to IETF RFC 3339.", + "format": "date-time", + "readOnly": true, + "title": "Timestamp", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "timestamp" + } + }, + "cm.lifecycleStateCause.parameters.traceId": { + "description": "Id assigned to the request, job, or action that triggered the current lifecycle state change.", + "readOnly": true, + "title": "Trace Id", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "traceId" + } + }, + "cm.selectors.ifSelector": { + "description": "Definition of selector", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "hostPortSelectorByName": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorByName" + }, + "hostPortSelectorByPortId": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorByPortId" + }, + "hostPortSelectorBySysName": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorBySysName" + }, + "hostPortSelectorByPortSourceMAC": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorByPortSourceMAC" + }, + "moduleIfSelectorByModuleId": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelectorByModuleId" + }, + "moduleIfSelectorByModuleName": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelectorByModuleName" + }, + "moduleIfSelectorByModuleMAC": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelectorByModuleMAC" + }, + "moduleIfSelectorByModuleSerialNumber": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelectorByModuleSerialNumber" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "selector" + } + }, + "cm.selector.hostPortSelectorByName": { + "additionalProperties": false, + "description": "Definition of host port selector based on host port name information", + "maxProperties": 3, + "minProperties": 3, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "portIdSubtype": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portIdSubtype" + }, + "portId": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portId" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hostPortSelectorByName" + } + }, + "cm.selector.hostPortSelector.parameters.portIdSubtype": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria for associating the host port to a module client interface using the tuple chassisIdSubtype, chassisId, portIdSubtype, portId.\n", + "enum": [ + "interfaceAlias", + "portComponent", + "macAddress", + "networkAddress", + "interfaceName", + "agentCircuitId", + "local" + ], + "title": "LLDP Port ID encoding", + "type": "string", + "x-enum-varnames": [ + "Interface alias", + "Port component", + "MAC address", + "Network address", + "Interface name", + "Agent circuit ID", + "Locally assigned" + ], + "x-oapi-codegen-extra-tags": { + "bson": "portIdSubtype" + } + }, + "cm.selector.hostPortSelector.parameters.portId": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria for associating the host port to a module client interface using the tuple chassisIdSubtype, chassisId, portIdSubtype, portId.\n", + "title": "LLDP Port ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "portId" + } + }, + "cm.selector.hostPortSelectorByPortId": { + "additionalProperties": false, + "description": "Definition of host port selector based on host port id and chassis id information", + "maxProperties": 4, + "minProperties": 4, + "properties": { + "chassisIdSubtype": { + "$ref": "#/components/schemas/cm.selector.hostSelector.parameters.chassisIdSubtype" + }, + "chassisId": { + "$ref": "#/components/schemas/cm.selector.hostSelector.parameters.chassisId" + }, + "portIdSubtype": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portIdSubtype" + }, + "portId": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portId" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hostPortSelectorByPortId" + } + }, + "cm.selector.hostSelector.parameters.chassisIdSubtype": { + "default": "macAddress", + "description": "Value of chassisIdSubtype (encoding of chassisId) within LLDP data.\nOnly applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules.\n", + "enum": [ + "reserved", + "chassisComponent", + "interfaceAlias", + "portComponent", + "macAddress", + "networkAddress", + "interfaceName", + "local" + ], + "title": "LLDP Chassis ID encoding", + "type": "string", + "x-enum-varnames": [ + "Reserved", + "Chassis component", + "Interface alias", + "Port component", + "MAC address", + "Network address", + "Interface name", + "Locally assigned" + ], + "x-oapi-codegen-extra-tags": { + "bson": "chassisIdSubtype" + } + }, + "cm.selector.hostSelector.parameters.chassisId": { + "description": "Value of chassisId within LLDP data\nOnly applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules.\n", + "title": "LLDP Chassis ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "chassisId" + } + }, + "cm.selector.hostPortSelectorBySysName": { + "additionalProperties": false, + "description": "Definition of host port selector based on host port id and host system name information", + "maxProperties": 3, + "minProperties": 3, + "properties": { + "sysName": { + "$ref": "#/components/schemas/cm.selector.hostSelector.parameters.sysName" + }, + "portIdSubtype": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portIdSubtype" + }, + "portId": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portId" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hostPortSelectorBySysName" + } + }, + "cm.selector.hostSelector.parameters.sysName": { + "description": "Value of System Name within LLDP data\nOnly applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules.\n", + "title": "LLDP System Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "sysName" + } + }, + "cm.selector.hostPortSelectorByPortSourceMAC": { + "additionalProperties": false, + "description": "Definition of host port selector based on host port source MAC address id information", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "portSourceMAC": { + "$ref": "#/components/schemas/cm.selector.hostPortSelector.parameters.portSourceMAC" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hostPortSelectorByPortSourceMAC" + } + }, + "cm.selector.hostPortSelector.parameters.portSourceMAC": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria for associating the host port to a module client interface using the portSourceMAC.\n", + "title": "Host Port MAC Address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "portSourceMAC" + } + }, + "cm.selector.moduleIfSelectorByModuleId": { + "additionalProperties": false, + "description": "Definition of host port selector based on module id information", + "maxProperties": 2, + "minProperties": 2, + "properties": { + "moduleId": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleId" + }, + "moduleClientIfAid": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelector.parameters.moduleClientIfAid" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIfSelectorByModuleId" + } + }, + "cm.selector.moduleSelector.parameters.moduleId": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules using moduleId.\n", + "title": "Module Identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleId" + } + }, + "cm.selector.moduleIfSelector.parameters.moduleClientIfAid": { + "description": "TODO\n", + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleClientIfAid" + } + }, + "cm.selector.moduleIfSelectorByModuleName": { + "additionalProperties": false, + "description": "Definition of host port selector based on module serial number information", + "maxProperties": 2, + "minProperties": 2, + "properties": { + "moduleName": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleName" + }, + "moduleClientIfAid": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelector.parameters.moduleClientIfAid" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIfSelectorByModuleName" + } + }, + "cm.selector.moduleSelector.parameters.moduleName": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules.\n", + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleName" + } + }, + "cm.selector.moduleIfSelectorByModuleMAC": { + "additionalProperties": false, + "description": "Definition of host port selector based on module MAC address information", + "maxProperties": 2, + "minProperties": 2, + "properties": { + "moduleMAC": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleMAC" + }, + "moduleClientIfAid": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelector.parameters.moduleClientIfAid" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIfSelectorByModuleMAC" + } + }, + "cm.selector.moduleSelector.parameters.moduleMAC": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules.\n", + "title": "MAC Address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleMAC" + } + }, + "cm.selector.moduleIfSelectorByModuleSerialNumber": { + "additionalProperties": false, + "description": "Definition of host port selector based on module serial number information", + "maxProperties": 2, + "minProperties": 2, + "properties": { + "moduleSerialNumber": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleSerialNumber" + }, + "moduleClientIfAid": { + "$ref": "#/components/schemas/cm.selector.moduleIfSelector.parameters.moduleClientIfAid" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIfSelectorByModuleSerialNumber" + } + }, + "cm.selector.moduleSelector.parameters.moduleSerialNumber": { + "description": "Only applicable when pre-planning objects.\nIf defined, this parameter is used as matching criteria when associating discovered XR modules.\n", + "title": "Serial number", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleSerialNumber" + } + }, + "cm.interface.hostPort": { + "description": "Definition of interface host parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "hostName": { + "$ref": "#/components/schemas/cm.parameters.hostName" + }, + "chassisIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisIdSubtype" + }, + "chassisId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisId" + }, + "sysName": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysName" + }, + "portIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portIdSubtype" + }, + "portId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portId" + }, + "portSourceMAC": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.localPortSourceMAC" + }, + "portDescr": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portDescr" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hostPort" + } + }, + "cm.parameters.hostName": { + "description": "User defined object name.", + "maxLength": 64, + "pattern": "^([A-Za-z0-9_\\-.,: ]*)$", + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "hostName" + } + }, + "cm.interface.moduleIf": { + "description": "Definition of interface module parameters", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/xr.device.di" + }, + "moduleName": { + "$ref": "#/components/schemas/xr.device.n" + }, + "macAddress": { + "$ref": "#/components/schemas/xr.platform.macAddress" + }, + "serialNumber": { + "$ref": "#/components/schemas/xr.platform.mnsel" + }, + "currentRole": { + "$ref": "#/components/schemas/xr.configuration.currentRole" + }, + "clientIfColId": { + "$ref": "#/components/schemas/xr.ethernet.colId" + }, + "clientIfAid": { + "$ref": "#/components/schemas/xr.ethernet.aid" + }, + "clientIfPortSpeed": { + "$ref": "#/components/schemas/xr.ethernet.portSpeed" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIf" + } + }, + "cm.parameters.parentIds": { + "description": "List of Parent Object identifiers", + "items": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "title": "Parent IDs", + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentIds" + } + }, + "xr.ethernet.colId": { + "description": "Object identifier in the supporting Ethernet collection.", + "title": "Collection Id", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "clientIfColId" + } + }, + "cm.xr-network": { + "description": "Definition of xr-network object", + "example": { + "href": "/networks/5f8c47b4-c02a-6242-260c-185dd04b8faf", + "rt": [ + "cm.network" + ], + "id": "5f8c47b4-c02a-6242-260c-185dd04b8faf", + "config": { + "name": "Sunnyvale Constellation", + "constellationFrequency": 193100000, + "modulation": "16QAM" + }, + "state": { + "name": "Sunnyvale Constellation", + "constellationFrequency": 193100000, + "modulation": "16QAM", + "lifecycleState": "configured", + "reachableModules": [ + { + "discoveredTime": "2022-04-05T14:32Z", + "module": { + "moduleId": "c85c2904-1794-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:03", + "moduleSerialNumber": "12345678903", + "configuredRole": "Auto", + "currentRole": "Hub", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "frequencyCtrl": "XR", + "constellationFrequency": 194100000, + "operatingFrequency": 194100000, + "ncoFrequency": 194100000, + "modulation": "16QAM", + "capacity": 400, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 16, + "txPowerTargetPerDsc": -6.4 + }, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "49:48:59:74:0F:05", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "6F:B9:08:F0:C2:49", + "portDescr": "et-1/0/0:0" + }, + "module": { + "moduleId": "c85c2904-1794-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:03", + "moduleSerialNumber": "12345678903", + "moduleCurrentRole": "Hub", + "moduleClientIfColId": 1, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 400 + } + } + ] + }, + { + "discoveredTime": "2022-04-05T14:32Z", + "module": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "configuredRole": "Auto", + "currentRole": "hub", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "frequencyCtrl": "XR", + "constellationFrequency": 193100000, + "operatingFrequency": 193100000, + "ncoFrequency": 193100000, + "modulation": "16QAM", + "capacity": 400, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 16, + "txPowerTargetPerDsc": -6.4, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "da:3d:c2:4c:55:40", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "moduleCurrentRole": "hub", + "moduleClientIfColId": 1, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + } + }, + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:0", + "portSourceMAC": "04:34:D6:88:A8:CB", + "portDescr": "et-1/0/1:0" + }, + "moduleIf": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "moduleCurrentRole": "hub", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T2", + "moduleClientIfPortSpeed": 100 + } + } + ] + } + }, + { + "discoveredTime": "2022-04-05T14:32Z", + "module": { + "moduleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678901", + "configuredRole": "Auto", + "currentRole": "Leaf", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "frequencyCtrl": "XR", + "constellationFrequency": 193100000, + "operatingFrequency": 193074500, + "ncoFrequency": 193074500, + "modulation": "16QAM", + "capacity": 100, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 4, + "txPowerTargetPerDsc": -6.4, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "8C:23:5E:E9:72:1C", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678901", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 1, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + } + }, + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:0", + "portSourceMAC": "B9:0B:80:0E:0B:70", + "portDescr": "et-1/0/1:0" + }, + "moduleIf": { + "moduleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678901", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T2", + "moduleClientIfPortSpeed": 100 + } + } + ] + } + }, + { + "discoveredTime": "2022-04-05T14:32Z", + "module": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678902", + "configuredRole": "Auto", + "currentRole": "Leaf", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "frequencyCtrl": "XR", + "fiberConnectionMode": "dual", + "constellationFrequency": 193100000, + "operatingFrequency": 193074500, + "ncoFrequency": 193074500, + "modulation": "16QAM", + "capacity": 100, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 4, + "txPowerTargetPerDsc": -6.4, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:99:F8:2c:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "da:3d:c2:4c:55:40", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678902", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + } + } + ] + } + } + ], + "controlLinks": [ + { + "sourceModuleId": "18e47620-8848-4c7e-710f-05c668478c57", + "destinationModuleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "conState": "Active", + "lastConStateChange": 1628084981 + }, + { + "sourceModuleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "destinationModuleId": "18e47620-8848-4c7e-710f-05c668478c57", + "conState": "Active", + "lastConStateChange": 1628084981 + }, + { + "sourceModuleId": "18e47620-8848-4c7e-710f-05c668478c57", + "destinationModuleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "conState": "Active", + "lastConStateChange": 1628081381 + }, + { + "sourceModuleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "destinationModuleId": "18e47620-8848-4c7e-710f-05c668478c57", + "conState": "Active", + "lastConStateChange": 1628081381 + } + ], + "availableServices": [ + { + "type": "100G", + "maximum": 4, + "available": 2, + "used": 2 + }, + { + "type": "75G", + "maximum": 4, + "available": 0, + "used": 0 + }, + { + "type": "50G", + "maximum": 8, + "available": 0, + "used": 0 + }, + { + "type": "25G", + "maximum": 16, + "available": 0, + "used": 0 + } + ] + }, + "hub": { + "href": "/networks/5f8c47b4-c02a-6242-260c-185dd04b8faf/hub/80da9300-8e6d-49d6-890f-c6436188b0fb", + "rt": [ + "cm.xr-network.hub" + ], + "id": "80da9300-8e6d-49d6-890f-c6436188b0fb", + "parentId": "5f8c47b4-c02a-6242-260c-185dd04b8faf", + "config": { + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:2" + } + }, + "module": { + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "maxAllowedDSCs": 16 + } + }, + "state": { + "lifecycleState": "configured", + "module": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "configuredRole": "Auto", + "currentRole": "hub", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "frequencyCtrl": "XR", + "constellationFrequency": 193100000, + "operatingFrequency": 193100000, + "ncoFrequency": 193100000, + "modulation": "16QAM", + "capacity": 400, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 16, + "txPowerTargetPerDsc": -6.4 + }, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "da:3d:c2:4c:55:40", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "moduleCurrentRole": "hub", + "moduleClientIfColId": 1, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + } + }, + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:0", + "portSourceMAC": "04:34:D6:88:A8:CB", + "portDescr": "et-1/0/1:0" + }, + "moduleIf": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "moduleCurrentRole": "hub", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T2", + "moduleClientIfPortSpeed": 100 + } + } + ] + } + }, + "leafModules": [ + { + "href": "/networks/5f8c47b4-c02a-6242-260c-185dd04b8faf/leafModules/0f4d67fe-02aa-44ec-a5d8-4c7a71b240cb", + "rt": [ + "cm.xr-network.hub" + ], + "id": "0f4d67fe-02aa-44ec-a5d8-4c7a71b240cb", + "parentId": "5f8c47b4-c02a-6242-260c-185dd04b8faf", + "config": { + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + }, + "module": { + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual" + } + }, + "state": { + "lifecycleState": "configured", + "module": { + "moduleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678901", + "configuredRole": "Auto", + "currentRole": "Leaf", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual", + "frequencyCtrl": "XR", + "constellationFrequency": 193100000, + "operatingFrequency": 193074500, + "ncoFrequency": 193074500, + "modulation": "16QAM", + "capacity": 100, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 4, + "txPowerTargetPerDsc": -6.4 + }, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "8C:23:5E:E9:72:1C", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678901", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 1, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + } + }, + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:0B:F8:00:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:0", + "portSourceMAC": "B9:0B:80:0E:0B:70", + "portDescr": "et-1/0/1:0" + }, + "moduleIf": { + "moduleId": "153a21fc-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678901", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T2", + "moduleClientIfPortSpeed": 100 + } + } + ] + } + }, + { + "href": "/networks/5f8c47b4-c02a-6242-260c-185dd04b8faf/leafModules/0a6cd54a-7767-43b9-915b-0ccc643412b9", + "rt": [ + "cm.xr-network.hub" + ], + "id": "0a6cd54a-7767-43b9-915b-0ccc643412b9", + "parentId": "5f8c47b4-c02a-6242-260c-185dd04b8faf", + "config": { + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:99:F8:2c:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + }, + "module": { + "trafficMode": "L1Mode", + "fiberConnectionMode": "dual" + } + }, + "state": { + "lifecycleState": "configured", + "module": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678902", + "configuredRole": "Auto", + "currentRole": "Leaf", + "roleStatus": "Ready", + "trafficMode": "L1Mode", + "frequencyCtrl": "XR", + "fiberConnectionMode": "dual", + "constellationFrequency": 193100000, + "operatingFrequency": 193074500, + "ncoFrequency": 193074500, + "modulation": "16QAM", + "capacity": 100, + "clientPortMode": "ethernet", + "baudRate": 32, + "maxAllowedDSCs": 4, + "txPowerTargetPerDsc": -6.4 + }, + "endpoints": [ + { + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:99:F8:2c:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "da:3d:c2:4c:55:40", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678902", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + } + } + ] + } + } + ] + }, + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.xr-network.config" + }, + "state": { + "$ref": "#/components/schemas/cm.xr-network.state" + }, + "hubModule": { + "$ref": "#/components/schemas/cm.xr-network.hubModule" + }, + "leafModules": { + "$ref": "#/components/schemas/cm.xr-network.leafModules" + }, + "reachableModules": { + "$ref": "#/components/schemas/cm.xr-network.reachableModules" + } + }, + "type": "object" + }, + "cm.xr-network.config": { + "additionalProperties": false, + "description": "Definition of xr-network configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.xr-network.parameters.name" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/cm.xr-network.parameters.constellationFrequency" + }, + "modulation": { + "$ref": "#/components/schemas/cm.xr-network.parameters.modulation" + } + }, + "type": "object" + }, + "cm.xr-network.state": { + "description": "Definition of constellation state", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.xr-network.parameters.name" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/xr.carrier.constellationFrequency" + }, + "modulation": { + "$ref": "#/components/schemas/xr.carrier.modulation" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.xr-network.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + }, + "controlLinks": { + "$ref": "#/components/schemas/cm.xr-network.state.controlLinks" + }, + "availableServices": { + "$ref": "#/components/schemas/cm.xr-network.state.availableServices" + } + }, + "type": "object" + }, + "cm.xr-network.state.controlLink": { + "description": "Definition of constellation control link parameters", + "properties": { + "sourceModuleId": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.sourceModuleId" + }, + "destinationModuleId": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.destinationModuleId" + }, + "conState": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.conState" + }, + "lastConStateChange": { + "$ref": "#/components/schemas/xr.controlplane.neighbor.lastConStateChange" + } + }, + "type": "object" + }, + "cm.xr-network.state.controlLinks": { + "description": "List of constellation control links", + "items": { + "$ref": "#/components/schemas/cm.xr-network.state.controlLink" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "controlLinks" + } + }, + "cm.xr-network.state.availableService": { + "description": "Possible, used and available services on the constellation", + "properties": { + "type": { + "$ref": "#/components/schemas/cm.xr-network.availableService.parameters.type" + }, + "maximum": { + "$ref": "#/components/schemas/cm.xr-network.availableService.parameters.maximum" + }, + "available": { + "$ref": "#/components/schemas/cm.xr-network.availableService.parameters.available" + }, + "used": { + "$ref": "#/components/schemas/cm.xr-network.availableService.parameters.used" + } + }, + "type": "object" + }, + "cm.xr-network.state.availableServices": { + "description": "List of possible and configured services over the constellation", + "items": { + "$ref": "#/components/schemas/cm.xr-network.state.availableService" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "availableServices" + } + }, + "cm.xr-network.parameters.name": { + "description": "User defined xr-network name", + "maxLength": 64, + "title": "Name", + "type": "string", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "cm.xr-network.parameters.constellationFrequency": { + "description": "Carrier center frequency of the Hub module within the constellation (applied to Hub and leaf modules).", + "maximum": 196100000, + "minimum": 191000000, + "title": "Frequency", + "type": "integer", + "x-unit": "MHz", + "x-oapi-codegen-extra-tags": { + "bson": "constellationFrequency" + } + }, + "cm.xr-network.parameters.modulation": { + "description": "Constellation carrier signal mdoulation (applied to Hub and leaf modules).\nPossible values: '16QAM', 'QPSK' ' 8QAM'\n", + "enum": [ + "16QAM", + "QPSK", + "8QAM" + ], + "title": "Modulation", + "type": "string", + "x-enum-varnames": [ + "16QAM", + "QPSK", + "8QAM" + ], + "x-oapi-codegen-extra-tags": { + "bson": "modulation" + } + }, + "cm.xr-network.parameters.lifecycleState": { + "description": "Provides the configuration status of an object.\nPossible values:\n- 'pendingConfiguration': This state occurs when one of the xr-network modules is pending configuration or pending deletion.\n- 'configured': This state occurs when all xr-network modules are configured. \n- 'configurationFailed': This state may occur when at least a configuration of a module from this xr-network failed or timeout.\n- 'pendingDeletion': This state may occur when a request to delete this xr-network is being processed.\n- 'deletionFailed': This state may occur when at least a removal of a module from this xr-network failed or timeout.\n- 'networkConflict': This state may occur when there is a conflict in a xr-network module configuration.\n- 'deleted': This state occurs when a xr-network is removed.\n", + "enum": [ + "pendingConfiguration", + "configured", + "configurationFailed", + "pendingDeletion", + "deletionFailed", + "networkConflict", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending configuration", + "Configured", + "Configuration failed", + "Pending deletion", + "Deletion failed", + "Network conflict", + "Deleted" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleState" + } + }, + "cm.xr-network.availableService.parameters.type": { + "description": "Represents the bandwidth of the possible services in the hub module\nPossible values:\n- 400G\n- 100G\n- 75G\n- 50G\n- 25G\n", + "enum": [ + "100G", + "75G", + "50G", + "25G" + ], + "title": "Bandwidth", + "type": "string", + "x-enum-varnames": [ + "100G", + "75G", + "50G", + "25G" + ], + "x-oapi-codegen-extra-tags": { + "bson": "type" + } + }, + "cm.xr-network.availableService.parameters.maximum": { + "description": "Number of maximum services of the above type that can exist in the constellation.", + "title": "Maximum", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "maximum" + } + }, + "cm.xr-network.availableService.parameters.available": { + "description": "Number of available services of the above type that can be configured in the constellation taking in account the existing hub and leaf modules available resources.", + "title": "Available", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "available" + } + }, + "cm.xr-network.availableService.parameters.used": { + "description": "Number of maximum services of the above type that exist in the constellation.", + "title": "Used", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "used" + } + }, + "cm.xr-network.createRequest": { + "additionalProperties": false, + "description": "Object used in the request body of POST requests in /xr-networks endpoint.\nContains the xr-network, hub and leaf module configuration parameters.\n", + "properties": { + "config": { + "$ref": "#/components/schemas/cm.xr-network.create" + }, + "hubModule": { + "$ref": "#/components/schemas/cm.xr-network.node.create" + }, + "leafModules": { + "items": { + "$ref": "#/components/schemas/cm.xr-network.node.create" + }, + "type": "array" + } + }, + "required": [ + "config", + "hubModule" + ], + "type": "object" + }, + "cm.xr-network.create": { + "additionalProperties": false, + "description": "Definition of xr-network configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.xr-network.parameters.name" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/cm.xr-network.parameters.constellationFrequency" + }, + "modulation": { + "$ref": "#/components/schemas/cm.xr-network.parameters.modulation" + } + }, + "required": [ + "constellationFrequency", + "modulation", + "name" + ], + "type": "object" + }, + "cm.xr-network.update": { + "additionalProperties": false, + "description": "Definition of xr-network editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.xr-network.parameters.name" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/cm.xr-network.parameters.constellationFrequency" + }, + "modulation": { + "$ref": "#/components/schemas/cm.xr-network.parameters.modulation" + } + }, + "type": "object" + }, + "cm.xr-network.hubModule": { + "$ref": "#/components/schemas/cm.xr-network.node" + }, + "cm.xr-network.leafModule": { + "$ref": "#/components/schemas/cm.xr-network.node" + }, + "cm.xr-network.leafModules": { + "description": "List of network connection endpoints", + "items": { + "$ref": "#/components/schemas/cm.xr-network.leafModule" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "leafModules" + } + }, + "cm.xr-network.reachableModule": { + "$ref": "#/components/schemas/cm.xr-network.node" + }, + "cm.xr-network.reachableModules": { + "description": "List of reachable modules of this network", + "items": { + "$ref": "#/components/schemas/cm.xr-network.reachableModule" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "reachableModules" + } + }, + "cm.xr-network.node": { + "description": "Definition of xr-network module object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "config": { + "$ref": "#/components/schemas/cm.xr-network.node.config" + }, + "state": { + "$ref": "#/components/schemas/cm.xr-network.node.state" + } + } + }, + "cm.xr-network.node.config": { + "additionalProperties": false, + "description": "Definition of constellation hub and leaf module configurable parameters", + "properties": { + "selector": { + "$ref": "#/components/schemas/cm.selectors.moduleSelector" + }, + "module": { + "$ref": "#/components/schemas/cm.xr-network.node.config.module" + } + }, + "type": "object" + }, + "cm.xr-network.node.config.module": { + "additionalProperties": false, + "description": "Definition of constellation hub and leaf module configurable parameters", + "properties": { + "trafficMode": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.trafficMode" + }, + "fiberConnectionMode": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.fiberConnectionMode" + }, + "maxAllowedDSCs": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.maxAllowedDSCs" + }, + "txPowerTargetPerDsc": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.txPowerTargetPerDsc" + } + }, + "type": "object" + }, + "cm.xr-network.node.state": { + "description": "Definition of constellation hub and leaf module state object", + "properties": { + "lifecycleState": { + "$ref": "#/components/schemas/cm.xr-network.node.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + }, + "discoveredTime": { + "$ref": "#/components/schemas/xr.discovered.neighbor.discoveredTime" + }, + "module": { + "$ref": "#/components/schemas/cm.xr-network.node.state.module" + }, + "endpoints": { + "$ref": "#/components/schemas/cm.xr-network.node.state.endpoints" + } + } + }, + "cm.xr-network.node.state.module": { + "description": "Definition of constellation hub and leaf module state parameters", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/xr.device.di" + }, + "moduleName": { + "$ref": "#/components/schemas/xr.device.n" + }, + "macAddress": { + "$ref": "#/components/schemas/xr.platform.macAddress" + }, + "serialNumber": { + "$ref": "#/components/schemas/xr.platform.mnsel" + }, + "configuredRole": { + "$ref": "#/components/schemas/xr.configuration.configuredRole" + }, + "currentRole": { + "$ref": "#/components/schemas/xr.configuration.currentRole" + }, + "roleStatus": { + "$ref": "#/components/schemas/xr.configuration.roleStatus" + }, + "trafficMode": { + "$ref": "#/components/schemas/xr.configuration.trafficMode" + }, + "fiberConnectionMode": { + "$ref": "#/components/schemas/xr.configuration.fiberConnectionMode" + }, + "frequencyCtrl": { + "$ref": "#/components/schemas/xr.carrier.frequencyCtrl" + }, + "constellationFrequency": { + "$ref": "#/components/schemas/xr.carrier.constellationFrequency" + }, + "operatingFrequency": { + "$ref": "#/components/schemas/xr.carrier.operatingFrequency" + }, + "ncoFrequency": { + "$ref": "#/components/schemas/xr.carrier.ncoFrequency" + }, + "modulation": { + "$ref": "#/components/schemas/xr.carrier.modulation" + }, + "capacity": { + "$ref": "#/components/schemas/xr.carrier.capacity" + }, + "clientPortMode": { + "$ref": "#/components/schemas/xr.carrier.clientPortMode" + }, + "baudRate": { + "$ref": "#/components/schemas/xr.carrier.baudRate" + }, + "maxAllowedDSCs": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.maxAllowedDSCs" + }, + "txPowerTargetPerDsc": { + "$ref": "#/components/schemas/xr.carrier.txPowerTargetPerDsc" + } + }, + "type": "object" + }, + "cm.xr-network.node.state.endpoint": { + "description": "Result of module association", + "properties": { + "hostPort": { + "$ref": "#/components/schemas/cm.interface.hostPort" + }, + "moduleIf": { + "$ref": "#/components/schemas/cm.xr-network.node.state.endpoint.moduleIf" + } + }, + "type": "object" + }, + "cm.xr-network.node.state.endpoint.moduleIf": { + "description": "Definition of selector", + "properties": { + "clientIfColId": { + "$ref": "#/components/schemas/xr.ethernet.colId" + }, + "clientIfAid": { + "$ref": "#/components/schemas/xr.ethernet.aid" + }, + "clientIfPortSpeed": { + "$ref": "#/components/schemas/xr.ethernet.portSpeed" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleIf" + } + }, + "cm.xr-network.node.state.endpoints": { + "description": "List of module client interfaces", + "items": { + "$ref": "#/components/schemas/cm.xr-network.node.state.endpoint" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "endpoints" + } + }, + "cm.xr-network.node.module.parameters.trafficMode": { + "description": "Possible Values:\n- L1Mode: Allows transparent transport of client traffic between XR hub and leaf module client ports\n- VTIMode: Allows transport of VLAN flows between an XR hub module client port to 1 or more XR leaf module client ports\n", + "enum": [ + "L1Mode", + "VTIMode" + ], + "title": "Traffic Mode", + "type": "string", + "x-enum-varnames": [ + "L1 mode", + "VTI mode" + ], + "x-oapi-codegen-extra-tags": { + "bson": "trafficMode" + } + }, + "cm.xr-network.node.module.parameters.fiberConnectionMode": { + "description": "Possible Values:\n- single: only one fiber is connected for by-directional traffic\n- dual: separate fibers for transmit and receive\n", + "enum": [ + "single", + "dual" + ], + "title": "Fiber Mode", + "type": "string", + "x-enum-varnames": [ + "Single", + "Dual" + ], + "x-oapi-codegen-extra-tags": { + "bson": "fiberConnectionMode" + } + }, + "cm.xr-network.node.module.parameters.maxAllowedDSCs": { + "description": "Number of digital subcarriers allowed to be used", + "enum": [ + 2, + 4, + 8, + 16 + ], + "title": "Max DSCs", + "type": "integer", + "x-enum-varnames": [ + "2", + "4", + "8", + "16" + ], + "x-oapi-codegen-extra-tags": { + "bson": "maxAllowedDSCs" + } + }, + "cm.xr-network.node.module.parameters.txPowerTargetPerDsc": { + "default": -100, + "description": "Target power per DSC.\nApplicable for all DSCs on the Carrier.\nValue \"-100 us\" used for \"Not configured\".\n", + "format": "double", + "maximum": 0, + "minimum": -100, + "multipleOf": 0.1, + "title": "Target power per DSC", + "type": "number", + "x-unit": "dBm", + "x-oapi-codegen-extra-tags": { + "bson": "txPowerTargetPerDsc" + } + }, + "cm.xr-network.node.parameters.lifecycleState": { + "description": "Provides the configuration status of a node within a network.\nPossible values:\n- 'pendingConfiguration': This state occurs when the module xr-network configuration is required.\n- 'configured': This state occurs when the module is configured in the network according to its xr-network requirements.\n- 'configurationFailed': This state occurs when the module xr-network configuration failed or timeout.\n- 'pendingDeletion': This state occurs when the module shall be removed from the current xr-network.\n- 'deletionFailed': This state occurs when the configuration to remove the module from the xr-network failed or timeout.\n- 'networkConflict': The current module configuration does not match the request or was already a member of other existing xr-network.\n- 'deleted': This state occurs when the current module is removed from the xr-network.\n", + "enum": [ + "pendingConfiguration", + "configured", + "configurationFailed", + "pendingDeletion", + "deletionFailed", + "networkConflict", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleState" + } + }, + "cm.xr-network.node.create": { + "additionalProperties": false, + "description": "Definition of constellation hub and leaf module creation parameters", + "properties": { + "selector": { + "$ref": "#/components/schemas/cm.selectors.moduleSelector" + }, + "module": { + "$ref": "#/components/schemas/cm.xr-network.node.module.create" + } + }, + "required": [ + "module", + "selector" + ], + "type": "object" + }, + "cm.xr-network.node.module.create": { + "additionalProperties": false, + "description": "Definition of constellation hub and leaf module creation parameters", + "properties": { + "trafficMode": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.trafficMode" + }, + "fiberConnectionMode": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.fiberConnectionMode" + }, + "maxAllowedDSCs": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.maxAllowedDSCs" + }, + "txPowerTargetPerDsc": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.txPowerTargetPerDsc" + } + }, + "required": [ + "trafficMode" + ], + "type": "object" + }, + "cm.xr-network.node.update": { + "properties": { + "module": { + "$ref": "#/components/schemas/cm.xr-network.node.module.update" + } + } + }, + "cm.xr-network.node.module.update": { + "additionalProperties": false, + "description": "Definition of constellation hub and leaf module editable parameters", + "minProperties": 1, + "properties": { + "trafficMode": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.trafficMode" + }, + "fiberConnectionMode": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.fiberConnectionMode" + }, + "maxAllowedDSCs": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.maxAllowedDSCs" + }, + "txPowerTargetPerDsc": { + "$ref": "#/components/schemas/cm.xr-network.node.module.parameters.txPowerTargetPerDsc" + } + }, + "type": "object" + }, + "cm.transport-capacity": { + "description": "Definition of transport-capacity object", + "example": { + "href": "/transport-capacities/6ce3aa86-2685-44b0-9f86-49e6a6c991a8", + "rt": [ + "cm.transport-capacity" + ], + "id": "6ce3aa86-2685-44b0-9f86-49e6a6c991a8", + "config": { + "name": "Transport capacity service example", + "capacityMode": "dedicatedDownlinkSymmetric" + }, + "state": { + "name": "Transport capacity service example", + "capacityMode": "dedicatedDownlinkSymmetric", + "lifecycleState": "configured", + "labels": [] + }, + "endpoints": [ + { + "href": "/transport-capacities/6ce3aa86-2685-44b0-9f86-49e6a6c991a8/endpoints/4511bc3d-617b-4757-9f4c-41bc7d8912eb", + "rt": [ + "cm.transport-capacity.hub" + ], + "id": "4511bc3d-617b-4757-9f4c-41bc7d8912eb", + "parentId": "6ce3aa86-2685-44b0-9f86-49e6a6c991a8", + "config": { + "capacity": 100, + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/1:2" + } + } + }, + "state": { + "capacity": 100, + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "da:3d:c2:4c:55:40", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:00", + "moduleSerialNumber": "12345678900", + "moduleCurrentRole": "hub", + "moduleClientIfColId": 1, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + }, + "lifecycleState": "configured", + "labels": [] + } + }, + { + "href": "/transport-capacities/6ce3aa86-2685-44b0-9f86-49e6a6c991a8/endpoints/35e92b25-a682-4805-964a-6ce893a7aa56", + "rt": [ + "cm.transport-capacity.leaf" + ], + "id": "35e92b25-a682-4805-964a-6ce893a7aa56", + "parentId": "6ce3aa86-2685-44b0-9f86-49e6a6c991a8", + "config": { + "capacity": 100, + "selector": { + "hostPortSelector": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:99:F8:2c:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0" + } + } + }, + "state": { + "capacity": 100, + "hostPort": { + "chassisIdSubtype": "macAddress", + "chassisId": "00:99:F8:2c:01:01", + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "da:3d:c2:4c:55:40", + "portDescr": "et-1/0/0:0" + }, + "moduleIf": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "moduleName": "XR Device", + "moduleMAC": "46:00:84:A0:0C:02", + "moduleSerialNumber": "12345678902", + "moduleCurrentRole": "Leaf", + "moduleClientIfColId": 2, + "moduleClientIfAid": "XR T1", + "moduleClientIfPortSpeed": 100 + }, + "lifecycleState": "configured", + "labels": [] + } + } + ], + "capacity-links": [ + { + "href": "/capacity-links/d9580972-7a72-43e7-91d9-5473251040ca", + "rt": [ + "cm.capacity-link" + ], + "id": "d9580972-7a72-43e7-91d9-5473251040ca", + "parentId": "6ce3aa86-2685-44b0-9f86-49e6a6c991a8", + "config": { + "directionality": "biDir", + "hubModule": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "dscgShared": false, + "dscs": [ + 7, + 5, + 3, + 1 + ] + }, + "leafModule": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "dscgShared": false, + "dscs": [ + 3, + 1, + 2, + 4 + ] + } + }, + "state": { + "directionality": "biDir", + "hubModule": { + "moduleId": "18e47620-8848-4c7e-710f-05c668478c57", + "dscgId": "552d4e35-c7fc-4fdf-bb31-1688f926582e", + "dscgShared": false, + "dscs": [ + 7, + 5, + 3, + 1 + ], + "lifecycleState": "configured" + }, + "leafModule": { + "moduleId": "23ffd75e-1a30-11ec-9621-0242ac130002", + "dscgId": "831884a0-fac7-4f1a-8c0d-74f82498921c", + "dscgShared": false, + "dscs": [ + 3, + 1, + 2, + 4 + ], + "lifecycleState": "configured" + } + } + } + ] + }, + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.transport-capacity.config" + }, + "state": { + "$ref": "#/components/schemas/cm.transport-capacity.state" + }, + "endpoints": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoints" + }, + "capacityLinks": { + "$ref": "#/components/schemas/cm.capacity-links" + } + }, + "type": "object" + }, + "cm.transport-capacity.config": { + "additionalProperties": false, + "description": "Definition of transport-capacity configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "capacityMode": { + "$ref": "#/components/schemas/cm.transport-capacity.parameters.capacityMode" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.transport-capacity.state": { + "description": "Definition of transport-capacity state parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "createdBy": { + "$ref": "#/components/schemas/cm.transport-capacity.parameters.createdBy" + }, + "capacityMode": { + "$ref": "#/components/schemas/cm.transport-capacity.parameters.capacityMode" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.transport-capacity.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.transport-capacity.parameters.createdBy": { + "description": "Indicates whether transport-capacity orchestration should be done through CM interface or through Host interface\nPossible values: 'host', 'cm'\n- 'host': Created through host interface and discovered by CM\n Cannot be edited or deleted through CM interface\n- 'cm': Created through CM interface\n Can be edited or deleted through CM interface\n", + "enum": [ + "host", + "cm" + ], + "readOnly": true, + "title": "Created by", + "type": "string", + "x-enum-varnames": [ + "Host", + "IPM" + ], + "x-oapi-codegen-extra-tags": { + "bson": "createdBy" + } + }, + "cm.transport-capacity.parameters.capacityMode": { + "description": "Defines the traffic characteristics of the transport capacity service.\nPossible values:\n- 'portMode': Provides transparent transport between XR hub and leaf modules\n- 'dedicatedDownlinkSymmetric': VLAN based P2P bidirectional flow between Hub and a Leaf modules with symmetric upstream and downstream bandwidths.\n- 'dedicatedDownlinkAsymmetric': VLAN based P2P bidirectional flow between Hub and a Leaf modules with asymmetric upstream and downstream bandwidths.\n- 'sharedDownlink': VLAN based bidirectional flow between Hub and Leaf modules where downstream traffic (hub to leaf) can be shared by multiple Leaf modules (as in a P2MP).\n", + "enum": [ + "portMode", + "dedicatedDownlinkSymmetric", + "dedicatedDownlinkAsymmetric", + "sharedDownlink" + ], + "readOnly": true, + "title": "Capacity Mode", + "type": "string", + "x-enum-varnames": [ + "Port mode", + "Dedicated downlink Symmetric", + "Dedicated downlink asymmetric", + "Shared downlink" + ], + "x-oapi-codegen-extra-tags": { + "bson": "capacityMode" + } + }, + "cm.transport-capacity.parameters.lifecycleState": { + "description": "Provides the configuration status of a transport capacity connection (i.e., the aggregated status of its endpoints).\nPossible values:\n- 'pendingConfiguration': This state occurs when one of the transport capacity connection modules is pending configuration or pending deletion.\n- 'configured': This state occurs when all transport capacity connection modules are configured.\n- 'configurationFailed': This state may occur when at least a configuration of a module from this transport capacity connection failed or timeout.\n- 'pendingDeletion': This state may occur when a request to delete this transport capacity connection is being processed.\n- 'deletionFailed': This state may occur when at least a removal of a module from this transport capacity connection failed or timeout.\n- 'networkConflict': This state may occur when there is a conflict in a transport capacity connection module configuration.\n- 'deleted': This state occurs when a transport capacity connection is removed.\n", + "enum": [ + "pendingConfiguration", + "configured", + "configurationFailed", + "pendingDeletion", + "deletionFailed", + "networkConflict", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending configuration", + "Configured", + "Configuration failed", + "Pending deletion", + "Deletion failed", + "Network conflict", + "Deleted" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleState" + } + }, + "cm.transport-capacity.createRequest": { + "additionalProperties": false, + "description": "Object used in the request body of POST requests in /transport-capacities endpoint.\nContains configuration parameters for transport-capacity and its ednpoint.\n", + "properties": { + "config": { + "$ref": "#/components/schemas/cm.transport-capacity.create" + }, + "endpoints": { + "items": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.create" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + } + }, + "required": [ + "config", + "endpoints" + ], + "type": "object" + }, + "cm.transport-capacity.create": { + "additionalProperties": false, + "description": "Definition of transport-capacity creation parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "capacityMode": { + "$ref": "#/components/schemas/cm.transport-capacity.parameters.capacityMode" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "required": [ + "capacityMode" + ], + "type": "object" + }, + "cm.transport-capacity.update": { + "additionalProperties": false, + "description": "Definition of transport-capacity editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.transport-capacity.endpoint": { + "description": "Definition of transport-capacity endpoint object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "config": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.config" + }, + "state": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.state" + } + } + }, + "cm.transport-capacity.endpoints": { + "items": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "endpoints" + } + }, + "cm.transport-capacity.endpoint.config": { + "additionalProperties": false, + "description": "Definition of transport-capacity endpoint configurable parameters", + "properties": { + "capacity": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.parameters.capacity" + }, + "selector": { + "$ref": "#/components/schemas/cm.selectors.ifSelector" + } + }, + "type": "object" + }, + "cm.transport-capacity.endpoint.state": { + "description": "Definition of transport-capacity endpoint state parameters", + "properties": { + "capacity": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.parameters.capacity" + }, + "hostPort": { + "$ref": "#/components/schemas/cm.interface.hostPort" + }, + "moduleIf": { + "$ref": "#/components/schemas/cm.interface.moduleIf" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + } + }, + "type": "object" + }, + "cm.transport-capacity.endpoint.parameters.capacity": { + "description": "Client to network capacity of the infrastructure connection dscg", + "title": "Upstream bandwidth", + "type": "integer", + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "capacity" + } + }, + "cm.transport-capacity.endpoint.parameters.lifecycleState": { + "description": "Provides the configuration status of a transport capacity endpoint.\nPossible values: \n- 'pendingConfiguration': This state occurs when the module transport capacity connection configuration is required.\n- 'configured': This state occurs when the module is configured in the network according to its transport capacity connection requirements.\n- 'configurationFailed': This state occurs when the module transport capacity connection configuration failed or timeout.\n- 'pendingDeletion': This state occurs when the module shall be removed from the current transport capacity connection.\n- 'deletionFailed': This state occurs when the configuration to remove the module from the transport capacity connection failed or timeout.\n- 'networkConflict': The current module is configured changed and no longer matches the transport capacity connection requirements.\n- 'deleted': This state occurs when the current module is removed from the xr-network.\n", + "enum": [ + "pendingConfiguration", + "configured", + "configurationFailed", + "pendingDeletion", + "deletionFailed", + "networkConflict", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending configuration", + "Configured", + "Configuration failed", + "Pending deletion", + "Deletion failed", + "Network conflict", + "Deleted" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleState" + } + }, + "cm.transport-capacity.endpoint.create": { + "additionalProperties": false, + "description": "Definition of transport-capacity endpoint creation parameters", + "properties": { + "capacity": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.parameters.capacity" + }, + "selector": { + "$ref": "#/components/schemas/cm.selectors.ifSelector" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "cm.transport-capacity.endpoint.update": { + "additionalProperties": false, + "description": "Definition of transport-capacity endpoint editable parameters", + "minProperties": 1, + "properties": { + "capacity": { + "$ref": "#/components/schemas/cm.transport-capacity.endpoint.parameters.capacity" + } + }, + "required": [ + "capacity" + ], + "type": "object" + }, + "cm.capacity-link": { + "description": "Definition of capacity-link object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "config": { + "$ref": "#/components/schemas/cm.capacity-link.config" + }, + "state": { + "$ref": "#/components/schemas/cm.capacity-link.state" + } + }, + "type": "object" + }, + "cm.capacity-links": { + "items": { + "$ref": "#/components/schemas/cm.capacity-link" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "capacityLinks" + } + }, + "cm.capacity-link.config": { + "additionalProperties": false, + "description": "Definition of capacity-link configurable parameters", + "properties": { + "directionality": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.directionality" + }, + "hubModule": { + "$ref": "#/components/schemas/cm.capacity-link.config.node" + }, + "leafModule": { + "$ref": "#/components/schemas/cm.capacity-link.config.node" + } + }, + "type": "object" + }, + "cm.capacity-link.config.node": { + "additionalProperties": false, + "description": "Definition of capacity-link hub module configurable parameters.", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.moduleId" + }, + "dscgShared": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.dscgShared" + }, + "txDSCs": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.txDSCs" + }, + "rxDSCs": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.rxDSCs" + } + }, + "required": [ + "dscgMode", + "dscs", + "moduleId" + ], + "type": "object" + }, + "cm.capacity-link.state": { + "description": "Definition of capacity-link state parameters", + "properties": { + "directionality": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.directionality" + }, + "hubModule": { + "$ref": "#/components/schemas/cm.capacity-link.state.hubModule" + }, + "leafModule": { + "$ref": "#/components/schemas/cm.capacity-link.state.leafModule" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + } + }, + "type": "object" + }, + "cm.capacity-link.state.hubModule": { + "additionalProperties": false, + "description": "Definition of capacity-link hub module state parameters.", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/xr.device.di" + }, + "dscgId": { + "$ref": "#/components/schemas/xr.carrier.dscg.id" + }, + "dscgAid": { + "$ref": "#/components/schemas/xr.carrier.dscg.aid" + }, + "dscgShared": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.dscgShared" + }, + "txDSCs": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.txDSCs" + }, + "rxDSCs": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.rxDSCs" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hubModule" + } + }, + "cm.capacity-link.state.leafModule": { + "additionalProperties": false, + "description": "Definition of capacity-link leaf module state parameters.", + "properties": { + "moduleId": { + "$ref": "#/components/schemas/xr.device.di" + }, + "dscgId": { + "$ref": "#/components/schemas/xr.carrier.dscg.id" + }, + "dscgAid": { + "$ref": "#/components/schemas/xr.carrier.dscg.aid" + }, + "dscgShared": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.dscgShared" + }, + "txDSCs": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.txDSCs" + }, + "rxDSCs": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.rxDSCs" + }, + "lifecycleState": { + "$ref": "#/components/schemas/cm.capacity-link.parameters.lifecycleState" + }, + "lifecycleStateCause": { + "$ref": "#/components/schemas/cm.parameters.lifecycleStateCause" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "leafModule" + } + }, + "cm.capacity-link.parameters.moduleId": { + "description": "Module identifier", + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "title": "ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "moduleId" + } + }, + "cm.capacity-link.parameters.directionality": { + "description": "Directionality of the capacity-link. \nuniDirUs: Refers to upstream direction from Leaf to Hub. \nuniDirDs: Refers to downstream traffic direction from Hub to Leaf.\n", + "enum": [ + "biDir", + "uniDirUs", + "uniDirDs" + ], + "title": "Directionality", + "type": "string", + "x-enum-varnames": [ + "Bidirectional", + "Unidirectional upstream", + "Unidirectional downstream" + ], + "x-oapi-codegen-extra-tags": { + "bson": "directionality" + } + }, + "cm.capacity-link.parameters.lifecycleState": { + "description": "Provides the configuration status of a capacity-link.\nPossible values:\n- 'pendingConfiguration': This state occurs when the hub or leaf module of the transport capacity connection is pending its DSCG configuration.\n- 'configured': This state occurs when there are matching DSCG configurations in the hub and leaf modules.\n- 'configurationFailed': This state may occur when the hub or leaf module DSCG configurations failed or timeout.\n- 'pendingDeletion': This state may occur when a request to delete a capacity-link is being processed.\n- 'deletionFailed': This state may occur when the configuration to remove a DSCG from the hub or leaf module failed or timeout.\n- 'networkConflict': This state may occur when there is a conflict in the hub or leaf module DSCG configurations.\n- 'deleted': This state occurs when a capacity-link is removed.\n", + "enum": [ + "pendingConfiguration", + "configured", + "configurationFailed", + "pendingDeletion", + "deletionFailed", + "networkConflict", + "deleted" + ], + "readOnly": true, + "title": "Lifecycle State", + "type": "string", + "x-enum-varnames": [ + "Pending configuration", + "Configured", + "Configuration failed", + "Pending deletion", + "Deletion failed", + "Network conflict", + "Deleted" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lifecycleState" + } + }, + "cm.capacity-link.parameters.dscgShared": { + "description": "Indicates whether the dscg can be shared by multiple transport-capacity connection.\n'True' option is only applicable to hub module unidirectional downstream DSCGs\n", + "title": "Shared", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "dscgShared" + } + }, + "cm.capacity-link.parameters.txDSCs": { + "items": { + "type": "integer" + }, + "maxItems": 16, + "minItems": 0, + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "txDSCs" + } + }, + "cm.capacity-link.parameters.rxDSCs": { + "items": { + "type": "integer" + }, + "maxItems": 16, + "minItems": 0, + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "rxDSCs" + } + }, + "xr.controlplane.neighbor.sourceModuleId": { + "description": "Represents the source module device identifier of control-link.", + "readOnly": true, + "title": "Device identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "sourceModuleId" + } + }, + "xr.controlplane.neighbor.destinationModuleId": { + "description": "Represents the destimation module device identifier of control-link.", + "readOnly": true, + "title": "Device identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "destinationModuleId" + } + }, + "cm.selectors.moduleSelector": { + "description": "Definition of the parameters provided upon host creation used as matching criteria for discovered hosts", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "moduleSelectorByModuleId": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleId" + }, + "moduleSelectorByModuleName": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleName" + }, + "moduleSelectorByModuleMAC": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleMAC" + }, + "moduleSelectorByModuleSerialNumber": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleSerialNumber" + }, + "hostPortSelectorByName": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorByName" + }, + "hostPortSelectorByPortId": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorByPortId" + }, + "hostPortSelectorBySysName": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorBySysName" + }, + "hostPortSelectorByPortSourceMAC": { + "$ref": "#/components/schemas/cm.selector.hostPortSelectorByPortSourceMAC" + } + }, + "title": "Host Selector", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "selector" + } + }, + "cm.selector.moduleSelectorByModuleId": { + "additionalProperties": false, + "description": "Definition of module selector based on module Id information", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "moduleId": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleId" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleSelectorByModuleId" + } + }, + "cm.selector.moduleSelectorByModuleName": { + "additionalProperties": false, + "description": "Definition of port selector based on module aid information", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "moduleName": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleName" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleSelectorByModuleName" + } + }, + "cm.selector.moduleSelectorByModuleMAC": { + "additionalProperties": false, + "description": "Definition of module selector based on mac address information", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "moduleMAC": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleMAC" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleSelectorByModuleMAC" + } + }, + "cm.selector.moduleSelectorByModuleSerialNumber": { + "additionalProperties": false, + "description": "Definition of module selector based on module serial number information", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "moduleSerialNumber": { + "$ref": "#/components/schemas/cm.selector.moduleSelector.parameters.moduleSerialNumber" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "moduleSelectorByModuleSerialNumber" + } + }, + "xr.carrier.dscg.id": { + "description": "DSCG Object identifier", + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "readOnly": true, + "title": "DSCG ID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "dscgId" + } + }, + "cm.subscription": { + "description": "Subscription data", + "properties": { + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "subscriptionId": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionId" + }, + "subscriptionName": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionName" + }, + "notificationChannel": { + "$ref": "#/components/schemas/cm.subscription.notificationChannel" + }, + "subscriptionFilters": { + "$ref": "#/components/schemas/cm.subscription.subscriptionFilters" + }, + "conState": { + "$ref": "#/components/schemas/cm.subscription.parameters.conState" + }, + "lastConnectionTime": { + "$ref": "#/components/schemas/cm.subscription.parameters.lastConnectionTime" + } + }, + "title": "Subscription", + "type": "object" + }, + "cm.subscription.notificationChannel": { + "description": "Definition of subscription notification-channel", + "properties": { + "streamAddress": { + "$ref": "#/components/schemas/cm.subscription.parameters.notificationChannel.streamAddress" + } + }, + "title": "Notification Channel", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "notificationChannel" + } + }, + "cm.subscription.subscriptionFilters": { + "description": "List of subscription-filters", + "items": { + "$ref": "#/components/schemas/cm.subscription.subscriptionFilter" + }, + "minItems": 1, + "title": "Subscription Filters", + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "subscriptionFilters" + } + }, + "cm.subscription.subscriptionFilter": { + "description": "Definition of subscription-filters", + "properties": { + "requestedNotificationTypes": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionFilter.requestedNotificationTypes" + }, + "requestedResources": { + "$ref": "#/components/schemas/cm.subscription.subscriptionFilter.requestedResources" + } + }, + "title": "Subscription Filter", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "subscriptionFilter" + } + }, + "cm.subscription.subscriptionFilter.requestedResources": { + "description": "Required resource types to be available in the notification channel with optional filter by resource ids and/or moduleIds", + "items": { + "$ref": "#/components/schemas/cm_subscription_subscriptionFilter_requestedResources_inner" + }, + "minItems": 1, + "title": "Resource Types", + "type": "array", + "uniqueItems": true + }, + "cm.subscription.parameters.subscriptionId": { + "description": "Universally unique identifier (UUID) of a subscription.", + "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$", + "readOnly": true, + "title": "UUID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "subscriptionId" + } + }, + "cm.subscription.parameters.subscriptionName": { + "description": "User defined subscription name.", + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "subscriptionName" + } + }, + "cm.subscription.parameters.conState": { + "description": "Shows if the subscription is currently active or not", + "enum": [ + "active", + "inactive" + ], + "readOnly": true, + "title": "Connection Status", + "type": "string", + "x-enum-varnames": [ + "Active", + "Inactive" + ], + "x-oapi-codegen-extra-tags": { + "bson": "conState" + } + }, + "cm.subscription.parameters.lastConnectionTime": { + "description": "Timestamp of last connectivity in date-time format pattern according to IETF RFC 3339.\nIf subscription is inactive, this timestamp shows when connectivity was lost.\nIf subscription is active this timestamp shows when connection was established.\n", + "format": "date-time", + "readOnly": true, + "title": "Connection Time", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lastConnectionTime" + } + }, + "cm.subscription.parameters.notificationChannel.streamAddress": { + "description": "WebSocket URI made available upon subscription creation", + "readOnly": true, + "title": "WebSocket URI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "streamAddress" + } + }, + "cm.subscription.parameters.subscriptionFilter.requestedNotificationTypes": { + "description": "Required notification types to be available in the notification channel\n- OC: Object Creation\n- OD: Object Deletion\n- AVC: Attribute Value Change\n- ERROR: Error notifications\n", + "items": { + "enum": [ + "OC", + "OD", + "AVC", + "Error" + ], + "type": "string", + "x-enum-varnames": [ + "OC", + "OD", + "AVC", + "Error" + ] + }, + "minItems": 1, + "title": "Notification Types", + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "requestedNotificationTypes" + } + }, + "cm.subscription.parameters.subscriptionFilter.requestedResources.resourceType": { + "description": "Required resource types to be available in the notification channel\nResource types are identified by the 'rt' link in the resource object\n", + "enum": [ + "cm.device", + "cm.host", + "cm.host.port", + "cm.module", + "cm.module.linePtp", + "cm.module.linePtp.carrier", + "cm.module.linePtp.carrier.dscg", + "cm.module.linePtp.carrier.dsc", + "cm.module.otu", + "cm.module.odu", + "cm.module.ethernetClient", + "cm.module.localConnection", + "cm.transport-capacity", + "cm.transport-capacity.endpoint", + "cm.capacity-link", + "cm.network-connection", + "cm.network-connection.endpoint", + "cm.network-connection.local-connection", + "cm.xr-network", + "cm.xr-network.hubModule", + "cm.xr-network.leafModule", + "cm.xr-network.reachableModule", + "cm.sw.action", + "cm.sw.moduleAction", + "cm.sw.ctrl", + "cm.sw.bank" + ], + "title": "Resource Type", + "type": "string", + "x-enum-varnames": [ + "cm.device", + "cm.host", + "cm.host.port", + "cm.module", + "cm.module.linePtp", + "cm.module.linePtp.carrier", + "cm.module.linePtp.carrier.dscg", + "cm.module.linePtp.carrier.dsc", + "cm.module.otu", + "cm.module.odu", + "cm.module.ethernetClient", + "cm.module.localConnection", + "cm.transport-capacity", + "cm.transport-capacity.endpoint", + "cm.capacity-link", + "cm.network-connection", + "cm.network-connection.endpoint", + "cm.network-connection.local-connection", + "cm.xr-network", + "cm.xr-network.hubModule", + "cm.xr-network.leafModule", + "cm.xr-network.reachableModule", + "cm.sw.action", + "cm.sw.moduleAction", + "cm.sw.ctrl", + "cm.sw.bank" + ], + "x-oapi-codegen-extra-tags": { + "bson": "resourceType" + } + }, + "cm.subscription.parameters.subscriptionFilter.requestedResources.ids": { + "description": "Required resource ids (with type defined in resourceType) to be available in the notification channel", + "items": { + "type": "string" + }, + "minItems": 1, + "title": "Resource Ids", + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "ids" + } + }, + "cm.subscription.parameters.subscriptionFilter.requestedResources.moduleIds": { + "description": "Required device ids (di property) within the defined resourceType (i.e. resource type containing the device ids) to be available in the notification channel", + "items": { + "type": "string" + }, + "minItems": 1, + "title": "Device Ids", + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "moduleIds" + } + }, + "cm.subscription.parameters.subscriptionFilter.requestedResources.hrefs": { + "description": "Required HREFs to be available in the notification channel.\nNote that this filter definition supports regex.\n", + "items": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "minItems": 1, + "title": "HREFs", + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "hrefs" + } + }, + "cm.subscription.request": { + "additionalProperties": false, + "description": "Subscription creation request body content", + "properties": { + "subscriptionName": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionName" + }, + "subscriptionFilters": { + "items": { + "$ref": "#/components/schemas/cm.subscription.subscriptionFilter" + }, + "minItems": 1, + "type": "array" + } + }, + "title": "Subscription request body content", + "type": "object" + }, + "cm.subscription.response": { + "description": "Subscription creation response body content", + "properties": { + "subscriptionId": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionId" + }, + "notificationChannel": { + "$ref": "#/components/schemas/cm.subscription.notificationChannel" + } + }, + "title": "Subscription response body content", + "type": "object" + }, + "cm_subscription_subscriptionFilter_requestedResources_inner": { + "properties": { + "resourceType": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionFilter.requestedResources.resourceType" + }, + "ids": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionFilter.requestedResources.ids" + }, + "moduleIds": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionFilter.requestedResources.moduleIds" + }, + "hrefs": { + "$ref": "#/components/schemas/cm.subscription.parameters.subscriptionFilter.requestedResources.hrefs" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "requestedResources" + } + }, + "cm.host": { + "description": "Definition of host object", + "example": { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "rt": [ + "cm.host" + ], + "id": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a", + "config": { + "name": "Sunnyvale Router 001", + "managedBy": "CM", + "location": { + "latitude": 20, + "longitude": 134.1 + }, + "selector": { + "hostSelectorByChassisId": { + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "state": { + "name": "Sunnyvale Router 001", + "chassisIdSubtype": "macAddress", + "chassisId": "28:c0:da:3e:3e:40", + "sysName": "Vendor A Router", + "sysDescr": "", + "lldpState": "Present", + "managedBy": "CM", + "location": { + "latitude": 20, + "longitude": 134.1 + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "ports": [ + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/5f8c47b4-c02a-6242-260c-185dd04b8faf", + "rt": [ + "cm.host.port" + ], + "id": "d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/5f8c47b4-c02a-6242-260c-185dd04b8faf", + "config": { + "managedBy": "CM", + "selector": { + "ifSelectorByHostPortSourceMAC": { + "portSourceMAC": "28:c0:da:3e:3e:44" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "state": { + "name": "towards San Jose", + "managedBy": "CM", + "lldpState": "Present", + "hostPort": { + "portIdSubtype": "interfaceName", + "portId": "et-1/0/0:0", + "portSourceMAC": "28:c0:da:3e:3e:44" + }, + "moduleIf": { + "moduleId": "aa079e7c-02df-43ed-636e-71f7bfc212ff", + "moduleName": "Sunnyvale-1/0/0", + "macAddress": "00:0B:F8:00:01:01", + "serialNumber": "12345678901", + "clientIfAid": "XR-T1" + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + } + }, + { + "href": "/hosts/d9672ef1-ddc1-cd6b-3c77-ea86b442545a/ports/4868c57e-0f4f-11ec-82a8-0242ac130003", + "rt": [ + "cm.host.port" + ], + "id": "4868c57e-0f4f-11ec-82a8-0242ac130003", + "config": { + "name": "towards Santa Clara", + "managedBy": "CM", + "selector": { + "ifSelectorByModuleMAC": { + "moduleMAC": "00:0B:F8:00:01:01", + "clientIfAid": "XR-T1" + } + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + }, + "state": { + "name": "towards Santa Clara", + "managedBy": "Host", + "lldpState": "Present", + "hostPort": { + "portIdSubtype": "interfaceName", + "portId": "et-1/0/2:0", + "portSourceMAC": "58:00:BB:00:00:12" + }, + "moduleIf": { + "moduleId": "4e58f211-oa575-41ae-65d6-54fbeba5a2fe", + "moduleName": "Sunnyvale-1/0/2", + "macAddress": "00:0B:F8:00:01:01", + "serialNumber": "12345678901", + "clientIfAid": "XR-T2" + }, + "labels": { + "region": "West Coast", + "city": "Sunnyvale" + } + } + } + ] + }, + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.host.config" + }, + "state": { + "$ref": "#/components/schemas/cm.host.state" + }, + "ports": { + "$ref": "#/components/schemas/cm.host.ports" + } + } + }, + "cm.host.config": { + "additionalProperties": false, + "description": "Configurable host parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "location": { + "$ref": "#/components/schemas/cm.parameters.location" + }, + "selector": { + "$ref": "#/components/schemas/cm.selectors.hostSelector" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.host.state": { + "description": "Definition of host state parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "chassisIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisIdSubtype" + }, + "chassisId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisId" + }, + "sysName": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysName" + }, + "sysDescr": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysDescr" + }, + "lldpState": { + "$ref": "#/components/schemas/cm.host.parameters.lldpState" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "location": { + "$ref": "#/components/schemas/cm.parameters.location" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.host.parameters.lldpState": { + "description": "Represents the consolidated LLDP state of the XR modules in the host.\nPossible Values:\n- 'Pending': Applicable for pre-planned scenarios when the host port is not yet discovered from an XR module or there is no XR module associated to the host.\n- 'NotPresent': Applicable when the XR module is not reporting host LLDP information.\n- 'Present': Applicable when the XR module is reporting host LLDP information.\n- 'Unknown': Applicable when the XR module is in 'Offline' state\nNote that the information presented for hosts with 'Unknown' state refers to the last known host information.\n", + "enum": [ + "Pending", + "Present", + "Unknown", + "NotPresent" + ], + "readOnly": true, + "title": "State", + "type": "string", + "x-enum-varnames": [ + "Pending", + "Present", + "Unknown", + "Not present" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lldpState" + } + }, + "cm.host.parameters.managedBy": { + "description": "Defines the ownership of the object.\nPossible values: 'Host', 'CM'\n- Host: Applicable to discovered objects that are automaticcaly created / deleted based on Host reported information.\n- CM: Applicable to pre-planned objects or objects with exising depondencies (e.g. host ports used in a service with the respective host selector).\n", + "enum": [ + "Host", + "CM" + ], + "title": "Managed by", + "type": "string", + "x-enum-varnames": [ + "Host", + "CM" + ], + "x-oapi-codegen-extra-tags": { + "bson": "managedBy" + } + }, + "cm.host.create": { + "additionalProperties": false, + "description": "Host creation parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "location": { + "$ref": "#/components/schemas/cm.parameters.location" + }, + "selector": { + "$ref": "#/components/schemas/cm.selectors.hostSelector" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "cm.host.update": { + "additionalProperties": false, + "description": "Editable host parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "location": { + "$ref": "#/components/schemas/cm.parameters.location" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.host.port": { + "description": "Definition of host port object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "config": { + "$ref": "#/components/schemas/cm.host.port.config" + }, + "state": { + "$ref": "#/components/schemas/cm.host.port.state" + } + } + }, + "cm.host.ports": { + "description": "List of host ports", + "items": { + "$ref": "#/components/schemas/cm.host.port" + }, + "type": "array" + }, + "cm.host.port.config": { + "additionalProperties": false, + "description": "Definition of host port configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "selector": { + "$ref": "#/components/schemas/cm.selectors.ifSelector" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.host.port.state": { + "description": "Definition of host port state object", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "hostName": { + "$ref": "#/components/schemas/cm.parameters.hostName" + }, + "chassisIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisIdSubtype" + }, + "chassisId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.chassisId" + }, + "sysName": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.sysName" + }, + "portIdSubtype": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portIdSubtype" + }, + "portId": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portId" + }, + "portSourceMAC": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.localPortSourceMAC" + }, + "portDescr": { + "$ref": "#/components/schemas/xr.ethernet.neighbor.portDescr" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "lldpState": { + "$ref": "#/components/schemas/cm.host.port.parameters.lldpState" + }, + "moduleIf": { + "$ref": "#/components/schemas/cm.interface.moduleIf" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.host.port.parameters.lldpState": { + "description": "Represents the consolidated LLDP state of the XR modules in the host.\nPossible Values:\n- Pending: Applicable for pre-planned scenarios when the host port is not yet discovered from an XR module\n- NotPresent: Applicable when the XR module is not reporting host LLDP information.\n- Present: Applicable when the XR module is reporting host LLDP information.\n- Unknown: Applicable when the XR module is in 'Offline' state or there is no XR module associated to the host.\nNote that the information presented for hosts with 'Unknown' state refers to the last known host information.\n", + "enum": [ + "Pending", + "Present", + "Unknown", + "NotPresent" + ], + "readOnly": true, + "title": "State", + "type": "string", + "x-enum-varnames": [ + "Pending", + "Present", + "Unknown", + "Not present" + ], + "x-oapi-codegen-extra-tags": { + "bson": "lldpState" + } + }, + "cm.host.port.create": { + "additionalProperties": false, + "description": "Host port creation parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "selector": { + "$ref": "#/components/schemas/cm.selectors.ifSelector" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "cm.host.port.update": { + "additionalProperties": false, + "description": "Definition of host port editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.parameters.name" + }, + "managedBy": { + "$ref": "#/components/schemas/cm.host.parameters.managedBy" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.parameters.location": { + "description": "Geographic coordinates in decimal degree.\n", + "properties": { + "latitude": { + "format": "double", + "maximum": 90, + "minimum": -90, + "title": "Latitude", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "latitude" + } + }, + "longitude": { + "format": "double", + "maximum": 180, + "minimum": -180, + "title": "Longitude", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "longitude" + } + } + }, + "title": "Location", + "type": "object" + }, + "cm.selectors.hostSelector": { + "description": "Definition of the parameters provided upon host creation used as matching criteria for discovered hosts", + "maxProperties": 1, + "minProperties": 1, + "properties": { + "hostSelectorByHostChassisId": { + "$ref": "#/components/schemas/cm.selector.hostSelectorByChassisId" + }, + "moduleSelectorByModuleId": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleId" + }, + "moduleSelectorByModuleName": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleName" + }, + "moduleSelectorByModuleMAC": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleMAC" + }, + "moduleSelectorByModuleSerialNumber": { + "$ref": "#/components/schemas/cm.selector.moduleSelectorByModuleSerialNumber" + } + }, + "title": "Host Selector", + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "selector" + } + }, + "cm.selector.hostSelectorByChassisId": { + "additionalProperties": false, + "description": "Definition of host selector based on chassisId information", + "maxProperties": 2, + "minProperties": 2, + "properties": { + "chassisIdSubtype": { + "$ref": "#/components/schemas/cm.selector.hostSelector.parameters.chassisIdSubtype" + }, + "chassisId": { + "$ref": "#/components/schemas/cm.selector.hostSelector.parameters.chassisId" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "hostSelectorByChassisId" + } + }, + "cm.ndu": { + "description": "Definition of ndu object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.state" + }, + "ports": { + "$ref": "#/components/schemas/cm.ndu.ports" + }, + "linePtps": { + "$ref": "#/components/schemas/cm.ndu.linePtps" + }, + "tribPtps": { + "$ref": "#/components/schemas/cm.ndu.tribPtps" + }, + "otus": { + "$ref": "#/components/schemas/cm.ndu.otus" + }, + "ethernetClients": { + "$ref": "#/components/schemas/cm.ndu.ethernetClients" + }, + "trails": { + "$ref": "#/components/schemas/cm.ndu.trails" + }, + "fans": { + "$ref": "#/components/schemas/cm.ndu.fans" + }, + "pem": { + "$ref": "#/components/schemas/cm.ndu.pem" + }, + "leds": { + "$ref": "#/components/schemas/cm.ndu.leds" + } + } + }, + "cm.ndu.config": { + "additionalProperties": false, + "description": "Definition of module configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/cm.ndu.parameters.name" + }, + "location": { + "$ref": "#/components/schemas/cm.ndu.config.location" + }, + "contact": { + "$ref": "#/components/schemas/ndu.configuration.contact" + }, + "managedBy": { + "$ref": "#/components/schemas/ndu.configuration.mgmtMode" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.ndu.config.location": { + "additionalProperties": false, + "description": "Location parameter", + "minProperties": 1, + "properties": { + "description": { + "$ref": "#/components/schemas/ndu.configuration.neLocation" + }, + "clli": { + "$ref": "#/components/schemas/ndu.configuration.clli" + }, + "latitude": { + "$ref": "#/components/schemas/ndu.configuration.latitude" + }, + "longitude": { + "$ref": "#/components/schemas/ndu.configuration.longitude" + }, + "altitude": { + "$ref": "#/components/schemas/ndu.configuration.altitude" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "location" + } + }, + "cm.ndu.state": { + "description": "Definition of module state object", + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.device.n" + }, + "nduAid": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "location": { + "$ref": "#/components/schemas/cm.ndu.config.location" + }, + "contact": { + "$ref": "#/components/schemas/ndu.configuration.contact" + }, + "managedBy": { + "$ref": "#/components/schemas/ndu.configuration.mgmtMode" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + }, + "connectivityState": { + "$ref": "#/components/schemas/cm.ndu.parameters.connectivityState" + }, + "hwDescription": { + "$ref": "#/components/schemas/cm.ndu.state.hwDescription" + } + } + }, + "cm.ndu.state.hwDescription": { + "description": "Definition of module platform properties", + "properties": { + "pi": { + "$ref": "#/components/schemas/ndu.platform.pi" + }, + "mnfv": { + "$ref": "#/components/schemas/ndu.platform.mnfv" + }, + "mnmn": { + "$ref": "#/components/schemas/ndu.platform.mnmn" + }, + "mnmo": { + "$ref": "#/components/schemas/ndu.platform.mnmo" + }, + "mnhw": { + "$ref": "#/components/schemas/ndu.platform.mnhw" + }, + "mndt": { + "$ref": "#/components/schemas/ndu.platform.mndt" + }, + "serialNumber": { + "$ref": "#/components/schemas/ndu.platform.mnsel" + }, + "clei": { + "$ref": "#/components/schemas/ndu.platform.clei" + }, + "macAddress": { + "$ref": "#/components/schemas/ndu.platform.macAddress" + }, + "piid": { + "$ref": "#/components/schemas/ndu.device.piid" + }, + "dmn": { + "$ref": "#/components/schemas/ndu.device.dmn" + }, + "sv": { + "$ref": "#/components/schemas/ndu.device.sv" + }, + "icv": { + "$ref": "#/components/schemas/ndu.device.icv" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "hwDescription" + } + }, + "cm.ndu.parameters.name": { + "description": "Property to change the NDU name. \nThis is also reflected in the same property in oic.wk.d\n", + "maxLength": 64, + "title": "NDU name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "cm.ndu.parameters.connectivityState": { + "description": "The CM connectivity state between the CM and the device.", + "enum": [ + "active", + "inactive" + ], + "title": "Connectivity state", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "connectivityState" + } + }, + "cm.ndu.update": { + "additionalProperties": false, + "description": "Definition of ndu editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/cm.ndu.parameters.name" + }, + "location": { + "$ref": "#/components/schemas/cm.ndu.config.location" + }, + "contact": { + "$ref": "#/components/schemas/ndu.configuration.contact" + }, + "managedBy": { + "$ref": "#/components/schemas/ndu.configuration.mgmtMode" + }, + "labels": { + "$ref": "#/components/schemas/cm.parameters.labels" + } + }, + "type": "object" + }, + "cm.ndu.port": { + "description": "Definition of NDU port object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.port.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.port.state" + }, + "toms": { + "$ref": "#/components/schemas/cm.ndu.port.toms" + }, + "xrs": { + "$ref": "#/components/schemas/cm.ndu.port.xrs" + }, + "edfas": { + "$ref": "#/components/schemas/cm.ndu.port.edfas" + }, + "voas": { + "$ref": "#/components/schemas/cm.ndu.port.voas" + } + } + }, + "cm.ndu.ports": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "ports" + } + }, + "cm.ndu.port.config": { + "additionalProperties": false, + "description": "Definition of ndu port configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.port.label" + }, + "connectedTo": { + "$ref": "#/components/schemas/ndu.port.connectedTo" + }, + "externalConnectivity": { + "$ref": "#/components/schemas/ndu.port.externalConnectivity" + } + }, + "type": "object" + }, + "cm.ndu.port.state": { + "description": "Definition of ndu port state object", + "properties": { + "portAid": { + "$ref": "#/components/schemas/ndu.port.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.port.parentAid" + }, + "name": { + "$ref": "#/components/schemas/ndu.port.label" + }, + "category": { + "$ref": "#/components/schemas/ndu.port.portType" + }, + "supportedTypes": { + "$ref": "#/components/schemas/ndu.port.supportedType" + }, + "installedType": { + "$ref": "#/components/schemas/ndu.port.installedType" + }, + "connectedTo": { + "$ref": "#/components/schemas/ndu.port.connectedTo" + }, + "externalConnectivity": { + "$ref": "#/components/schemas/ndu.port.externalConnectivity" + } + }, + "type": "object" + }, + "cm.ndu.port.update": { + "additionalProperties": false, + "description": "Definition of ndu port editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.port.label" + }, + "connectedTo": { + "$ref": "#/components/schemas/ndu.port.connectedTo" + }, + "externalConnectivity": { + "$ref": "#/components/schemas/ndu.port.externalConnectivity" + } + }, + "type": "object" + }, + "cm.ndu.port.tom": { + "description": "Definition of NDU TOM object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.port.tom.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.port.tom.state" + } + } + }, + "cm.ndu.port.toms": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.tom" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "toms" + } + }, + "cm.ndu.port.tom.config": { + "additionalProperties": false, + "description": "Definition of ndu TOM configurable parameters", + "properties": { + "requiredType": { + "$ref": "#/components/schemas/ndu.tom.requiredType" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "cm.ndu.port.tom.state": { + "description": "Definition of ndu TOM state object", + "properties": { + "tomAid": { + "$ref": "#/components/schemas/ndu.tom.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.tom.parentAid" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "serDes": { + "items": { + "$ref": "#/components/schemas/ndu.serDesData" + }, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "inventory": { + "$ref": "#/components/schemas/ndu.inventory" + } + }, + "type": "object" + }, + "cm.ndu.port.tom.update": { + "additionalProperties": false, + "description": "Definition of ndu TOM editable parameters", + "minProperties": 1, + "properties": { + "requiredType": { + "$ref": "#/components/schemas/ndu.tom.requiredType" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + } + }, + "type": "object" + }, + "cm.ndu.port.xr": { + "description": "Definition of NDU XR pluggable interface object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.port.xr.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.port.xr.state" + } + } + }, + "cm.ndu.port.xrs": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.xr" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "xrs" + } + }, + "cm.ndu.port.xr.config": { + "additionalProperties": false, + "description": "Definition of ndu XR pluggable interface configurable parameters", + "properties": { + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "cm.ndu.port.xr.state": { + "description": "Definition of ndu XR pluggable interface state object", + "properties": { + "xrAid": { + "$ref": "#/components/schemas/ndu.xr.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.xr.parentAid" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "serDes": { + "items": { + "$ref": "#/components/schemas/ndu.serDesData" + }, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "inventory": { + "$ref": "#/components/schemas/ndu.inventory" + } + }, + "type": "object" + }, + "cm.ndu.port.xr.update": { + "additionalProperties": false, + "description": "Definition of ndu XR pluggable interface editable parameters", + "minProperties": 1, + "properties": { + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + } + }, + "type": "object" + }, + "cm.ndu.port.edfa": { + "description": "Definition of NDU EDFA object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.port.edfa.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.port.edfa.state" + } + } + }, + "cm.ndu.port.edfas": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.edfa" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "edfas" + } + }, + "cm.ndu.port.edfa.config": { + "additionalProperties": false, + "description": "Definition of ndu EDFA configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.edfa.label" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "function": { + "$ref": "#/components/schemas/ndu.edfa.function" + }, + "amplifierEnable": { + "$ref": "#/components/schemas/ndu.edfa.amplifierEnable" + }, + "controlMode": { + "$ref": "#/components/schemas/ndu.edfa.controlMode" + }, + "amplifierMode": { + "$ref": "#/components/schemas/ndu.edfa.amplifierMode" + }, + "gainTarget": { + "$ref": "#/components/schemas/ndu.edfa.gainTarget" + }, + "optimumEdfaGain": { + "$ref": "#/components/schemas/ndu.edfa.optimumEdfaGain" + }, + "inputPowerMon": { + "$ref": "#/components/schemas/ndu.edfa.inputPowerMon" + }, + "outputPowerMon": { + "$ref": "#/components/schemas/ndu.edfa.outputPowerMon" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "cm.ndu.port.edfa.state": { + "description": "Definition of ndu EDFA state object", + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.edfa.label" + }, + "edfaAid": { + "$ref": "#/components/schemas/ndu.edfa.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.edfa.parentAid" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "serDes": { + "items": { + "$ref": "#/components/schemas/ndu.serDesData" + }, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "function": { + "$ref": "#/components/schemas/ndu.edfa.function" + }, + "amplifierEnable": { + "$ref": "#/components/schemas/ndu.edfa.amplifierEnable" + }, + "controlMode": { + "$ref": "#/components/schemas/ndu.edfa.controlMode" + }, + "amplifierMode": { + "$ref": "#/components/schemas/ndu.edfa.amplifierMode" + }, + "gainTarget": { + "$ref": "#/components/schemas/ndu.edfa.gainTarget" + }, + "optimumEdfaGain": { + "$ref": "#/components/schemas/ndu.edfa.optimumEdfaGain" + }, + "inputPowerMon": { + "$ref": "#/components/schemas/ndu.edfa.inputPowerMon" + }, + "outputPowerMon": { + "$ref": "#/components/schemas/ndu.edfa.outputPowerMon" + }, + "inventory": { + "$ref": "#/components/schemas/ndu.inventory" + } + }, + "type": "object" + }, + "cm.ndu.port.edfa.update": { + "additionalProperties": false, + "description": "Definition of ndu EDFA editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.edfa.label" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "function": { + "$ref": "#/components/schemas/ndu.edfa.function" + }, + "amplifierEnable": { + "$ref": "#/components/schemas/ndu.edfa.amplifierEnable" + }, + "controlMode": { + "$ref": "#/components/schemas/ndu.edfa.controlMode" + }, + "amplifierMode": { + "$ref": "#/components/schemas/ndu.edfa.amplifierMode" + }, + "gainTarget": { + "$ref": "#/components/schemas/ndu.edfa.gainTarget" + }, + "optimumEdfaGain": { + "$ref": "#/components/schemas/ndu.edfa.optimumEdfaGain" + }, + "inputPowerMon": { + "$ref": "#/components/schemas/ndu.edfa.inputPowerMon" + }, + "outputPowerMon": { + "$ref": "#/components/schemas/ndu.edfa.outputPowerMon" + } + }, + "type": "object" + }, + "cm.ndu.port.voa": { + "description": "Definition of NDU VOA object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.port.voa.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.port.voa.state" + } + } + }, + "cm.ndu.port.voas": { + "items": { + "$ref": "#/components/schemas/cm.ndu.port.voa" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "voas" + } + }, + "cm.ndu.port.voa.config": { + "additionalProperties": false, + "description": "Definition of ndu VOA configurable parameters", + "properties": { + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "outputVoaAttenuation": { + "$ref": "#/components/schemas/ndu.voa.outputVoaAttenuation" + } + }, + "type": "object", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "cm.ndu.port.voa.state": { + "description": "Definition of ndu VOA state object", + "properties": { + "voaAid": { + "$ref": "#/components/schemas/ndu.voa.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.voa.parentAid" + }, + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "serDes": { + "items": { + "$ref": "#/components/schemas/ndu.serDesData" + }, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "serDes" + } + }, + "outputVoaAttenuation": { + "$ref": "#/components/schemas/ndu.voa.outputVoaAttenuation" + }, + "outputVoaActual": { + "$ref": "#/components/schemas/ndu.voa.outputVoaActual" + }, + "inputPowerMon": { + "$ref": "#/components/schemas/ndu.voa.inputPowerMon" + }, + "outputPowerMon": { + "$ref": "#/components/schemas/ndu.voa.outputPowerMon" + }, + "inventory": { + "$ref": "#/components/schemas/ndu.inventory" + } + }, + "type": "object" + }, + "cm.ndu.port.voa.update": { + "additionalProperties": false, + "description": "Definition of ndu VOA editable parameters", + "minProperties": 1, + "properties": { + "enableSerdes": { + "$ref": "#/components/schemas/ndu.enableSerdes" + }, + "outputVoaAttenuation": { + "$ref": "#/components/schemas/ndu.voa.outputVoaAttenuation" + }, + "outputVoaActual": { + "$ref": "#/components/schemas/ndu.voa.outputVoaActual" + } + }, + "type": "object" + }, + "cm.ndu.linePtp": { + "description": "Definition of ndu line port object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.linePtp.state" + }, + "carriers": { + "$ref": "#/components/schemas/cm.ndu.linePtp.carriers" + } + } + }, + "cm.ndu.linePtps": { + "items": { + "$ref": "#/components/schemas/cm.ndu.linePtp" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "linePtps" + } + }, + "cm.ndu.linePtp.state": { + "description": "Definition of module line port state object", + "properties": { + "linePtpAid": { + "$ref": "#/components/schemas/ndu.lineptp.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.lineptp.parentAid" + } + }, + "type": "object" + }, + "cm.ndu.linePtp.carrier": { + "description": "Definition of ndu carrier object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.linePtp.carrier.state" + } + } + }, + "cm.ndu.linePtp.carriers": { + "items": { + "$ref": "#/components/schemas/cm.ndu.linePtp.carrier" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "carriers" + } + }, + "cm.ndu.linePtp.carrier.state": { + "description": "Definition of module carrier state object", + "properties": { + "carrierAid": { + "$ref": "#/components/schemas/xr.carrier.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.carrier.parentAid" + } + }, + "type": "object" + }, + "cm.ndu.tribPtp": { + "description": "Definition of NDU tributary port object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.tribPtp.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.tribPtp.state" + } + } + }, + "cm.ndu.tribPtps": { + "items": { + "$ref": "#/components/schemas/cm.ndu.tribPtp" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "tribPtps" + } + }, + "cm.ndu.tribPtp.config": { + "additionalProperties": false, + "description": "Definition of ndu tributary port configurable parameters", + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.ptp.label" + }, + "serviceType": { + "$ref": "#/components/schemas/ndu.ptp.serviceType" + }, + "disableAction": { + "$ref": "#/components/schemas/ndu.ptp.tributaryDisableAction" + }, + "disableActionHoldOff": { + "$ref": "#/components/schemas/ndu.ptp.tributaryDisableActionHoldoff" + }, + "powerThresholdLow": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdLow" + }, + "powerThresholdLowOffset": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdLowOffset" + }, + "powerThresholdHigh": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdHigh" + }, + "powerThresholdHighOffset": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdHighOffset" + } + }, + "type": "object" + }, + "cm.ndu.tribPtp.state": { + "description": "Definition of ndu tributary port state object", + "properties": { + "tribPtpAid": { + "$ref": "#/components/schemas/ndu.ptp.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.lineptp.parentAid" + }, + "name": { + "$ref": "#/components/schemas/ndu.ptp.label" + }, + "serviceType": { + "$ref": "#/components/schemas/ndu.ptp.serviceType" + }, + "disableAction": { + "$ref": "#/components/schemas/ndu.ptp.tributaryDisableAction" + }, + "disableActionHoldOff": { + "$ref": "#/components/schemas/ndu.ptp.tributaryDisableActionHoldoff" + }, + "powerThresholdLow": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdLow" + }, + "powerThresholdLowOffset": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdLowOffset" + }, + "powerThresholdHigh": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdHigh" + }, + "powerThresholdHighOffset": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdHighOffset" + } + }, + "type": "object" + }, + "cm.ndu.tribPtp.update": { + "additionalProperties": false, + "description": "Definition of ndu tributary port editable parameters", + "minProperties": 1, + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.ptp.label" + }, + "serviceType": { + "$ref": "#/components/schemas/ndu.ptp.serviceType" + }, + "disableAction": { + "$ref": "#/components/schemas/ndu.ptp.tributaryDisableAction" + }, + "disableActionHoldOff": { + "$ref": "#/components/schemas/ndu.ptp.tributaryDisableActionHoldoff" + }, + "powerThresholdLow": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdLow" + }, + "powerThresholdLowOffset": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdLowOffset" + }, + "powerThresholdHigh": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdHigh" + }, + "powerThresholdHighOffset": { + "$ref": "#/components/schemas/ndu.ptp.powerThresholdHighOffset" + } + }, + "type": "object" + }, + "cm.ndu.otu": { + "description": "Definition of NDU otu object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.otu.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.otu.state" + }, + "odus": { + "$ref": "#/components/schemas/cm.ndu.otu.odus" + } + } + }, + "cm.ndu.otus": { + "items": { + "$ref": "#/components/schemas/cm.ndu.otu" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "otus" + } + }, + "cm.ndu.otu.config": { + "additionalProperties": false, + "description": "Definition of NDU otu configurable parameters", + "properties": { + "txTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.txTTI" + }, + "expectedTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.expectedTTI" + }, + "facPRBSGen": { + "$ref": "#/components/schemas/xr.ndu.otu.diagnostic.facPRBSGen" + }, + "facPRBSMon": { + "$ref": "#/components/schemas/xr.ndu.otu.diagnostic.facPRBSMon" + } + }, + "type": "object" + }, + "cm.ndu.otu.state": { + "description": "Definition of NDU otu state object", + "properties": { + "otuAid": { + "$ref": "#/components/schemas/xr.ndu.otu.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ndu.otu.parentAid" + }, + "otuType": { + "$ref": "#/components/schemas/xr.ndu.otu.otuType" + }, + "rate": { + "$ref": "#/components/schemas/xr.ndu.otu.rate" + }, + "txTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.txTTI" + }, + "rxTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.rxTTI" + }, + "expectedTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.expectedTTI" + }, + "facPRBSGen": { + "$ref": "#/components/schemas/xr.ndu.otu.diagnostic.facPRBSGen" + }, + "facPRBSMon": { + "$ref": "#/components/schemas/xr.ndu.otu.diagnostic.facPRBSMon" + } + }, + "type": "object" + }, + "cm.ndu.otu.update": { + "additionalProperties": false, + "description": "Definition of NDU otu editable parameters", + "minProperties": 1, + "properties": { + "txTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.txTTI" + }, + "expectedTTI": { + "$ref": "#/components/schemas/xr.ndu.otu.expectedTTI" + }, + "facPRBSGen": { + "$ref": "#/components/schemas/xr.ndu.otu.diagnostic.facPRBSGen" + }, + "facPRBSMon": { + "$ref": "#/components/schemas/xr.ndu.otu.diagnostic.facPRBSMon" + } + }, + "type": "object" + }, + "cm.ndu.otu.odu": { + "description": "Definition of NTU ODU object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.otu.odu.state" + } + } + }, + "cm.ndu.otu.odus": { + "items": { + "$ref": "#/components/schemas/cm.ndu.otu.odu" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "odus" + } + }, + "cm.ndu.otu.odu.state": { + "description": "Definition of NDU ODU state object", + "properties": { + "oduAid": { + "$ref": "#/components/schemas/xr.ndu.otu.odu.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ndu.otu.odu.parentAid" + }, + "oduType": { + "$ref": "#/components/schemas/xr.ndu.otu.odu.oduType" + } + } + }, + "cm.ndu.ethernetClient": { + "description": "Definition of NDU ethernetClient object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "config": { + "$ref": "#/components/schemas/cm.ndu.ethernetClient.config" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.ethernetClient.state" + } + } + }, + "cm.ndu.ethernetClients": { + "items": { + "$ref": "#/components/schemas/cm.ndu.ethernetClient" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "ethernetClients" + } + }, + "cm.ndu.ethernetClient.config": { + "additionalProperties": false, + "description": "Definition of NDU ethernetClient configuration object", + "properties": { + "fecMode": { + "$ref": "#/components/schemas/xr.ndu.ethernet.fecMode" + }, + "loopbackType": { + "$ref": "#/components/schemas/xr.ndu.ethernet.diagnostic.loopbackType" + }, + "loopbackMode": { + "$ref": "#/components/schemas/xr.ndu.ethernet.diagnostic.loopbackMode" + } + }, + "type": "object" + }, + "cm.ndu.ethernetClient.state": { + "description": "Definition of module ethernetClient state parameters", + "properties": { + "clientIfAid": { + "$ref": "#/components/schemas/xr.ndu.ethernet.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/xr.ndu.ethernet.parentAid" + }, + "clientIfPortSpeed": { + "$ref": "#/components/schemas/xr.ndu.ethernet.portSpeed" + }, + "fecType": { + "$ref": "#/components/schemas/xr.ndu.ethernet.fecType" + }, + "fecMode": { + "$ref": "#/components/schemas/xr.ndu.ethernet.fecMode" + }, + "loopbackType": { + "$ref": "#/components/schemas/xr.ndu.ethernet.diagnostic.loopbackType" + }, + "loopbackMode": { + "$ref": "#/components/schemas/xr.ndu.ethernet.diagnostic.loopbackMode" + } + }, + "type": "object" + }, + "cm.ndu.ethernetClient.update": { + "additionalProperties": false, + "description": "Definition of NDU ethernetClient editable object", + "minProperties": 1, + "properties": { + "fecMode": { + "$ref": "#/components/schemas/xr.ndu.ethernet.fecMode" + }, + "loopbackType": { + "$ref": "#/components/schemas/xr.ndu.ethernet.diagnostic.loopbackType" + }, + "loopbackMode": { + "$ref": "#/components/schemas/xr.ndu.ethernet.diagnostic.loopbackMode" + } + }, + "type": "object" + }, + "cm.ndu.trail": { + "description": "Definition of NTU trail object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.trail.state" + } + } + }, + "cm.ndu.trails": { + "items": { + "$ref": "#/components/schemas/cm.ndu.trail" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "trails" + } + }, + "cm.ndu.trail.state": { + "description": "Definition of NDU ODU state object", + "properties": { + "trailAid": { + "$ref": "#/components/schemas/ndu.trail.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.trail.parentAid" + }, + "trailType": { + "$ref": "#/components/schemas/ndu.trail.trailType" + }, + "clientAid": { + "$ref": "#/components/schemas/ndu.trail.Aid_A" + }, + "lineAid": { + "$ref": "#/components/schemas/ndu.trail.Aid_Z" + } + } + }, + "cm.ndu.fan": { + "description": "Definition of NTU fan object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.fan.state" + } + } + }, + "cm.ndu.fans": { + "items": { + "$ref": "#/components/schemas/cm.ndu.fan" + }, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "fans" + } + }, + "cm.ndu.fan.state": { + "description": "Definition of NDU fan state object", + "properties": { + "fanAid": { + "$ref": "#/components/schemas/ndu.fan.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.fan.parentAid" + }, + "inventory": { + "$ref": "#/components/schemas/ndu.inventory" + } + } + }, + "cm.ndu.pem": { + "description": "Definition of NDU PEM object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.pem.state" + } + } + }, + "cm.ndu.pem.state": { + "description": "Definition of NDU PEM state object", + "properties": { + "pemAid": { + "$ref": "#/components/schemas/ndu.fan.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.fan.parentAid" + }, + "availablePower": { + "$ref": "#/components/schemas/ndu.pem.availablePower" + }, + "pemUnderVoltageThreshold": { + "$ref": "#/components/schemas/ndu.pem.pemUnderVoltageThreshold" + }, + "pemOverVoltageThreshold": { + "$ref": "#/components/schemas/ndu.pem.pemOverVoltageThreshold" + }, + "inventory": { + "$ref": "#/components/schemas/ndu.inventory" + } + }, + "type": "object" + }, + "cm.ndu.pem.update": { + "additionalProperties": false, + "description": "Definition of ndu PEM editable parameters", + "minProperties": 1, + "properties": { + "pemUnderVoltageThreshold": { + "$ref": "#/components/schemas/ndu.pem.pemUnderVoltageThreshold" + }, + "pemOverVoltageThreshold": { + "$ref": "#/components/schemas/ndu.pem.pemOverVoltageThreshold" + } + }, + "type": "object" + }, + "cm.ndu.leds": { + "description": "Definition of NDU LEDs object", + "properties": { + "href": { + "$ref": "#/components/schemas/cm.parameters.href" + }, + "rt": { + "$ref": "#/components/schemas/cm.parameters.rt" + }, + "id": { + "$ref": "#/components/schemas/cm.parameters.uuid" + }, + "parentId": { + "$ref": "#/components/schemas/cm.parameters.parentId" + }, + "colId": { + "$ref": "#/components/schemas/ndu.colId" + }, + "state": { + "$ref": "#/components/schemas/cm.ndu.leds.state" + } + } + }, + "cm.ndu.leds.state": { + "description": "Definition of NDU LEDs state object", + "properties": { + "ledsAid": { + "$ref": "#/components/schemas/ndu.leds.aid" + }, + "parentAid": { + "$ref": "#/components/schemas/ndu.leds.parentAid" + }, + "leds": { + "$ref": "#/components/schemas/ndu.leds.leds" + } + } + }, + "ndu.configuration.contact": { + "description": "Contact info of administrator of NDU", + "title": "Contact", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "contact" + } + }, + "ndu.configuration.mgmtMode": { + "description": "Defines the ownership of the object.", + "enum": [ + "local", + "CM" + ], + "title": "Managed by", + "type": "string", + "x-enum-varnames": [ + "Local", + "IPM" + ], + "x-oapi-codegen-extra-tags": { + "bson": "managedBy" + } + }, + "ndu.configuration.neLocation": { + "description": "NE location, defined by operator.", + "maxLength": 64, + "title": "Description", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "description" + } + }, + "ndu.configuration.clli": { + "description": "Common Location Language Identifier", + "maxLength": 11, + "minLength": 6, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clli" + } + }, + "ndu.configuration.latitude": { + "description": "Latitude location info. \nRange: -90 to +90\n", + "format": "double", + "maximum": 90, + "minimum": -90, + "title": "Latitude", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "latitude" + } + }, + "ndu.configuration.longitude": { + "description": "Longitude location info. \nRange: -180 to +180\n", + "format": "double", + "maximum": 180, + "minimum": -180, + "title": "Longitude", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "longitude" + } + }, + "ndu.configuration.altitude": { + "title": "Altitude", + "type": "integer", + "x-unit": "Meters", + "x-oapi-codegen-extra-tags": { + "bson": "altitude" + } + }, + "ndu.device.n": { + "description": "Friendly name of the device", + "maxLength": 64, + "readOnly": true, + "title": "NDU name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "ndu.device.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "nduAid" + } + }, + "ndu.platform.pi": { + "description": "Unique UUID for the hardware platform calculated from the mac address", + "maxLength": 36, + "minLength": 36, + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "readOnly": true, + "title": "Platform UUID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "pi" + } + }, + "ndu.platform.mnfv": { + "description": "Manufacturer's firmware version", + "maxLength": 64, + "readOnly": true, + "title": "Firmware version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnfv" + } + }, + "ndu.platform.mnmn": { + "description": "Manufacturer name", + "maxLength": 64, + "readOnly": true, + "title": "Manufacturer", + "type": "string" + }, + "ndu.platform.mnmo": { + "description": "Manufacturer's Model/Part number", + "maxLength": 64, + "readOnly": true, + "title": "Model number", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnmo" + } + }, + "ndu.platform.mnhw": { + "description": "Platform Hardware Version", + "maxLength": 64, + "readOnly": true, + "title": "HW Version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mnhw" + } + }, + "ndu.platform.mndt": { + "description": "HW Manufacturing date", + "pattern": "([0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|2[0-9]|1[0-9]|0[1-9])", + "readOnly": true, + "title": "Manufacturing date", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "mndt" + } + }, + "ndu.platform.mnsel": { + "description": "Device Serial number", + "maxLength": 64, + "readOnly": true, + "title": "Serial number", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "serialNumber" + } + }, + "ndu.platform.clei": { + "description": "Globally unique 10-character alphanumeric intelligent code identifying equipment in a structured naming format", + "readOnly": true, + "title": "CLEI Code", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clei" + } + }, + "ndu.platform.macAddress": { + "description": "Device MAC Address", + "readOnly": true, + "title": "MAC address", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "macAddress" + } + }, + "ndu.device.piid": { + "description": "Protocol independent unique identifier for the Device that is immutable.", + "maxLength": 36, + "minLength": 36, + "pattern": "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "readOnly": true, + "title": "PIID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "piid" + } + }, + "ndu.device.dmn": { + "properties": { + "language": { + "$ref": "#/components/schemas/ndu.device.dmn.language" + }, + "value": { + "$ref": "#/components/schemas/ndu.device.dmn.value" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "dmn" + } + }, + "ndu.device.dmn.language": { + "description": "Format pattern according to IETF RFC 5646 (language tag).", + "pattern": "[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})", + "title": "Language", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "language" + } + }, + "ndu.device.dmn.value": { + "description": "Manufacturer name", + "maxLength": 64, + "readOnly": true, + "title": "Manufacturer", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "value" + } + }, + "ndu.device.sv": { + "description": "Software version.", + "maxLength": 64, + "readOnly": true, + "title": "Software version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "sv" + } + }, + "ndu.device.icv": { + "description": "Device HW version.", + "maxLength": 64, + "readOnly": true, + "title": "Hardware version", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "icv" + } + }, + "ndu.colId": { + "description": "Object identifier in the supporting collection.", + "readOnly": true, + "title": "Collection Id", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "colId" + } + }, + "ndu.port.label": { + "description": "User defined port label", + "maxLength": 64, + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "ndu.port.connectedTo": { + "description": "User configurable neighbor entity information", + "maxLength": 64, + "title": "Neighbor", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "connectedTo" + } + }, + "ndu.port.externalConnectivity": { + "description": "Whether port has NMS external connectivity.", + "title": "External Connectivity", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "externalConnectivity" + } + }, + "ndu.port.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type..", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "portAid" + } + }, + "ndu.port.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.port.portType": { + "description": "Describes the port type", + "enum": [ + "line", + "tributary", + "usb", + "dcn", + "uplink", + "optical" + ], + "readOnly": true, + "title": "Type", + "type": "string", + "x-enum-varnames": [ + "Line", + "Tributary", + "USB", + "DCN", + "Uplink", + "Optical" + ], + "x-oapi-codegen-extra-tags": { + "bson": "category" + } + }, + "ndu.port.supportedType": { + "description": "List of supported pluggable interfaces", + "items": { + "type": "string" + }, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "supportedTypes" + } + }, + "ndu.port.installedType": { + "description": "Installed pluggable interface", + "readOnly": true, + "type": "string" + }, + "ndu.tom.requiredType": { + "default": "", + "description": "User defined required type.\nInserted value should match a tom value defined in port supportedTypes.\n", + "maxLength": 64, + "title": "Required Type", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "requiredType" + } + }, + "ndu.enableSerdes": { + "description": "Serdes control parameter", + "title": "Enable Serdes", + "type": "boolean", + "x-oapi-codegen-extra-tags": { + "bson": "enableSerdes" + } + }, + "ndu.tom.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "tomAid" + } + }, + "ndu.tom.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.port.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.serDesData": { + "properties": { + "name": { + "$ref": "#/components/schemas/ndu.serDes.name" + }, + "value": { + "$ref": "#/components/schemas/ndu.serDes.value" + }, + "status": { + "$ref": "#/components/schemas/ndu.serDes.status" + } + } + }, + "ndu.serDes.name": { + "description": "Serdes name", + "readOnly": true, + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "ndu.serDes.value": { + "description": "Serdes value", + "readOnly": true, + "title": "Value", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "value" + } + }, + "ndu.serDes.status": { + "description": "Serdes status", + "enum": [ + "set", + "unknown", + "inProgress", + "failed", + "notSupported" + ], + "readOnly": true, + "title": "Status", + "type": "string", + "x-enum-varnames": [ + "Set", + "Unknown", + "In progress", + "Failed", + "Not supported" + ], + "x-oapi-codegen-extra-tags": { + "bson": "status" + } + }, + "ndu.inventory": { + "properties": { + "hardwareVersion": { + "$ref": "#/components/schemas/ndu.inventory.hardwareVersion" + }, + "actualType": { + "$ref": "#/components/schemas/ndu.inventory.actualType" + }, + "PON": { + "$ref": "#/components/schemas/ndu.inventory.pon" + }, + "serialNumber": { + "$ref": "#/components/schemas/ndu.inventory.serialNumber" + }, + "clei": { + "$ref": "#/components/schemas/ndu.inventory.clei" + }, + "vendor": { + "$ref": "#/components/schemas/ndu.inventory.vendor" + }, + "partNumber": { + "$ref": "#/components/schemas/ndu.inventory.partNumber" + }, + "manufactureDate": { + "$ref": "#/components/schemas/ndu.inventory.manufactureDate" + }, + "fwName": { + "$ref": "#/components/schemas/ndu.inventory.fwName" + }, + "fwVersion": { + "$ref": "#/components/schemas/ndu.inventory.fwVersion" + }, + "expectedFWVersion": { + "$ref": "#/components/schemas/ndu.inventory.expectedFWVersion" + }, + "fwStatus": { + "$ref": "#/components/schemas/ndu.inventory.fwStatus" + } + }, + "x-oapi-codegen-extra-tags": { + "bson": "hardwareVersion" + } + }, + "ndu.inventory.hardwareVersion": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "inventory" + } + }, + "ndu.inventory.actualType": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "actualType" + } + }, + "ndu.inventory.pon": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "PON" + } + }, + "ndu.inventory.serialNumber": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "serialNumber" + } + }, + "ndu.inventory.clei": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clei" + } + }, + "ndu.inventory.vendor": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "vendor" + } + }, + "ndu.inventory.partNumber": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "partNumber" + } + }, + "ndu.inventory.manufactureDate": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "manufactureDate" + } + }, + "ndu.inventory.fwName": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "fwName" + } + }, + "ndu.inventory.fwVersion": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "fwVersion" + } + }, + "ndu.inventory.expectedFWVersion": { + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "expectedFWVersion" + } + }, + "ndu.inventory.fwStatus": { + "enum": [ + "notApplicable", + "current", + "notCurrent", + "unavailable" + ], + "readOnly": true, + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "fwStatus" + } + }, + "ndu.xr.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "xrAid" + } + }, + "ndu.xr.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.port.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.edfa.label": { + "description": "User defined label", + "maxLength": 64, + "title": "Name", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "ndu.edfa.function": { + "description": "booster amplifier or pre-amplifier", + "enum": [ + "pa", + "ba" + ], + "title": "Function", + "type": "string", + "x-enum-varnames": [ + "Pre-amplifier", + "Booster amplifier" + ], + "x-oapi-codegen-extra-tags": { + "bson": "function" + } + }, + "ndu.edfa.amplifierEnable": { + "description": "The enable switch for the amplifier.", + "enum": [ + "enabled", + "disabled" + ], + "title": "Status", + "type": "string", + "x-enum-varnames": [ + "Enabled", + "Disabled" + ], + "x-oapi-codegen-extra-tags": { + "bson": "amplifierEnable" + } + }, + "ndu.edfa.controlMode": { + "description": "Mode of control of the amplifier (user defined targeting or automatic power targeting)", + "enum": [ + "autoMaxPw", + "manual" + ], + "title": "Power Control", + "type": "string", + "x-enum-varnames": [ + "Automatic", + "Manual" + ], + "x-oapi-codegen-extra-tags": { + "bson": "controlMode" + } + }, + "ndu.edfa.amplifierMode": { + "description": "Mode of operation.", + "enum": [ + "constantPower", + "constantGain" + ], + "title": "Amplifier Mode", + "type": "string", + "x-enum-varnames": [ + "Power control", + "Gain control" + ], + "x-oapi-codegen-extra-tags": { + "bson": "amplifierMode" + } + }, + "ndu.edfa.gainTarget": { + "description": "Target gain to be achieved by the amplifier.", + "format": "double", + "title": "Target Gain", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "gainTarget" + } + }, + "ndu.edfa.optimumEdfaGain": { + "description": "Optimum EDFA gain of the emplifier", + "format": "double", + "readOnly": true, + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "optimumEdfaGain" + } + }, + "ndu.edfa.inputPowerMon": { + "description": "Monitored input power.", + "format": "double", + "readOnly": true, + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "inputPowerMon" + } + }, + "ndu.edfa.outputPowerMon": { + "description": "Monitored output power", + "format": "double", + "readOnly": true, + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "outputPowerMon" + } + }, + "ndu.edfa.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "edfaAid" + } + }, + "ndu.edfa.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.port.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.voa.outputVoaAttenuation": { + "default": 0, + "description": "Attenuation setting on VOA. \nRange 0.. 20, \nUnit: dB, \nDefault: 0\n", + "format": "double", + "maximum": 20, + "minimum": 0, + "title": "VOA Attenuation", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "outputVoaAttenuation" + } + }, + "ndu.voa.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "voaAid" + } + }, + "ndu.voa.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.port.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.voa.outputVoaActual": { + "description": "Attenuation setting monitor (actual)", + "readOnly": true, + "title": "Actual VOA Attenuation", + "type": "integer", + "x-oapi-codegen-extra-tags": { + "bson": "outputVoaActual" + } + }, + "ndu.voa.inputPowerMon": { + "description": "Monitored input power", + "format": "double", + "readOnly": true, + "title": "Input power", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "inputPowerMon" + } + }, + "ndu.voa.outputPowerMon": { + "description": "Monitored output power", + "format": "double", + "readOnly": true, + "title": "Output power", + "type": "number", + "x-oapi-codegen-extra-tags": { + "bson": "outputPowerMon" + } + }, + "ndu.lineptp.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "linePtpAid" + } + }, + "ndu.lineptp.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.ptp.label": { + "description": "User defined label", + "maxLength": 64, + "title": "Description", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "name" + } + }, + "ndu.ptp.serviceType": { + "enum": [ + "100GBE", + "4x25GBE", + "OTU4" + ], + "title": "Service Type", + "type": "string", + "x-enum-varnames": [ + "100GBE", + "4x25GBE", + "OTU4" + ], + "x-oapi-codegen-extra-tags": { + "bson": "serviceType" + } + }, + "ndu.ptp.tributaryDisableAction": { + "description": "Defines the applicable disable action for the tributary port", + "enum": [ + "laserShutoff", + "sendIdles", + "sendLf" + ], + "title": "Disable action", + "type": "string", + "x-enum-varnames": [ + "Laser shutdown", + "Send idle", + "Send loss of frame" + ], + "x-oapi-codegen-extra-tags": { + "bson": "disableAction" + } + }, + "ndu.ptp.tributaryDisableActionHoldoff": { + "description": "Time in ms before TDA kicks in.", + "maximum": 10000, + "minimum": 0, + "title": "Disable action hold-off time", + "type": "integer", + "x-unit": "ms", + "x-oapi-codegen-extra-tags": { + "bson": "disableActionHoldOff" + } + }, + "ndu.ptp.powerThresholdLow": { + "description": "The threshold below which the system raises the OPR-OORL alarm. \nRange: -55.00 to +55.00 \nUnits: dBm\n", + "format": "double", + "maximum": 55, + "minimum": -55, + "title": "Under Power Threshold", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "powerThresholdLow" + } + }, + "ndu.ptp.powerThresholdLowOffset": { + "description": "Adjustment factor for low alarm. \nThe effective threshold will be (threshold-low + threshold-low-offset). \nRange: -10.00 to +10.00\nUnits: dB\n", + "format": "double", + "maximum": 10, + "minimum": -10, + "title": "Under Power Threshold Offset", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "powerThresholdLowOffset" + } + }, + "ndu.ptp.powerThresholdHigh": { + "description": "The threshold above which the system raises the OPR-OORH alarm. \nRange: -55.00 to +55.00 \nUnits: dB\n", + "format": "double", + "maximum": 55, + "minimum": -55, + "title": "Over Power Threshold", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "powerThresholdHigh" + } + }, + "ndu.ptp.powerThresholdHighOffset": { + "description": "Adjustment factor for low alarm.\nThe effective threshold will be (threshold-high+ threshold-high-offset)\nRange: -10.00 to +10.00 \nUnits: dB\n", + "format": "double", + "maximum": 10, + "minimum": -10, + "title": "Over Power Threshold Offset", + "type": "number", + "x-unit": "dB", + "x-oapi-codegen-extra-tags": { + "bson": "powerThresholdHighOffset" + } + }, + "ndu.ptp.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "tribPtpAid" + } + }, + "xr.ndu.otu.txTTI": { + "default": "", + "description": "Up to 64 byte string for transmitting as TTI.", + "maxLength": 64, + "title": "Transmit TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "txTTI" + } + }, + "xr.ndu.otu.expectedTTI": { + "default": "", + "description": "Up to 64 byte string of TTI that is expected to be received.", + "maxLength": 64, + "title": "Expected TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "expectedTTI" + } + }, + "xr.ndu.otu.diagnostic.facPRBSGen": { + "default": "disabled", + "description": "Enable/Disable facility PRBS test pattern generation", + "enum": [ + "enabled", + "disabled" + ], + "title": "Facility PRBS generation", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSGen" + } + }, + "xr.ndu.otu.diagnostic.facPRBSMon": { + "default": "disabled", + "description": "Enable/Disable facility PRBS test pattern monitoring", + "enum": [ + "enabled", + "disabled" + ], + "title": "Facility PRBS monitoring", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "facPRBSMon" + } + }, + "xr.ndu.otu.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "otuAid" + } + }, + "xr.ndu.otu.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.ndu.otu.otuType": { + "description": "OTU Type", + "enum": [ + "OTUCni", + "OTUCn", + "OTUCni-M", + "OTU4" + ], + "readOnly": true, + "title": "OTU type", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "otuType" + } + }, + "xr.ndu.otu.rate": { + "description": "Rate of the OTU.", + "enum": [ + 25, + 50, + 100, + 200, + 400 + ], + "readOnly": true, + "title": "Rate", + "type": "integer", + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "rate" + } + }, + "xr.ndu.otu.rxTTI": { + "description": "Up to 64 byte string of received TTI.", + "maxLength": 64, + "readOnly": true, + "title": "Received TTI", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "rxTTI" + } + }, + "xr.ndu.otu.odu.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "oduAid" + } + }, + "xr.ndu.otu.odu.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.carrier.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.carrier.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "carrierAid" + } + }, + "xr.ndu.otu.odu.oduType": { + "description": "ODU type", + "enum": [ + "ODUCni", + "ODUflexi", + "ODUCni-M", + "ODU4i" + ], + "readOnly": true, + "title": "ODU type", + "type": "string", + "x-enum-varnames": [ + "ODUCni", + "ODUflexi", + "ODUCni-M", + "ODU4i" + ], + "x-oapi-codegen-extra-tags": { + "bson": "oduType" + } + }, + "xr.ndu.ethernet.fecMode": { + "default": "enabled", + "description": "Forward error correction mode of operation", + "enum": [ + "enabled", + "disabled" + ], + "title": "Forward error correction mode", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "fecMode" + } + }, + "xr.ndu.ethernet.diagnostic.loopbackType": { + "default": "loopbackAndContinue", + "description": "Loopback type. - 'loopbackAndContinue': Signal is looped back and is also forwarded downstream. - 'loopback': Signal is looped back and LF maintenance signal is sent downstream.\n", + "enum": [ + "loopbackAndContinue", + "loopback" + ], + "title": "Loopback type", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "loopbackType" + } + }, + "xr.ndu.ethernet.diagnostic.loopbackMode": { + "default": "disabled", + "description": "Post-FEC Loopback mode for the ethernet client.", + "enum": [ + "disabled", + "facility", + "terminal" + ], + "title": "Loopback mode", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "loopbackMode" + } + }, + "xr.ndu.ethernet.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clientIfAid" + } + }, + "xr.ndu.ethernet.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "xr.ndu.ethernet.portSpeed": { + "description": "Ethernet port speed in Gbps", + "enum": [ + 100, + 400, + 200, + 50, + 25 + ], + "readOnly": true, + "title": "Port speed", + "type": "integer", + "x-unit": "Gbps", + "x-oapi-codegen-extra-tags": { + "bson": "clientIfPortSpeed" + } + }, + "xr.ndu.ethernet.fecType": { + "description": "Automatically set by the module based on SerDes and Port configuration.", + "enum": [ + "KR4", + "KP4" + ], + "readOnly": true, + "title": "Fec type", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "fecType" + } + }, + "ndu.trail.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "maxLength": 64, + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "trailAid" + } + }, + "ndu.trail.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.trail.trailType": { + "default": "biDir", + "description": "Directionality of the LC", + "enum": [ + "biDir" + ], + "title": "Directionality", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "trailType" + } + }, + "ndu.trail.Aid_A": { + "description": "Points to the AID of the connected resource A of the trail.", + "title": "Client side AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "clientAid" + } + }, + "ndu.trail.Aid_Z": { + "description": "Points to the AID of the connected resource Z of the trail.", + "readOnly": true, + "title": "Line side AID", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "lineAid" + } + }, + "ndu.fan.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string" + }, + "ndu.fan.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.pem.availablePower": { + "format": "double", + "readOnly": true, + "title": "Available Power", + "type": "number" + }, + "ndu.pem.pemUnderVoltageThreshold": { + "description": "Ranges:\n- 40.5 to 57.0 for DC PEM,\n- 100 to 260V for AC PEM\n", + "format": "double", + "title": "Under Voltage Threshold", + "type": "number" + }, + "ndu.pem.pemOverVoltageThreshold": { + "description": "Ranges:\n- 40.5 to -57.0 for DC PEM,\n- 100 to 260V for AC PEM\n", + "format": "double", + "title": "Over Voltage Threshold", + "type": "number" + }, + "ndu.leds.aid": { + "description": "Access Identifier (AID) - unique instance within a device and specific resource type.", + "readOnly": true, + "title": "Access identifier", + "type": "string", + "x-oapi-codegen-extra-tags": { + "bson": "ledsAid" + } + }, + "ndu.leds.parentAid": { + "items": { + "$ref": "#/components/schemas/ndu.device.aid" + }, + "maxItems": 1, + "minItems": 1, + "readOnly": true, + "type": "array", + "x-oapi-codegen-extra-tags": { + "bson": "parentAid" + } + }, + "ndu.leds.leds": { + "items": { + "$ref": "#/components/schemas/ndu.ledState" + }, + "readOnly": true, + "type": "array", + "uniqueItems": true, + "x-oapi-codegen-extra-tags": { + "bson": "leds" + } + }, + "ndu.ledState": { + "properties": { + "ledId": { + "$ref": "#/components/schemas/ndu.ledState.ledId" + }, + "state": { + "$ref": "#/components/schemas/ndu.ledState.state" + } + }, + "type": "object" + }, + "ndu.ledState.ledId": { + "enum": [ + "CFP_RX", + "CFP_TX", + "POL_Upper", + "POL_Lower", + "QSFP28_1_RX", + "QSFP28_2_RX", + "QSFP28_1_TX", + "QSFP28_2_TX", + "QSFP28_1_Service", + "QSFP28_2_Service", + "Maintenance", + "IpAuth", + "Power", + "Status", + "Fips" + ], + "readOnly": true, + "type": "string", + "x-enum-varnames": [ + "CFP_RX", + "CFP_TX", + "POL_Upper", + "POL_Lower", + "QSFP28 Port #1 RX", + "QSFP28 Port #2 RX", + "QSFP28 Port #1 TX", + "QSFP28 Port #2 TX", + "QSFP28 Port #1 Service", + "QSFP28 Port #2 Service", + "Maintenance", + "IP Authentication", + "Power", + "Status", + "Fips" + ], + "x-oapi-codegen-extra-tags": { + "bson": "ledId" + } + }, + "ndu.ledState.state": { + "enum": [ + "Unknown", + "Off", + "Green", + "GreenSlowSingleFlash", + "GreenSlowDoubleFlash", + "GreenSlowIsoPhase", + "GreenQuickIsoPhase", + "GreenFastIsoPhase", + "GreenOneSecondFlicker", + "GreenTwoSecondFlicker", + "GreenInvertedSingleFlash", + "GreenInvertedDoubleFlash", + "Red", + "RedSlowSingleFlash", + "RedSlowDoubleFlash", + "RedSlowIsoPhase", + "RedQuickIsoPhase", + "RedInvertedSingleFlash", + "RedInvertedDoubleFlash", + "Yellow", + "YellowSlowIsoPhase", + "GreenRedSlowIsoPhase" + ], + "readOnly": true, + "type": "string", + "x-enum-varnames": [ + "Unknown", + "Off", + "Green", + "GreenSlowSingleFlash", + "GreenSlowDoubleFlash", + "GreenSlowIsoPhase", + "GreenQuickIsoPhase", + "GreenFastIsoPhase", + "GreenOneSecondFlicker", + "GreenTwoSecondFlicker", + "GreenInvertedSingleFlash", + "GreenInvertedDoubleFlash", + "Red", + "RedSlowSingleFlash", + "RedSlowDoubleFlash", + "RedSlowIsoPhase", + "RedQuickIsoPhase", + "RedInvertedSingleFlash", + "RedInvertedDoubleFlash", + "Yellow", + "YellowSlowIsoPhase", + "GreenRedSlowIsoPhase" + ], + "x-oapi-codegen-extra-tags": { + "bson": "state" + } + } + } + } +} diff --git a/src/device/service/drivers/xr/setup_test_env.sh b/src/device/service/drivers/xr/setup_test_env.sh index 1f8b0a5a7a8dc986715c6f54a62151f6afa4ad80..92ff4a0312fb8f963f934f4cfd8d18603675aed0 100755 --- a/src/device/service/drivers/xr/setup_test_env.sh +++ b/src/device/service/drivers/xr/setup_test_env.sh @@ -1,4 +1,18 @@ #!/bin/sh +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + export CONTEXTSERVICE_SERVICE_HOST=$(kubectl get service/contextservice --namespace tfs --template '{{.spec.clusterIP}}') export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service/contextservice --namespace tfs -o jsonpath='{.spec.ports[?(@.name=="grpc")].port}') export COMPUTESERVICE_SERVICE_HOST=$(kubectl get service/computeservice --namespace tfs --template '{{.spec.clusterIP}}') diff --git a/src/device/service/monitoring/MonitoringLoop.py b/src/device/service/monitoring/MonitoringLoop.py new file mode 100644 index 0000000000000000000000000000000000000000..296ff8f7e51d9a98ca3ec9f0b885228087cf88de --- /dev/null +++ b/src/device/service/monitoring/MonitoringLoop.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 queue, threading +from device.service.driver_api._Driver import _Driver + +class MonitoringLoop: + def __init__(self, device_uuid : str, driver : _Driver, samples_queue : queue.Queue) -> None: + self._device_uuid = device_uuid + self._driver = driver + self._samples_queue = samples_queue + self._running = threading.Event() + self._terminate = threading.Event() + self._samples_stream = self._driver.GetState(blocking=True, terminate=self._terminate) + self._collector_thread = threading.Thread(target=self._collect, daemon=True) + + def _collect(self) -> None: + for sample in self._samples_stream: + if self._terminate.is_set(): break + sample = (self._device_uuid, *sample) + self._samples_queue.put_nowait(sample) + + def start(self): + self._collector_thread.start() + self._running.set() + + @property + def is_running(self): return self._running.is_set() + + def stop(self): + self._terminate.set() + self._collector_thread.join() diff --git a/src/device/service/monitoring/MonitoringLoops.py b/src/device/service/monitoring/MonitoringLoops.py new file mode 100644 index 0000000000000000000000000000000000000000..2acbfdf53293373c03a6470301547ff0b5c7b34b --- /dev/null +++ b/src/device/service/monitoring/MonitoringLoops.py @@ -0,0 +1,174 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 copy, logging, queue, threading +from typing import Dict, Optional, Tuple, Union +from common.proto.kpi_sample_types_pb2 import KpiSampleType +from common.proto.monitoring_pb2 import Kpi +from monitoring.client.MonitoringClient import MonitoringClient +from ..driver_api._Driver import _Driver +from .MonitoringLoop import MonitoringLoop + +LOGGER = logging.getLogger(__name__) + +QUEUE_GET_WAIT_TIMEOUT = 0.5 + +def value_to_grpc(value : Union[bool, float, int, str]) -> Dict: + if isinstance(value, int): + kpi_value_field_name = 'int64Val' + kpi_value_field_cast = int + elif isinstance(value, float): + kpi_value_field_name = 'floatVal' + kpi_value_field_cast = float + elif isinstance(value, bool): + kpi_value_field_name = 'boolVal' + kpi_value_field_cast = bool + else: + kpi_value_field_name = 'stringVal' + kpi_value_field_cast = str + + return {kpi_value_field_name: kpi_value_field_cast(value)} + +TYPE_TARGET_KEY = Tuple[str, str] # (device_uuid, monitoring_resource_key) +TYPE_TARGET_KPI = Tuple[str, float, float] # (kpi_uuid, sampling_duration, sampling_interval) +TYPE_KPI_DETAIL = Tuple[str, str, float, float] # (device_uuid, monitoring_resource_key, + # sampling_duration, sampling_interval) + +class MonitoringLoops: + def __init__(self) -> None: + self._monitoring_client = MonitoringClient() + self._samples_queue = queue.Queue() + self._running = threading.Event() + self._terminate = threading.Event() + + self._lock_device_endpoint = threading.Lock() + self._device_endpoint_sampletype__to__resource_key : Dict[Tuple[str, str, int], str] = dict() + + self._lock_monitoring_loop = threading.Lock() + self._device_uuid__to__monitoring_loop : Dict[str, MonitoringLoop] = dict() + + self._lock_kpis = threading.Lock() + self._target_to_kpi : Dict[TYPE_TARGET_KEY, TYPE_TARGET_KPI] = dict() + self._kpi_to_detail : Dict[str, TYPE_KPI_DETAIL] = dict() + + self._exporter_thread = threading.Thread(target=self._export, daemon=True) + + def add_device(self, device_uuid : str, driver : _Driver) -> None: + with self._lock_monitoring_loop: + monitoring_loop = self._device_uuid__to__monitoring_loop.get(device_uuid) + if (monitoring_loop is not None) and monitoring_loop.is_running: return + monitoring_loop = MonitoringLoop(device_uuid, driver, self._samples_queue) + self._device_uuid__to__monitoring_loop[device_uuid] = monitoring_loop + monitoring_loop.start() + + def remove_device(self, device_uuid : str) -> None: + with self._lock_monitoring_loop: + monitoring_loop = self._device_uuid__to__monitoring_loop.get(device_uuid) + if monitoring_loop is None: return + if monitoring_loop.is_running: monitoring_loop.stop() + self._device_uuid__to__monitoring_loop.pop(device_uuid, None) + + def add_resource_key( + self, device_uuid : str, endpoint_uuid : str, kpi_sample_type : KpiSampleType, resource_key : str + ) -> None: + with self._lock_device_endpoint: + key = (device_uuid, endpoint_uuid, kpi_sample_type) + self._device_endpoint_sampletype__to__resource_key[key] = resource_key + + def get_resource_key( + self, device_uuid : str, endpoint_uuid : str, kpi_sample_type : KpiSampleType + ) -> Optional[str]: + with self._lock_device_endpoint: + key = (device_uuid, endpoint_uuid, kpi_sample_type) + return self._device_endpoint_sampletype__to__resource_key.get(key) + + def get_all_resource_keys(self) -> Dict[Tuple[str, str, int], str]: + with self._lock_device_endpoint: + return copy.deepcopy(self._device_endpoint_sampletype__to__resource_key) + + def remove_resource_key( + self, device_uuid : str, endpoint_uuid : str, kpi_sample_type : KpiSampleType + ) -> None: + with self._lock_device_endpoint: + key = (device_uuid, endpoint_uuid, kpi_sample_type) + self._device_endpoint_sampletype__to__resource_key.pop(key, None) + + def add_kpi( + self, device_uuid : str, monitoring_resource_key : str, kpi_uuid : str, sampling_duration : float, + sampling_interval : float + ) -> None: + with self._lock_kpis: + kpi_key = (device_uuid, monitoring_resource_key) + kpi_values = (kpi_uuid, sampling_duration, sampling_interval) + self._target_to_kpi[kpi_key] = kpi_values + + kpi_details = (device_uuid, monitoring_resource_key, sampling_duration, sampling_interval) + self._kpi_to_detail[kpi_uuid] = kpi_details + + def get_kpi_by_uuid(self, kpi_uuid : str) -> Optional[TYPE_KPI_DETAIL]: + with self._lock_kpis: + return self._kpi_to_detail.get(kpi_uuid) + + def get_kpi_by_metric( + self, device_uuid : str, monitoring_resource_key : str + ) -> Optional[TYPE_TARGET_KPI]: + with self._lock_kpis: + kpi_key = (device_uuid, monitoring_resource_key) + return self._target_to_kpi.get(kpi_key) + + def remove_kpi(self, kpi_uuid : str) -> None: + with self._lock_kpis: + kpi_details = self._kpi_to_detail.pop(kpi_uuid, None) + if kpi_details is None: return + kpi_key = kpi_details[0:2] # (device_uuid, monitoring_resource_key, _, _) + self._target_to_kpi.pop(kpi_key, None) + + def start(self): + self._exporter_thread.start() + + @property + def is_running(self): return self._running.is_set() + + def stop(self): + self._terminate.set() + self._exporter_thread.join() + + def _export(self) -> None: + self._running.set() + while not self._terminate.is_set(): + try: + sample = self._samples_queue.get(block=True, timeout=QUEUE_GET_WAIT_TIMEOUT) + #LOGGER.debug('[MonitoringLoops:_export] sample={:s}'.format(str(sample))) + except queue.Empty: + continue + + device_uuid, timestamp, monitoring_resource_key, value = sample + + kpi_details = self.get_kpi_by_metric(device_uuid, monitoring_resource_key) + if kpi_details is None: + MSG = 'Kpi for Device({:s})/MonitoringResourceKey({:s}) not found' + LOGGER.warning(MSG.format(str(device_uuid), str(monitoring_resource_key))) + continue + kpi_uuid,_,_ = kpi_details + + try: + self._monitoring_client.IncludeKpi(Kpi(**{ + 'kpi_id' : {'kpi_id': {'uuid': kpi_uuid}}, + 'timestamp': {'timestamp': timestamp}, + 'kpi_value': value_to_grpc(value), + })) + except: # pylint: disable=bare-except + LOGGER.exception('Unable to format/send Kpi') + + self._running.clear() diff --git a/src/common/orm/backend/inmemory/__init__.py b/src/device/service/monitoring/__init__.py similarity index 88% rename from src/common/orm/backend/inmemory/__init__.py rename to src/device/service/monitoring/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/common/orm/backend/inmemory/__init__.py +++ b/src/device/service/monitoring/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/CommonObjects.py b/src/device/tests/CommonObjects.py index 61f0b44cd5715ac5e631c9e552fc61e7caa524d0..ce41c4a2ab585284c7646038b3c223fa8a8531a7 100644 --- a/src/device/tests/CommonObjects.py +++ b/src/device/tests/CommonObjects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,19 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Topology import json_topology, json_topology_id # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- KPI Sample Types ----------------------------------------------------------------------------------------------- diff --git a/src/device/tests/Device_Emulated.py b/src/device/tests/Device_Emulated.py index 7b8f15918146fcde9e920825e42e2985deeaee24..bb5dfa5f39e2e3ec3c07f9f49dc55e03c8e3c88d 100644 --- a/src/device/tests/Device_Emulated.py +++ b/src/device/tests/Device_Emulated.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -18,7 +18,7 @@ from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, json_device_id) from device.tests.CommonObjects import PACKET_PORT_SAMPLE_TYPES -DEVICE_EMU_UUID = 'EMULATED' +DEVICE_EMU_UUID = 'R1-EMU' DEVICE_EMU_ID = json_device_id(DEVICE_EMU_UUID) DEVICE_EMU = json_device_emulated_packet_router_disabled(DEVICE_EMU_UUID) DEVICE_EMU_EP_UUIDS = ['EP1', 'EP2', 'EP3', 'EP4'] diff --git a/src/device/tests/Device_Microwave_Template.py b/src/device/tests/Device_Microwave_Template.py index 710d28becad9c0bb50b639f3c5d0ef8fa1abe145..38e96e2b0fcf30282068334157d634d98164e2e5 100644 --- a/src/device/tests/Device_Microwave_Template.py +++ b/src/device/tests/Device_Microwave_Template.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/Device_OpenConfig_Template.py b/src/device/tests/Device_OpenConfig_Template.py index af339cce40b60f8ea0e310613c951968f4fc9aeb..8ab45337514bf354d8b338c8bb97721d099355f4 100644 --- a/src/device/tests/Device_OpenConfig_Template.py +++ b/src/device/tests/Device_OpenConfig_Template.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/Device_Transport_Api_Template.py b/src/device/tests/Device_Transport_Api_Template.py index ef4fa4d57700637121f7d64113c57120ffbc49a4..73408ebc070b8df3e07ddfaed19785b825a92975 100644 --- a/src/device/tests/Device_Transport_Api_Template.py +++ b/src/device/tests/Device_Transport_Api_Template.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/MockService_Dependencies.py b/src/device/tests/MockService_Dependencies.py index ba8d0ac56d74d2efa3e7964a3ae519bb355bff91..8216b0f8e07b1d76dbfd7b2a9d39909486636431 100644 --- a/src/device/tests/MockService_Dependencies.py +++ b/src/device/tests/MockService_Dependencies.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/PrepareTestScenario.py b/src/device/tests/PrepareTestScenario.py index 440bdac41ba792e5dbfd47e114516bb17be69859..c8e72dd77ff8b9d96290b996d346b4f2f2ac7c4b 100644 --- a/src/device/tests/PrepareTestScenario.py +++ b/src/device/tests/PrepareTestScenario.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/__init__.py b/src/device/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/device/tests/__init__.py +++ b/src/device/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/device_p4.py b/src/device/tests/device_p4.py index ccc62c2195c8dae41a8e98b128b08965954d57f0..de796c2f7c6e1d4d97a48999cece483b2156a43f 100644 --- a/src/device/tests/device_p4.py +++ b/src/device/tests/device_p4.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/mock_p4runtime_service.py b/src/device/tests/mock_p4runtime_service.py index c1b2dcb45a18caf0c839f9bd8a68484bba5efbea..f06a43bb84282fc7b87cb03df0c5d0fab1c98043 100644 --- a/src/device/tests/mock_p4runtime_service.py +++ b/src/device/tests/mock_p4runtime_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/mock_p4runtime_servicer_impl.py b/src/device/tests/mock_p4runtime_servicer_impl.py index 8a516303d9310be55662ef749175655c4069ae5c..65bcfab502105c826bd48d4dc6de928245cda4bd 100644 --- a/src/device/tests/mock_p4runtime_servicer_impl.py +++ b/src/device/tests/mock_p4runtime_servicer_impl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/test_internal_p4.py b/src/device/tests/test_internal_p4.py index 4907e538843dfa5d9c7833b4d02f05e483720510..a09ec79ef97e7b83f366f1b60966d3cc68134a37 100644 --- a/src/device/tests/test_internal_p4.py +++ b/src/device/tests/test_internal_p4.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/test_unitary_emulated.py b/src/device/tests/test_unitary_emulated.py index 745c25c1eba679dc67e0ed9e04f38eb0ae8c3af4..cbad108a848a6b0106330f7d22143910542997c3 100644 --- a/src/device/tests/test_unitary_emulated.py +++ b/src/device/tests/test_unitary_emulated.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -156,8 +156,8 @@ def test_device_emulated_configure( for config_rule in device_data.device_config.config_rules if config_rule.WhichOneof('config_rule') == 'custom' ] - #LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format( - # '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules]))) + LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format( + '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules]))) RESULTING_CONFIG_ENDPOINTS = {cr['custom']['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)} for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED: values = json.loads(RESULTING_CONFIG_ENDPOINTS[endpoint_cooked[0]]['custom']['resource_value']) @@ -168,12 +168,14 @@ def test_device_emulated_configure( config_rule = ( ConfigActionEnum.Name(config_rule['action']), config_rule['custom']['resource_key'], json.loads(json.dumps(config_rule['custom']['resource_value']))) + LOGGER.info('A config_rule: {:s} {:s} = {:s}'.format(*config_rule)) assert config_rule in config_rules for config_rule in DEVICE_EMU_CONFIG_ADDRESSES: assert 'custom' in config_rule config_rule = ( ConfigActionEnum.Name(config_rule['action']), config_rule['custom']['resource_key'], json.loads(json.dumps(config_rule['custom']['resource_value']))) + LOGGER.info('B config_rule: {:s} {:s} = {:s}'.format(*config_rule)) assert config_rule in config_rules # Try to reconfigure... @@ -222,6 +224,7 @@ def test_device_emulated_configure( config_rule = ( ConfigActionEnum.Name(config_rule['action']), config_rule['custom']['resource_key'], config_rule['custom']['resource_value']) + #LOGGER.info('config_rule: {:s} {:s} = {:s}'.format(*config_rule)) assert config_rule in config_rules @@ -376,7 +379,11 @@ def test_device_emulated_deconfigure( for config_rule in config_rules: assert config_rule.WhichOneof('config_rule') == 'custom' if config_rule.custom.resource_key.startswith('/endpoints/endpoint'): continue - config_rule_value = json.loads(config_rule.custom.resource_value) + if config_rule.custom.resource_key.startswith('_connect/'): continue + try: + config_rule_value = json.loads(config_rule.custom.resource_value) + except: # pylint: disable=bare-except + config_rule_value = config_rule.custom.resource_value if isinstance(config_rule_value, str) and config_rule_value.startswith('do_sampling (trigger:'): continue clean_config_rules.append(config_rule) LOGGER.info('clean_config_rules = {:s}'.format(str(clean_config_rules))) diff --git a/src/device/tests/test_unitary_microwave.py b/src/device/tests/test_unitary_microwave.py index 189984703ec7d6d9e68613624e3b759e133438ac..0d1ff61cf965ff20736a0a433ac0ac57eb1d541c 100644 --- a/src/device/tests/test_unitary_microwave.py +++ b/src/device/tests/test_unitary_microwave.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/test_unitary_openconfig.py b/src/device/tests/test_unitary_openconfig.py index 6144a95d96bbbfd68213356f06573a2200c11bb1..e61442a4a6b41108d49b52c4ca58d4a2826c786a 100644 --- a/src/device/tests/test_unitary_openconfig.py +++ b/src/device/tests/test_unitary_openconfig.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/test_unitary_p4.py b/src/device/tests/test_unitary_p4.py index 43313caff33d646918b9be23c87e499185714a2c..9370824cf39d53dbf9aec4a65e6d50ad7a253d09 100644 --- a/src/device/tests/test_unitary_p4.py +++ b/src/device/tests/test_unitary_p4.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/device/tests/test_unitary_tapi.py b/src/device/tests/test_unitary_tapi.py index 993c0c413d868471316aee6b3b1e313d3f449ceb..46962b2d9c48d1e27256a9dbb3f5c429208ac4ea 100644 --- a/src/device/tests/test_unitary_tapi.py +++ b/src/device/tests/test_unitary_tapi.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/.gitlab-ci.yml b/src/dlt/.gitlab-ci.yml index 3c2013f50904eb9cd366bf3e3b3cfce6d10c6fd6..df30a7b1deb3360fbf8b578796fa39f3b7e736ba 100644 --- a/src/dlt/.gitlab-ci.yml +++ b/src/dlt/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -109,20 +109,32 @@ unit test dlt-connector: - build dlt 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 --driver=bridge --subnet=172.28.0.0/24 --gateway=172.28.0.254 teraflowbridge; fi + - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create --driver=bridge teraflowbridge; fi - if docker container ls | grep ${IMAGE_NAME}-connector; then docker rm -f ${IMAGE_NAME}-connector; else echo "${IMAGE_NAME}-connector image is not in the system"; fi - if docker container ls | grep ${IMAGE_NAME}-gateway; then docker rm -f ${IMAGE_NAME}-gateway; else echo "${IMAGE_NAME}-gateway image is not in the system"; fi script: - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-connector:$IMAGE_TAG" - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-gateway:$IMAGE_TAG" - - docker run --name ${IMAGE_NAME}-gateway -d -p 50051:50051 -v "$PWD/src/${IMAGE_NAME}/gateway/tests:/opt/results" --network=teraflowbridge --ip 172.28.0.1 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-gateway:$IMAGE_TAG + - > + docker run --name ${IMAGE_NAME}-gateway -d -p 50051:50051 --network=teraflowbridge + --volume "$PWD/src/${IMAGE_NAME}/gateway/tests:/opt/results" + $CI_REGISTRY_IMAGE/${IMAGE_NAME}-gateway:$IMAGE_TAG + - DLT_GATEWAY_HOST=$(docker inspect ${IMAGE_NAME}-gateway --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}") + - echo $DLT_GATEWAY_HOST - sleep 1 - - docker run --name ${IMAGE_NAME}-connector -d -p 8080:8080 --env "DLT_GATEWAY_HOST=172.28.0.1" --env "DLT_GATEWAY_PORT=50051" -v "$PWD/src/${IMAGE_NAME}/connector/tests:/opt/results" --network=teraflowbridge --ip 172.28.0.2 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-connector:$IMAGE_TAG + - > + docker run --name ${IMAGE_NAME}-connector -d -p 8080:8080 --network=teraflowbridge + --volume "$PWD/src/${IMAGE_NAME}/connector/tests:/opt/results" + --env "DLT_GATEWAY_HOST=${DLT_GATEWAY_HOST}" + --env "DLT_GATEWAY_PORT=50051" + $CI_REGISTRY_IMAGE/${IMAGE_NAME}-connector:$IMAGE_TAG - sleep 5 - docker ps -a - docker logs ${IMAGE_NAME}-connector - docker logs ${IMAGE_NAME}-gateway - - docker exec -i ${IMAGE_NAME}-connector bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/connector/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}-connector_report.xml" + - > + docker exec -i ${IMAGE_NAME}-connector bash -c + "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/connector/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}-connector_report.xml" - docker exec -i ${IMAGE_NAME}-connector bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing" coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' after_script: diff --git a/src/dlt/__init__.py b/src/dlt/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/dlt/__init__.py +++ b/src/dlt/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/Config.py b/src/dlt/connector/Config.py index bdf9f306959e86160012541e8a72cc9aabb019c0..d89eda5d8dd956fe39d6a3e55fa10cf9f69a0715 100644 --- a/src/dlt/connector/Config.py +++ b/src/dlt/connector/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/Dockerfile b/src/dlt/connector/Dockerfile index c5d600ee0d55deb5a8bd4dca2d4f12cd092ad420..f4d85ec8c591041e920c7404acc862c3d5a4a560 100644 --- a/src/dlt/connector/Dockerfile +++ b/src/dlt/connector/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/__init__.py b/src/dlt/connector/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/dlt/connector/__init__.py +++ b/src/dlt/connector/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/client/DltConnectorClient.py b/src/dlt/connector/client/DltConnectorClient.py index 1ca511d0434dd72458982bf7c7d55d8bbd1859f1..55322ab58cf91735dbadea237c1a9c0b1461018d 100644 --- a/src/dlt/connector/client/DltConnectorClient.py +++ b/src/dlt/connector/client/DltConnectorClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/client/DltEventsCollector.py b/src/dlt/connector/client/DltEventsCollector.py index d022ac0f0144eecfcdb706665a8bde81fa54492f..9f929d7ccf4a8f54c6f87304ec05bb9086f8522c 100644 --- a/src/dlt/connector/client/DltEventsCollector.py +++ b/src/dlt/connector/client/DltEventsCollector.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/client/DltGatewayClient.py b/src/dlt/connector/client/DltGatewayClient.py index e2f5530f9a971d0a25cac042d361c52db5c16304..4654f470e307fa23d5e10c1db59c9ccb04f19fdc 100644 --- a/src/dlt/connector/client/DltGatewayClient.py +++ b/src/dlt/connector/client/DltGatewayClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/client/__init__.py b/src/dlt/connector/client/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/connector/client/__init__.py +++ b/src/dlt/connector/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/main_test.py b/src/dlt/connector/main_test.py index a877a5ce39a29dd8bf37416868d9c5a701912259..679be72870cf84b790553e2d43ed9961a1d66379 100644 --- a/src/dlt/connector/main_test.py +++ b/src/dlt/connector/main_test.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # pip install grpcio==1.47.0 grpcio-tools==1.47.0 protobuf==3.20.1 # PYTHONPATH=./src python # PYTHONPATH=/home/cttc/teraflow/src python -m dlt.connector.main_test diff --git a/src/dlt/connector/requirements.in b/src/dlt/connector/requirements.in index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/dlt/connector/requirements.in +++ b/src/dlt/connector/requirements.in @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/dlt/connector/service/DltConnectorService.py b/src/dlt/connector/service/DltConnectorService.py index 40237b628776f7053092b45d036072fbde35253c..b3e82253064e2758200fb3a6b4d34d5ccd71487f 100644 --- a/src/dlt/connector/service/DltConnectorService.py +++ b/src/dlt/connector/service/DltConnectorService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/service/DltConnectorServiceServicerImpl.py b/src/dlt/connector/service/DltConnectorServiceServicerImpl.py index 9af1ae6ead6fa66722e9d92d96ed07e2731c5ab4..4e628a2ae1c2d3d12b8a8dc4bcca5ba85faa4308 100644 --- a/src/dlt/connector/service/DltConnectorServiceServicerImpl.py +++ b/src/dlt/connector/service/DltConnectorServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/service/__init__.py b/src/dlt/connector/service/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/connector/service/__init__.py +++ b/src/dlt/connector/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/service/__main__.py b/src/dlt/connector/service/__main__.py index 76e7bc6f1bb1b50e736327d8f08c0880e45c6835..c9812f90a76ebb06e35bde23033758e5740b877a 100644 --- a/src/dlt/connector/service/__main__.py +++ b/src/dlt/connector/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/service/event_dispatcher/DltEventDispatcher.py b/src/dlt/connector/service/event_dispatcher/DltEventDispatcher.py index 8973ae621c1291f8ed6e2673f0c64b59712143ee..78d375efafc0329048654d34033bb46b00cb3bdf 100644 --- a/src/dlt/connector/service/event_dispatcher/DltEventDispatcher.py +++ b/src/dlt/connector/service/event_dispatcher/DltEventDispatcher.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import grpc, json, logging, threading from typing import Any, Dict, Set -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID, INTERDOMAIN_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.proto.context_pb2 import ContextId, Device, EventTypeEnum, Link, Slice, TopologyId from common.proto.dlt_connector_pb2 import DltSliceId from common.proto.dlt_gateway_pb2 import DltRecordEvent, DltRecordOperationEnum, DltRecordTypeEnum @@ -35,7 +35,7 @@ LOGGER = logging.getLogger(__name__) GET_EVENT_TIMEOUT = 0.5 -ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_UUID)) +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) class Clients: def __init__(self) -> None: @@ -66,9 +66,9 @@ class DltEventDispatcher(threading.Thread): def run(self) -> None: clients = Clients() - create_context(clients.context_client, DEFAULT_CONTEXT_UUID) - create_topology(clients.context_client, DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID) - create_topology(clients.context_client, DEFAULT_CONTEXT_UUID, INTERDOMAIN_TOPOLOGY_UUID) + create_context(clients.context_client, DEFAULT_CONTEXT_NAME) + create_topology(clients.context_client, DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME) + create_topology(clients.context_client, DEFAULT_CONTEXT_NAME, INTERDOMAIN_TOPOLOGY_NAME) dlt_events_collector = DltEventsCollector(clients.dlt_gateway_client, log_events_received=True) dlt_events_collector.start() @@ -81,8 +81,8 @@ class DltEventDispatcher(threading.Thread): local_domain_uuids = { topology_id.topology_uuid.uuid for topology_id in existing_topology_ids.topology_ids } - local_domain_uuids.discard(DEFAULT_TOPOLOGY_UUID) - local_domain_uuids.discard(INTERDOMAIN_TOPOLOGY_UUID) + local_domain_uuids.discard(DEFAULT_TOPOLOGY_NAME) + local_domain_uuids.discard(INTERDOMAIN_TOPOLOGY_NAME) self.dispatch_event(clients, local_domain_uuids, event) @@ -118,13 +118,13 @@ class DltEventDispatcher(threading.Thread): LOGGER.info('[_dispatch_device] record={:s}'.format(grpc_message_to_json_string(record))) create_context(clients.context_client, domain_uuid) - create_topology(clients.context_client, domain_uuid, DEFAULT_TOPOLOGY_UUID) + create_topology(clients.context_client, domain_uuid, DEFAULT_TOPOLOGY_NAME) device = Device(**json.loads(record.data_json)) clients.context_client.SetDevice(device) device_uuid = device.device_id.device_uuid.uuid # pylint: disable=no-member - add_device_to_topology(clients.context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_UUID, device_uuid) + add_device_to_topology(clients.context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME, device_uuid) domain_context_id = ContextId(**json_context_id(domain_uuid)) - add_device_to_topology(clients.context_client, domain_context_id, DEFAULT_TOPOLOGY_UUID, device_uuid) + add_device_to_topology(clients.context_client, domain_context_id, DEFAULT_TOPOLOGY_NAME, device_uuid) elif event_type in {EventTypeEnum.EVENTTYPE_DELETE}: raise NotImplementedError('Delete Device') @@ -148,7 +148,7 @@ class DltEventDispatcher(threading.Thread): link = Link(**json.loads(record.data_json)) clients.context_client.SetLink(link) link_uuid = link.link_id.link_uuid.uuid # pylint: disable=no-member - add_link_to_topology(clients.context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_UUID, link_uuid) + add_link_to_topology(clients.context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME, link_uuid) elif event_type in {EventTypeEnum.EVENTTYPE_DELETE}: raise NotImplementedError('Delete Link') @@ -165,7 +165,7 @@ class DltEventDispatcher(threading.Thread): context_uuid = slice_.slice_id.context_id.context_uuid.uuid owner_uuid = slice_.slice_owner.owner_uuid.uuid create_context(clients.context_client, context_uuid) - create_topology(clients.context_client, context_uuid, DEFAULT_TOPOLOGY_UUID) + create_topology(clients.context_client, context_uuid, DEFAULT_TOPOLOGY_NAME) if domain_uuid in local_domain_uuids: # it is for "me" diff --git a/src/dlt/connector/service/event_dispatcher/__init__.py b/src/dlt/connector/service/event_dispatcher/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/connector/service/event_dispatcher/__init__.py +++ b/src/dlt/connector/service/event_dispatcher/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/service/tools/Checkers.py b/src/dlt/connector/service/tools/Checkers.py index e25d8d5a5068ee927088697ad3453fba99a1f316..17a44c2fa2cc2a30216278bb4d84ff6469b099ff 100644 --- a/src/dlt/connector/service/tools/Checkers.py +++ b/src/dlt/connector/service/tools/Checkers.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/service/tools/__init__.py b/src/dlt/connector/service/tools/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/connector/service/tools/__init__.py +++ b/src/dlt/connector/service/tools/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/tests/MockService_Dependencies.py b/src/dlt/connector/tests/MockService_Dependencies.py index 65ddc3cb48cb878b2ab5ba8b5ec44479b0b71451..36e1ca5519a55fdfc864b266ed1f6f225c00af71 100644 --- a/src/dlt/connector/tests/MockService_Dependencies.py +++ b/src/dlt/connector/tests/MockService_Dependencies.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/tests/Objects.py b/src/dlt/connector/tests/Objects.py index f797e93e6f2f4f6597a667fff61b2b8ba1cbd72a..2ff850000a2d20b0556dc6e65a21b7151db849d6 100644 --- a/src/dlt/connector/tests/Objects.py +++ b/src/dlt/connector/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/tests/PrepareTestScenario.py b/src/dlt/connector/tests/PrepareTestScenario.py index 5c5d1cb5cc1c6868a5b47d929f026deecbe52f52..755d2f1ff615e23396dd33d02c6f8a3719be6065 100644 --- a/src/dlt/connector/tests/PrepareTestScenario.py +++ b/src/dlt/connector/tests/PrepareTestScenario.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,98 +12,98 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, pytest -from typing import Tuple -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.orm.Database import Database -from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum -from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum -from common.message_broker.MessageBroker import MessageBroker -from context.client.ContextClient import ContextClient -from context.service.grpc_server.ContextService import ContextService -from dlt.connector.client.DltConnectorClient import DltConnectorClient -from dlt.connector.service.DltConnectorService import DltConnectorService -from .MockService_Dependencies import MockService_Dependencies - -LOCAL_HOST = '127.0.0.1' -MOCKSERVICE_PORT = 10000 -#GRPC_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.CONTEXT) # avoid privileged ports -#os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST )] = str(LOCAL_HOST) -#os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(GRPC_PORT) - -# ===== BlockChain Emulator (Mock DLT Gateway) ========================================================================= -# A single gateway is used for all the domains - -@pytest.fixture(scope='session') -def dltgateway_service(): - _service = MockService_Dependencies(MOCKSERVICE_PORT) - _service.configure_env_vars() - _service.start() - yield _service - _service.stop() - -# ===== Domain A (Real Context + Real DLT Connector) =================================================================== - -@pytest.fixture(scope='session') -def context_service_a(): # pylint: disable=redefined-outer-name - _database = Database(get_database_backend(backend=DatabaseBackendEnum.INMEMORY)) - _message_broker = MessageBroker(get_messagebroker_backend(backend=MessageBrokerBackendEnum.INMEMORY)) - _service = ContextService(_database, _message_broker) - _service.start() - yield _service - _service.stop() - _message_broker.terminate() - -@pytest.fixture(scope='session') -def context_client_a(context_service_a : ContextService): # pylint: disable=redefined-outer-name - _client = ContextClient(host=context_service_a.bind_address, port=context_service_a.bind_port) - yield _client - _client.close() - -@pytest.fixture(scope='session') -def dltconnector_service_a(): - _service = DltConnectorService() - _service.bind_port += 1 - _service.start() - yield _service - _service.stop() - -@pytest.fixture(scope='session') -def dltconnector_client_a(dltconnector_service_a : DltConnectorService): # pylint: disable=redefined-outer-name - _client = DltConnectorClient(host=dltconnector_service_a.bind_address, port=dltconnector_service_a.bind_port) - yield _client - _client.close() - -# ===== Domain B (Real Context + Real DLT Connector) =================================================================== - -@pytest.fixture(scope='session') -def context_service_b(): # pylint: disable=redefined-outer-name - _database = Database(get_database_backend(backend=DatabaseBackendEnum.INMEMORY)) - _message_broker = MessageBroker(get_messagebroker_backend(backend=MessageBrokerBackendEnum.INMEMORY)) - _service = ContextService(_database, _message_broker) - _service.start() - yield _service - _service.stop() - _message_broker.terminate() - -@pytest.fixture(scope='session') -def context_client_b(context_service_b : ContextService): # pylint: disable=redefined-outer-name - _client = ContextClient(host=context_service_b.bind_address, port=context_service_b.bind_port) - yield _client - _client.close() - -@pytest.fixture(scope='session') -def dltconnector_service_b(): - _service = DltConnectorService() - _service.bind_port += 2 - _service.start() - yield _service - _service.stop() - -@pytest.fixture(scope='session') -def dltconnector_client_b(dltconnector_service_b : DltConnectorService): # pylint: disable=redefined-outer-name - _client = DltConnectorClient(host=dltconnector_service_b.bind_address, port=dltconnector_service_b.bind_port) - yield _client - _client.close() +#import os, pytest +#from typing import Tuple +#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.orm.Database import Database +#from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum +#from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum +#from common.message_broker.MessageBroker import MessageBroker +#from context.client.ContextClient import ContextClient +#from context.service.grpc_server.ContextService import ContextService +#from dlt.connector.client.DltConnectorClient import DltConnectorClient +#from dlt.connector.service.DltConnectorService import DltConnectorService +#from .MockService_Dependencies import MockService_Dependencies +# +#LOCAL_HOST = '127.0.0.1' +#MOCKSERVICE_PORT = 10000 +##GRPC_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.CONTEXT) # avoid privileged ports +##os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST )] = str(LOCAL_HOST) +##os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(GRPC_PORT) +# +## ===== BlockChain Emulator (Mock DLT Gateway) ========================================================================= +## A single gateway is used for all the domains +# +#@pytest.fixture(scope='session') +#def dltgateway_service(): +# _service = MockService_Dependencies(MOCKSERVICE_PORT) +# _service.configure_env_vars() +# _service.start() +# yield _service +# _service.stop() +# +## ===== Domain A (Real Context + Real DLT Connector) =================================================================== +# +#@pytest.fixture(scope='session') +#def context_service_a(): # pylint: disable=redefined-outer-name +# _database = Database(get_database_backend(backend=DatabaseBackendEnum.INMEMORY)) +# _message_broker = MessageBroker(get_messagebroker_backend(backend=MessageBrokerBackendEnum.INMEMORY)) +# _service = ContextService(_database, _message_broker) +# _service.start() +# yield _service +# _service.stop() +# _message_broker.terminate() +# +#@pytest.fixture(scope='session') +#def context_client_a(context_service_a : ContextService): # pylint: disable=redefined-outer-name +# _client = ContextClient(host=context_service_a.bind_address, port=context_service_a.bind_port) +# yield _client +# _client.close() +# +#@pytest.fixture(scope='session') +#def dltconnector_service_a(): +# _service = DltConnectorService() +# _service.bind_port += 1 +# _service.start() +# yield _service +# _service.stop() +# +#@pytest.fixture(scope='session') +#def dltconnector_client_a(dltconnector_service_a : DltConnectorService): # pylint: disable=redefined-outer-name +# _client = DltConnectorClient(host=dltconnector_service_a.bind_address, port=dltconnector_service_a.bind_port) +# yield _client +# _client.close() +# +## ===== Domain B (Real Context + Real DLT Connector) =================================================================== +# +#@pytest.fixture(scope='session') +#def context_service_b(): # pylint: disable=redefined-outer-name +# _database = Database(get_database_backend(backend=DatabaseBackendEnum.INMEMORY)) +# _message_broker = MessageBroker(get_messagebroker_backend(backend=MessageBrokerBackendEnum.INMEMORY)) +# _service = ContextService(_database, _message_broker) +# _service.start() +# yield _service +# _service.stop() +# _message_broker.terminate() +# +#@pytest.fixture(scope='session') +#def context_client_b(context_service_b : ContextService): # pylint: disable=redefined-outer-name +# _client = ContextClient(host=context_service_b.bind_address, port=context_service_b.bind_port) +# yield _client +# _client.close() +# +#@pytest.fixture(scope='session') +#def dltconnector_service_b(): +# _service = DltConnectorService() +# _service.bind_port += 2 +# _service.start() +# yield _service +# _service.stop() +# +#@pytest.fixture(scope='session') +#def dltconnector_client_b(dltconnector_service_b : DltConnectorService): # pylint: disable=redefined-outer-name +# _client = DltConnectorClient(host=dltconnector_service_b.bind_address, port=dltconnector_service_b.bind_port) +# yield _client +# _client.close() diff --git a/src/dlt/connector/tests/__init__.py b/src/dlt/connector/tests/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/connector/tests/__init__.py +++ b/src/dlt/connector/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/connector/tests/test_unitary.py b/src/dlt/connector/tests/test_unitary.py index 00c1164e1becde1d56de2a6c53c51160a31fc6f7..edd96b4ec0d87dd2ddd79d3574ec45973ac1827e 100644 --- a/src/dlt/connector/tests/test_unitary.py +++ b/src/dlt/connector/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,43 +12,44 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging -from typing import Tuple -from common.orm.Database import Database -from common.message_broker.MessageBroker import MessageBroker -from common.proto.context_pb2 import Context, ContextId, Device, DeviceId, Link, LinkId, Topology, TopologyId -from context.client.ContextClient import ContextClient -from .PrepareTestScenario import ( - # pylint: disable=unused-import - dltgateway_service, - context_service_a, context_client_a, dltconnector_service_a, dltconnector_client_a, - context_service_b, context_client_b, dltconnector_service_b, dltconnector_client_b) -from .Objects import ( - DA_CONTEXTS, DA_TOPOLOGIES, DA_DEVICES, DA_LINKS, - DB_CONTEXTS, DB_TOPOLOGIES, DB_DEVICES, DB_LINKS) - -LOGGER = logging.getLogger(__name__) -LOGGER.setLevel(logging.DEBUG) - -def test_create_events( - context_client : ContextClient, # pylint: disable=redefined-outer-name - context_db_mb : Tuple[Database, MessageBroker]): # 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 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' ])) - - - - dltgateway_client = DltGatewayClient(host='127.0.0.1', port=50051) - dltgateway_collector = DltEventsCollector(dltgateway_client, log_events_received=True) - dltgateway_collector.start() - - dltgateway_collector.stop() +#import logging +#from typing import Tuple +#from common.orm.Database import Database +#from common.message_broker.MessageBroker import MessageBroker +#from common.proto.context_pb2 import Context, ContextId, Device, DeviceId, Link, LinkId, Topology, TopologyId +#from context.client.ContextClient import ContextClient +#from .PrepareTestScenario import ( +# # pylint: disable=unused-import +# dltgateway_service, +# context_service_a, context_client_a, dltconnector_service_a, dltconnector_client_a, +# context_service_b, context_client_b, dltconnector_service_b, dltconnector_client_b) +#from .Objects import ( +# DA_CONTEXTS, DA_TOPOLOGIES, DA_DEVICES, DA_LINKS, +# DB_CONTEXTS, DB_TOPOLOGIES, DB_DEVICES, DB_LINKS) +# +#LOGGER = logging.getLogger(__name__) +#LOGGER.setLevel(logging.DEBUG) +# +#def test_create_events( +# context_client : ContextClient, # pylint: disable=redefined-outer-name +# context_db_mb : Tuple[Database, MessageBroker]): # 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 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' ])) +# +# +# +# dltgateway_client = DltGatewayClient(host='127.0.0.1', port=50051) +# dltgateway_collector = DltEventsCollector(dltgateway_client, log_events_received=True) +# dltgateway_collector.start() +# +# dltgateway_collector.stop() +# \ No newline at end of file diff --git a/src/dlt/gateway/settings.gradle.kts b/src/dlt/gateway/settings.gradle.kts index 67683a7440a06dd490a07dce3e3858ec8242f1ea..9c09bb933a23509312b8dfac226caed41f55b053 100644 --- a/src/dlt/gateway/settings.gradle.kts +++ b/src/dlt/gateway/settings.gradle.kts @@ -1,3 +1,19 @@ +/* + * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + rootProject.name = "gateway" diff --git a/src/dlt/mock_blockchain/Dockerfile b/src/dlt/mock_blockchain/Dockerfile index 22199b5f8f442e6d4617a2aed2e1dec9ad13e31a..09fe5d399c8455f8fd898d6b4c9eb992c8c9d469 100644 --- a/src/dlt/mock_blockchain/Dockerfile +++ b/src/dlt/mock_blockchain/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/mock_blockchain/__init__.py b/src/dlt/mock_blockchain/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/mock_blockchain/__init__.py +++ b/src/dlt/mock_blockchain/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/mock_blockchain/requirements.in b/src/dlt/mock_blockchain/requirements.in index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/dlt/mock_blockchain/requirements.in +++ b/src/dlt/mock_blockchain/requirements.in @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/dlt/mock_blockchain/service/__init__.py b/src/dlt/mock_blockchain/service/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/dlt/mock_blockchain/service/__init__.py +++ b/src/dlt/mock_blockchain/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/dlt/mock_blockchain/service/__main__.py b/src/dlt/mock_blockchain/service/__main__.py index 359c6990addfcd9278496338c50320c152c1810f..e4cffac51064b68c2acc494410e51785c45cd437 100644 --- a/src/dlt/mock_blockchain/service/__main__.py +++ b/src/dlt/mock_blockchain/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/gitlab-ci.yml_generator.py b/src/gitlab-ci.yml_generator.py old mode 100755 new mode 100644 index 8e367eb02b85b74a38932a2bb57004712d7fb883..4a4ac389e1e4ec0bfa67270fc8665dfbc830b111 --- a/src/gitlab-ci.yml_generator.py +++ b/src/gitlab-ci.yml_generator.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/.gitlab-ci.yml b/src/interdomain/.gitlab-ci.yml index 23bad6cf3b604b6134325b72316d036a9e53b6fc..486c6d0a931ff18be59ddaaa0268fcb1adfbaa2c 100644 --- a/src/interdomain/.gitlab-ci.yml +++ b/src/interdomain/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/Config.py b/src/interdomain/Config.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/interdomain/Config.py +++ b/src/interdomain/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/Dockerfile b/src/interdomain/Dockerfile index ee1071896d0ab0838a2126a2abb9a77278461573..69fcf3d9c52b9dc6232a2a8f3051acba88987408 100644 --- a/src/interdomain/Dockerfile +++ b/src/interdomain/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/__init__.py b/src/interdomain/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/interdomain/__init__.py +++ b/src/interdomain/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/client/InterdomainClient.py b/src/interdomain/client/InterdomainClient.py index 1f1ca924a972b85d9d1c848e1897b520d63adf93..f5631de61f9df3e35cac7efc1d768b9fbc9d5d7c 100644 --- a/src/interdomain/client/InterdomainClient.py +++ b/src/interdomain/client/InterdomainClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/client/__init__.py b/src/interdomain/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/interdomain/client/__init__.py +++ b/src/interdomain/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/requirements.in b/src/interdomain/requirements.in index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/interdomain/requirements.in +++ b/src/interdomain/requirements.in @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/interdomain/service/InterdomainService.py b/src/interdomain/service/InterdomainService.py index 28b57d64baefb601d2990f73e8da41e7cd9db724..59b6cd820d88caee36de7b2176d51523769ac947 100644 --- a/src/interdomain/service/InterdomainService.py +++ b/src/interdomain/service/InterdomainService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/service/InterdomainServiceServicerImpl.py b/src/interdomain/service/InterdomainServiceServicerImpl.py index 3fb3e72b9b7e2f4c8ea03f0bb2dfce76ac4fcbcd..b72fc1b3122c3d04bde5394ae33d973fa33fa3b8 100644 --- a/src/interdomain/service/InterdomainServiceServicerImpl.py +++ b/src/interdomain/service/InterdomainServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,13 +13,13 @@ # limitations under the License. import grpc, logging, uuid -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_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 from common.tools.context_queries.Context import create_context from common.tools.context_queries.InterDomain import ( - compute_interdomain_path, compute_traversed_domains, get_local_device_uuids, is_inter_domain, is_multi_domain) + compute_interdomain_path, compute_traversed_domains, get_local_device_uuids, is_inter_domain) from common.tools.context_queries.Topology import create_topology from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Topology import json_topology_id @@ -35,6 +35,8 @@ 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...') @@ -93,9 +95,9 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): LOGGER.info('[loop] [local] domain_uuid={:s} is_local_domain={:s} slice_uuid={:s}'.format( str(domain_uuid), str(is_local_domain), str(slice_uuid))) - # local slices always in DEFAULT_CONTEXT_UUID + # local slices always in DEFAULT_CONTEXT_NAME #context_uuid = request.slice_id.context_id.context_uuid.uuid - context_uuid = DEFAULT_CONTEXT_UUID + context_uuid = DEFAULT_CONTEXT_NAME endpoint_ids = map_abstract_endpoints_to_real(context_client, domain_uuid, endpoint_ids) sub_slice = compose_slice( context_uuid, slice_uuid, endpoint_ids, constraints=request.slice_constraints, @@ -109,14 +111,28 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): # create context/topology for the remote domains where we are creating slices create_context(context_client, domain_uuid) - create_topology(context_client, domain_uuid, DEFAULT_TOPOLOGY_UUID) + create_topology(context_client, domain_uuid, DEFAULT_TOPOLOGY_NAME) + sub_slice = compose_slice( domain_uuid, slice_uuid, endpoint_ids, constraints=request.slice_constraints, config_rules=request.slice_config.config_rules, owner_uuid=slice_owner_uuid) LOGGER.info('[loop] [remote] sub_slice={:s}'.format(grpc_message_to_json_string(sub_slice))) sub_slice_id = context_client.SetSlice(sub_slice) - topology_id = TopologyId(**json_topology_id(domain_uuid)) - dlt_record_sender.add_slice(topology_id, sub_slice) + + if USE_DLT: + topology_id = TopologyId(**json_topology_id(domain_uuid)) + dlt_record_sender.add_slice(topology_id, sub_slice) + else: + interdomain_client = self.remote_domain_clients.get_peer('remote-teraflow') + sub_slice_reply = interdomain_client.LookUpSlice(sub_slice) + if sub_slice_reply == sub_slice.slice_id: # pylint: disable=no-member + # successful case + remote_sub_slice = interdomain_client.OrderSliceFromCatalog(sub_slice) + else: + # not in catalog + remote_sub_slice = interdomain_client.CreateSliceAndAddToCatalog(sub_slice) + if remote_sub_slice.slice_status.slice_status != SliceStatusEnum.SLICESTATUS_ACTIVE: + raise Exception('Remote Slice creation failed. Wrong Slice status returned') LOGGER.info('[loop] adding sub-slice') reply.slice_subslice_ids.add().CopyFrom(sub_slice_id) # pylint: disable=no-member @@ -158,6 +174,6 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): context_client = ContextClient() slice_client = SliceClient() reply = slice_client.CreateSlice(request) - if reply != request.slice_id: # pylint: disable=no-member + if reply != request.slice_id: raise Exception('Slice creation failed. Wrong Slice Id was returned') return context_client.GetSlice(request.slice_id) diff --git a/src/interdomain/service/RemoteDomainClients.py b/src/interdomain/service/RemoteDomainClients.py index 0aaadfeff0aa05ab0d356b00069a6ec86e89926d..297c9a60d0cc4c67fda7f746e5fead1837b9d4ee 100644 --- a/src/interdomain/service/RemoteDomainClients.py +++ b/src/interdomain/service/RemoteDomainClients.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import logging, socket -from common.Constants import DEFAULT_CONTEXT_UUID, ServiceNameEnum +from common.Constants import DEFAULT_CONTEXT_NAME, ServiceNameEnum from common.Settings import get_service_host, get_service_port_grpc from common.proto.context_pb2 import TeraFlowController from interdomain.client.InterdomainClient import InterdomainClient @@ -25,7 +25,7 @@ class RemoteDomainClients: self.peer_domain = {} def add_peer( - self, domain_name : str, host : str, port : int, context_uuid : str = DEFAULT_CONTEXT_UUID + self, domain_name : str, host : str, port : int, context_uuid : str = DEFAULT_CONTEXT_NAME ) -> None: while True: try: @@ -36,7 +36,7 @@ class RemoteDomainClients: interdomain_client = InterdomainClient(host=host, port=port) request = TeraFlowController() - request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID # pylint: disable=no-member + request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME # pylint: disable=no-member request.ip_address = get_service_host(ServiceNameEnum.INTERDOMAIN) request.port = int(get_service_port_grpc(ServiceNameEnum.INTERDOMAIN)) diff --git a/src/interdomain/service/Tools.py b/src/interdomain/service/Tools.py index fb6371603ea90437437541bb995a59813764d9ef..609dc6e07815de80d6d18f7464ce164ea3e14332 100644 --- a/src/interdomain/service/Tools.py +++ b/src/interdomain/service/Tools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import json, logging from typing import List, Optional, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID, INTERDOMAIN_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.proto.context_pb2 import ( ConfigRule, Constraint, ContextId, Device, Empty, EndPointId, Slice, SliceStatusEnum) from common.tools.context_queries.CheckType import device_type_is_network, endpoint_type_is_border @@ -32,12 +32,12 @@ def compute_slice_owner( ) -> Optional[str]: traversed_domain_uuids = {traversed_domain[0] for traversed_domain in traversed_domains} - existing_topology_ids = context_client.ListTopologyIds(ContextId(**json_context_id(DEFAULT_CONTEXT_UUID))) + existing_topology_ids = context_client.ListTopologyIds(ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))) existing_topology_uuids = { topology_id.topology_uuid.uuid for topology_id in existing_topology_ids.topology_ids } - existing_topology_uuids.discard(DEFAULT_TOPOLOGY_UUID) - existing_topology_uuids.discard(INTERDOMAIN_TOPOLOGY_UUID) + existing_topology_uuids.discard(DEFAULT_TOPOLOGY_NAME) + existing_topology_uuids.discard(INTERDOMAIN_TOPOLOGY_NAME) candidate_owner_uuids = traversed_domain_uuids.intersection(existing_topology_uuids) if len(candidate_owner_uuids) != 1: diff --git a/src/interdomain/service/__init__.py b/src/interdomain/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/interdomain/service/__init__.py +++ b/src/interdomain/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/service/__main__.py b/src/interdomain/service/__main__.py index bcbda8dfda05ec7b245b5939d8a3afc4b979562f..f4bdbb7b80ca3f355a92268e74d28e02f7883302 100644 --- a/src/interdomain/service/__main__.py +++ b/src/interdomain/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/service/_old_code/InterdomainServiceServicerImpl.py b/src/interdomain/service/_old_code/InterdomainServiceServicerImpl.py index f3818578186360365e3b828810d942def5722cea..e80f5c712ac2c47644cac609489761c67ffb69eb 100644 --- a/src/interdomain/service/_old_code/InterdomainServiceServicerImpl.py +++ b/src/interdomain/service/_old_code/InterdomainServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -108,16 +108,14 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): slice_endpoint_id.device_id.device_uuid.uuid = 'R1@D2' slice_endpoint_id.endpoint_uuid.uuid = '2/1' - local_slice_reply = slice_client.CreateSlice(local_slice_request) - if local_slice_reply != local_slice_request.slice_id: # pylint: disable=no-member - raise Exception('Local Slice creation failed. Wrong Slice Id was returned') + local_slice_id_reply = slice_client.CreateSlice(local_slice_request) subslice_id = reply.slice_subslice_ids.add() - subslice_id.context_id.context_uuid.uuid = local_slice_request.slice_id.context_id.context_uuid.uuid - subslice_id.slice_uuid.uuid = local_slice_request.slice_id.slice_uuid.uuid + subslice_id.context_id.context_uuid.uuid = local_slice_id_reply.context_id.context_uuid.uuid + subslice_id.slice_uuid.uuid = local_slice_id_reply.slice_uuid.uuid - context_client.SetSlice(reply) - return reply.slice_id + reply_slice_id = context_client.SetSlice(reply) + return reply_slice_id @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def Authenticate(self, request : TeraFlowController, context : grpc.ServicerContext) -> AuthenticationResult: diff --git a/src/interdomain/service/topology_abstractor/AbstractDevice.py b/src/interdomain/service/topology_abstractor/AbstractDevice.py index 3448c1036d4ef086d679d5f4308ae95decfbffa7..0de93daa8c6e7a77b696cdf437d6e870d33b3666 100644 --- a/src/interdomain/service/topology_abstractor/AbstractDevice.py +++ b/src/interdomain/service/topology_abstractor/AbstractDevice.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import copy, logging from typing import Dict, Optional -from common.Constants import DEFAULT_CONTEXT_UUID, INTERDOMAIN_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.DeviceTypes import DeviceTypeEnum from common.proto.context_pb2 import ( ContextId, Device, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, EndPoint) @@ -67,9 +67,9 @@ class AbstractDevice: is_datacenter = device_type_is_datacenter(self.__device_type) is_network = device_type_is_network(self.__device_type) if is_datacenter or is_network: - # Add abstract device to topologies [INTERDOMAIN_TOPOLOGY_UUID] - context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_UUID)) - topology_uuids = [INTERDOMAIN_TOPOLOGY_UUID] + # Add abstract device to topologies [INTERDOMAIN_TOPOLOGY_NAME] + context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) + topology_uuids = [INTERDOMAIN_TOPOLOGY_NAME] for topology_uuid in topology_uuids: add_device_to_topology(self.__context_client, context_id, topology_uuid, self.__device_uuid) @@ -80,7 +80,7 @@ class AbstractDevice: # self.update_endpoints(dc_device) #elif is_network: # devices_in_admin_topology = get_devices_in_topology( - # self.__context_client, context_id, DEFAULT_TOPOLOGY_UUID) + # self.__context_client, context_id, DEFAULT_TOPOLOGY_NAME) # for device in devices_in_admin_topology: # if device_type_is_datacenter(device.device_type): continue # self.update_endpoints(device) diff --git a/src/interdomain/service/topology_abstractor/AbstractLink.py b/src/interdomain/service/topology_abstractor/AbstractLink.py index 7fe7b07b0708ebf8490cf4304646037973b05d56..bdab62476c709de7d3fa2c4de2dba687714aba77 100644 --- a/src/interdomain/service/topology_abstractor/AbstractLink.py +++ b/src/interdomain/service/topology_abstractor/AbstractLink.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import copy, logging from typing import Dict, List, Optional, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, INTERDOMAIN_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.proto.context_pb2 import ContextId, EndPointId, Link, LinkId from common.tools.context_queries.Link import add_link_to_topology, get_existing_link_uuids from common.tools.object_factory.Context import json_context_id @@ -67,9 +67,9 @@ class AbstractLink: else: self._load_existing() - # Add abstract link to topologies [INTERDOMAIN_TOPOLOGY_UUID] - context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_UUID)) - topology_uuids = [INTERDOMAIN_TOPOLOGY_UUID] + # Add abstract link to topologies [INTERDOMAIN_TOPOLOGY_NAME] + context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) + topology_uuids = [INTERDOMAIN_TOPOLOGY_NAME] for topology_uuid in topology_uuids: add_link_to_topology(self.__context_client, context_id, topology_uuid, self.__link_uuid) diff --git a/src/interdomain/service/topology_abstractor/DltRecordSender.py b/src/interdomain/service/topology_abstractor/DltRecordSender.py index f7e3d81dded18c7406b54389cbe128c0fd27d7b4..d6efbc809ef848067d7ee496dca300ab8a04f406 100644 --- a/src/interdomain/service/topology_abstractor/DltRecordSender.py +++ b/src/interdomain/service/topology_abstractor/DltRecordSender.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/service/topology_abstractor/TopologyAbstractor.py b/src/interdomain/service/topology_abstractor/TopologyAbstractor.py index 5729fe733c3a9a8f73f188b40338160ab286998b..bdbf016f85a0c58969b7a58677f9695e2635c8c0 100644 --- a/src/interdomain/service/topology_abstractor/TopologyAbstractor.py +++ b/src/interdomain/service/topology_abstractor/TopologyAbstractor.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import logging, threading from typing import Dict, Optional, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID, INTERDOMAIN_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.DeviceTypes import DeviceTypeEnum from common.proto.context_pb2 import ( ContextEvent, ContextId, Device, DeviceEvent, DeviceId, EndPoint, EndPointId, Link, LinkEvent, TopologyId, @@ -39,8 +39,8 @@ from .Types import EventTypes LOGGER = logging.getLogger(__name__) -ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_UUID)) -INTERDOMAIN_TOPOLOGY_ID = TopologyId(**json_topology_id(INTERDOMAIN_TOPOLOGY_UUID, context_id=ADMIN_CONTEXT_ID)) +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) +INTERDOMAIN_TOPOLOGY_ID = TopologyId(**json_topology_id(INTERDOMAIN_TOPOLOGY_NAME, context_id=ADMIN_CONTEXT_ID)) class TopologyAbstractor(threading.Thread): def __init__(self) -> None: @@ -65,8 +65,8 @@ class TopologyAbstractor(threading.Thread): def run(self) -> None: self.context_client.connect() - create_context(self.context_client, DEFAULT_CONTEXT_UUID) - topology_uuids = [DEFAULT_TOPOLOGY_UUID, INTERDOMAIN_TOPOLOGY_UUID] + create_context(self.context_client, DEFAULT_CONTEXT_NAME) + topology_uuids = [DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME] create_missing_topologies(self.context_client, ADMIN_CONTEXT_ID, topology_uuids) self.dlt_connector_client.connect() @@ -96,7 +96,7 @@ class TopologyAbstractor(threading.Thread): # context_uuid = event.topology_id.context_id.context_uuid.uuid # if context_uuid != own_context_uuid: return True # topology_uuid = event.topology_id.topology_uuid.uuid - # if topology_uuid in {INTERDOMAIN_TOPOLOGY_UUID}: return True + # if topology_uuid in {INTERDOMAIN_TOPOLOGY_NAME}: return True # # return False @@ -200,7 +200,7 @@ class TopologyAbstractor(threading.Thread): device_uuid = device.device_id.device_uuid.uuid interdomain_device_uuids = get_uuids_of_devices_in_topology( - self.context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_UUID) + self.context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) for endpoint in device.device_endpoints: if not endpoint_type_is_border(endpoint.endpoint_type): continue @@ -236,8 +236,8 @@ class TopologyAbstractor(threading.Thread): topology_uuid = topology_id.topology_uuid.uuid context_id = topology_id.context_id context_uuid = context_id.context_uuid.uuid - topology_uuids = {DEFAULT_TOPOLOGY_UUID, INTERDOMAIN_TOPOLOGY_UUID} - if (context_uuid == DEFAULT_CONTEXT_UUID) and (topology_uuid not in topology_uuids): + topology_uuids = {DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME} + if (context_uuid == DEFAULT_CONTEXT_NAME) and (topology_uuid not in topology_uuids): abstract_topology_id = TopologyId(**json_topology_id(topology_uuid, context_id=ADMIN_CONTEXT_ID)) self._get_or_create_abstract_device( topology_uuid, DeviceTypeEnum.NETWORK, dlt_record_sender, abstract_topology_id) diff --git a/src/interdomain/service/topology_abstractor/Types.py b/src/interdomain/service/topology_abstractor/Types.py index f6a0fa7a1d7a564045b6e850c2b46cf313da52b7..fa1d135da932481cc19df9286a0af7fa62aff348 100644 --- a/src/interdomain/service/topology_abstractor/Types.py +++ b/src/interdomain/service/topology_abstractor/Types.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/service/topology_abstractor/__init__.py b/src/interdomain/service/topology_abstractor/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/interdomain/service/topology_abstractor/__init__.py +++ b/src/interdomain/service/topology_abstractor/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/tests/__init__.py b/src/interdomain/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/interdomain/tests/__init__.py +++ b/src/interdomain/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/interdomain/tests/test_unitary.py b/src/interdomain/tests/test_unitary.py index 7fe1acc7cec5cbf3663dc7db68c45a22b56d3a6d..403dea54334da54a794b6da40dd64d1e6e856034 100644 --- a/src/interdomain/tests/test_unitary.py +++ b/src/interdomain/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/.gitlab-ci.yml b/src/l3_attackmitigator/.gitlab-ci.yml index bcad35c74b3ca2f427b54831f313db855657c821..c43b553a406bdbaf4cf77f80360469b87dd1c3e4 100644 --- a/src/l3_attackmitigator/.gitlab-ci.yml +++ b/src/l3_attackmitigator/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/Config.py b/src/l3_attackmitigator/Config.py index 429977bc585a01fb288aab121cdb3cedb8fa9ac0..fafeb8d11d1ec5e5dd2da16c699161ea03f4995d 100644 --- a/src/l3_attackmitigator/Config.py +++ b/src/l3_attackmitigator/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/Dockerfile b/src/l3_attackmitigator/Dockerfile index 2b814f0eed8fbfba96a759212ae5ff0e2172c14f..da9ed75ad4f627b5f5f54d21c2f1a8544a600e03 100644 --- a/src/l3_attackmitigator/Dockerfile +++ b/src/l3_attackmitigator/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/__init__.py b/src/l3_attackmitigator/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_attackmitigator/__init__.py +++ b/src/l3_attackmitigator/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/client/__init__.py b/src/l3_attackmitigator/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_attackmitigator/client/__init__.py +++ b/src/l3_attackmitigator/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/client/l3_attackmitigatorClient.py b/src/l3_attackmitigator/client/l3_attackmitigatorClient.py index 77e09a2f718fb7d0748666842117f60652bebdea..fad553cc25ce655ed6ba6435b6511cf440774950 100644 --- a/src/l3_attackmitigator/client/l3_attackmitigatorClient.py +++ b/src/l3_attackmitigator/client/l3_attackmitigatorClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/requirements.in b/src/l3_attackmitigator/requirements.in index 772ae923931c8b09917e75a600ce2b5a0d2d4ecf..a8aba849708799232f6b0732c3661396266da329 100644 --- a/src/l3_attackmitigator/requirements.in +++ b/src/l3_attackmitigator/requirements.in @@ -1 +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. + # no extra dependency diff --git a/src/l3_attackmitigator/service/__init__.py b/src/l3_attackmitigator/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_attackmitigator/service/__init__.py +++ b/src/l3_attackmitigator/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/service/__main__.py b/src/l3_attackmitigator/service/__main__.py index ac2ff528ae2df5d0604978534a256e111080d181..1e91d5e9729f027b096afa97d1808795193dc2fa 100644 --- a/src/l3_attackmitigator/service/__main__.py +++ b/src/l3_attackmitigator/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/service/l3_attackmitigatorService.py b/src/l3_attackmitigator/service/l3_attackmitigatorService.py index 2ce7f93169430d586ba33a03f03918966c8dcc7b..84ab811ef944808e042712191dfef7d2646f4926 100644 --- a/src/l3_attackmitigator/service/l3_attackmitigatorService.py +++ b/src/l3_attackmitigator/service/l3_attackmitigatorService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py b/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py index 8664704524ecef779235af3ca3dc765af7af4898..b697a83ff43c28a9051fb6465db3803ca1c068d8 100644 --- a/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py +++ b/src/l3_attackmitigator/service/l3_attackmitigatorServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/tests/__init__.py b/src/l3_attackmitigator/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_attackmitigator/tests/__init__.py +++ b/src/l3_attackmitigator/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_attackmitigator/tests/test_unitary.py b/src/l3_attackmitigator/tests/test_unitary.py index 14d43edaff85da0e2597c55557dde74dbaae32aa..8f048f876e28ac1fcd8517690056c71afe685f8e 100644 --- a/src/l3_attackmitigator/tests/test_unitary.py +++ b/src/l3_attackmitigator/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/.gitlab-ci.yml b/src/l3_centralizedattackdetector/.gitlab-ci.yml index 073b7925c7f7c39e1a44766fc21167236875877d..791b917524fa3ad2fa91e0bc4f928fcb60851341 100644 --- a/src/l3_centralizedattackdetector/.gitlab-ci.yml +++ b/src/l3_centralizedattackdetector/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/Config.py b/src/l3_centralizedattackdetector/Config.py index 2b7ec70f13e273c5913607f8b9cd4b6cb59555f7..f6c7e33553820b1214e5265cf219db629bcfe006 100644 --- a/src/l3_centralizedattackdetector/Config.py +++ b/src/l3_centralizedattackdetector/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/Dockerfile b/src/l3_centralizedattackdetector/Dockerfile index 3db5c2b4d7e4020b727d0d3f9b106f9c4af2e6b6..e5b9aa33b78b2593dc1df6d48edaf8c41b65a02b 100644 --- a/src/l3_centralizedattackdetector/Dockerfile +++ b/src/l3_centralizedattackdetector/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/__init__.py b/src/l3_centralizedattackdetector/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_centralizedattackdetector/__init__.py +++ b/src/l3_centralizedattackdetector/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/client/__init__.py b/src/l3_centralizedattackdetector/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_centralizedattackdetector/client/__init__.py +++ b/src/l3_centralizedattackdetector/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py b/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py index 3a159503c1c2d6b7387122430f1d36b77cd3ff78..f84bd84217c30e25c6e8ccfbb9b9e48c073a5ee5 100644 --- a/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py +++ b/src/l3_centralizedattackdetector/client/l3_centralizedattackdetectorClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/requirements.in b/src/l3_centralizedattackdetector/requirements.in index 9e25a1c28fb6c472e92bbb175eaa1c030fffe760..130abd9424379f173b5393a00d14337c582f31e9 100644 --- a/src/l3_centralizedattackdetector/requirements.in +++ b/src/l3_centralizedattackdetector/requirements.in @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + numpy==1.23.* onnxruntime==1.12.* scikit-learn==1.1.* diff --git a/src/l3_centralizedattackdetector/service/__init__.py b/src/l3_centralizedattackdetector/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_centralizedattackdetector/service/__init__.py +++ b/src/l3_centralizedattackdetector/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/service/__main__.py b/src/l3_centralizedattackdetector/service/__main__.py index 42c7412cb85a7c168d09347eda32d73ea61dbf0e..3408127242a01c110263d14947d63e64cfaa79a2 100644 --- a/src/l3_centralizedattackdetector/service/__main__.py +++ b/src/l3_centralizedattackdetector/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py index bad8cee7eadc26ceaf4dddd8a8452b3b8636e1d9..bf58247d3c6467b6f9b3ca7d0dcbc9c5239195c4 100644 --- a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py +++ b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py index ad05b0ee62e87ce9028dc043b693c1b4cae008b3..dfe67813f875cbbc3173460efed73b212ba0ee0f 100644 --- a/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py +++ b/src/l3_centralizedattackdetector/service/l3_centralizedattackdetectorServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/service/ml_model/teraflow_rf.onnx b/src/l3_centralizedattackdetector/service/ml_model/teraflow_rf.onnx index e2bd04b7be0b6f0d60e1172448952388bb9edb6b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 Binary files a/src/l3_centralizedattackdetector/service/ml_model/teraflow_rf.onnx and b/src/l3_centralizedattackdetector/service/ml_model/teraflow_rf.onnx differ diff --git a/src/l3_centralizedattackdetector/tests/__init__.py b/src/l3_centralizedattackdetector/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_centralizedattackdetector/tests/__init__.py +++ b/src/l3_centralizedattackdetector/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_centralizedattackdetector/tests/test_unitary.py b/src/l3_centralizedattackdetector/tests/test_unitary.py index a939b9efa11c9ceeb96ccb6d04c9ec929ab55cda..4d28755c02a1f68fb74e9b2b852aee51984f4b73 100644 --- a/src/l3_centralizedattackdetector/tests/test_unitary.py +++ b/src/l3_centralizedattackdetector/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/.gitlab-ci.yml b/src/l3_distributedattackdetector/.gitlab-ci.yml index c373d223715f77a833fdb3ea1c090e61f2e2c303..226cb642176a7d0854ee8dbdaf623cf7bcad1fc2 100644 --- a/src/l3_distributedattackdetector/.gitlab-ci.yml +++ b/src/l3_distributedattackdetector/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/Config.py b/src/l3_distributedattackdetector/Config.py index 73d3e471a2fc1b4ccc2a053064abd70e0b145a0f..e04de0b2622b621fb95f1c382ac3a152836de760 100644 --- a/src/l3_distributedattackdetector/Config.py +++ b/src/l3_distributedattackdetector/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/Dockerfile b/src/l3_distributedattackdetector/Dockerfile index 4bdbcf03cebc6f89603cde6d8ea41e28d6bd157c..e78c41803f4b80a129ad9537265f68885f0a6d3b 100644 --- a/src/l3_distributedattackdetector/Dockerfile +++ b/src/l3_distributedattackdetector/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/__init__.py b/src/l3_distributedattackdetector/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_distributedattackdetector/__init__.py +++ b/src/l3_distributedattackdetector/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/requirements.in b/src/l3_distributedattackdetector/requirements.in index 772ae923931c8b09917e75a600ce2b5a0d2d4ecf..a8aba849708799232f6b0732c3661396266da329 100644 --- a/src/l3_distributedattackdetector/requirements.in +++ b/src/l3_distributedattackdetector/requirements.in @@ -1 +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. + # no extra dependency diff --git a/src/l3_distributedattackdetector/service/__init__.py b/src/l3_distributedattackdetector/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_distributedattackdetector/service/__init__.py +++ b/src/l3_distributedattackdetector/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/service/__main__.py b/src/l3_distributedattackdetector/service/__main__.py index 1ce6831f22e63b482031f919f040ad1182c4e2d4..1f558dfb6c271cf63a9e36ae06cb9993f7e49c57 100644 --- a/src/l3_distributedattackdetector/service/__main__.py +++ b/src/l3_distributedattackdetector/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/tests/__init__.py b/src/l3_distributedattackdetector/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/l3_distributedattackdetector/tests/__init__.py +++ b/src/l3_distributedattackdetector/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/tests/data_generator.py b/src/l3_distributedattackdetector/tests/data_generator.py index 43c3d707c8ccd52ccc63afdc7278bf67ec3f628a..bd65566389b1dbfa3d42c6ae55e72d15f8f9c608 100644 --- a/src/l3_distributedattackdetector/tests/data_generator.py +++ b/src/l3_distributedattackdetector/tests/data_generator.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/l3_distributedattackdetector/tests/test_unitary.py b/src/l3_distributedattackdetector/tests/test_unitary.py index 0e868d7815ec0c3837bb2e9a1e439b98f3674f39..88e3dda986056e70f22cafc6124f0edc6770ee3e 100644 --- a/src/l3_distributedattackdetector/tests/test_unitary.py +++ b/src/l3_distributedattackdetector/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/load_generator/.gitlab-ci.yml b/src/load_generator/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..5f2ee0d76105e57d31b0a6596d020ef53e65a631 --- /dev/null +++ b/src/load_generator/.gitlab-ci.yml @@ -0,0 +1,39 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Build, tag, and push the Docker image to the GitLab Docker registry +build load_generator: + variables: + IMAGE_NAME: 'load_generator' # 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/common/**/*.py + - proto/*.proto + - src/$IMAGE_NAME/**/*.{py,in,yml} + - src/$IMAGE_NAME/Dockerfile + - src/$IMAGE_NAME/tests/*.py + - manifests/${IMAGE_NAME}service.yaml + - .gitlab-ci.yml diff --git a/src/load_generator/Config.py b/src/load_generator/Config.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/Config.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/load_generator/Dockerfile b/src/load_generator/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..c9297eb2fa08047ff1883f8c350ebbd1d0b5dd8c --- /dev/null +++ b/src/load_generator/Dockerfile @@ -0,0 +1,77 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 + +# 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 +RUN python3 -m pip install --upgrade setuptools wheel +RUN python3 -m pip install --upgrade pip-tools + +# Get common Python packages +# Note: this step enables sharing the previous Docker build steps among all the Python components +WORKDIR /var/teraflow +COPY common_requirements.in common_requirements.in +RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in +RUN python3 -m pip install -r common_requirements.txt + +# Add common files into working directory +WORKDIR /var/teraflow/common +COPY src/common/. ./ +RUN rm -rf proto + +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /var/teraflow/common/proto +WORKDIR /var/teraflow/common/proto +RUN touch __init__.py +COPY proto/*.proto ./ +RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto +RUN rm *.proto +RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \; + +# Create component sub-folders, get specific Python packages +RUN mkdir -p /var/teraflow/load_generator +WORKDIR /var/teraflow/load_generator +COPY src/load_generator/requirements.in requirements.in +RUN pip-compile --quiet --output-file=requirements.txt requirements.in +RUN python3 -m pip install -r requirements.txt + +# Add component files into working directory +WORKDIR /var/teraflow +COPY src/context/__init__.py context/__init__.py +COPY src/context/client/. context/client/ +COPY src/dlt/__init__.py dlt/__init__.py +COPY src/dlt/connector/__init__.py dlt/connector/__init__.py +COPY src/dlt/connector/. dlt/connector/ +COPY src/load_generator/. load_generator/ +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/ + +# Start the service +ENTRYPOINT ["python", "-m", "load_generator.service"] diff --git a/src/load_generator/README.md b/src/load_generator/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e6b0397bf435abb91f5e7c463da32367eba142cf --- /dev/null +++ b/src/load_generator/README.md @@ -0,0 +1,18 @@ +# Tool: Load Generator + +Simple tool to generate load in ETSI TeraFlowSDN controller with requests for creating services and slices. +The tool can be executed form command line or from WebUI interface. + +## Example (Command Line): + +Deploy TeraFlowSDN controller with your specific settings: +```(bash) +cd ~/tfs-ctrl +source my_deploy.sh +./deploy.sh +``` + +Run the tool: +```(bash) +./src/load_generator/run.sh +``` diff --git a/src/common/orm/backend/redis/__init__.py b/src/load_generator/__init__.py similarity index 88% rename from src/common/orm/backend/redis/__init__.py rename to src/load_generator/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/common/orm/backend/redis/__init__.py +++ b/src/load_generator/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/load_generator/client/LoadGeneratorClient.py b/src/load_generator/client/LoadGeneratorClient.py new file mode 100644 index 0000000000000000000000000000000000000000..99626bbbb59671af41c11054d34338194f42a6af --- /dev/null +++ b/src/load_generator/client/LoadGeneratorClient.py @@ -0,0 +1,60 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import grpc, logging +from common.Constants import ServiceNameEnum +from common.Settings import get_service_host, get_service_port_grpc +from common.proto.context_pb2 import Empty +from common.proto.load_generator_pb2_grpc import LoadGeneratorServiceStub +from common.tools.client.RetryDecorator import retry, delay_exponential +from common.tools.grpc.Tools import grpc_message_to_json_string + +LOGGER = logging.getLogger(__name__) +MAX_RETRIES = 15 +DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) +RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + +class LoadGeneratorClient: + def __init__(self, host=None, port=None): + if not host: host = get_service_host(ServiceNameEnum.LOAD_GENERATOR) + if not port: port = get_service_port_grpc(ServiceNameEnum.LOAD_GENERATOR) + self.endpoint = '{:s}:{:s}'.format(str(host), str(port)) + LOGGER.debug('Creating channel to {:s}...'.format(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 = LoadGeneratorServiceStub(self.channel) + + def close(self): + if self.channel is not None: self.channel.close() + self.channel = None + self.stub = None + + @RETRY_DECORATOR + def Start(self, request : Empty) -> Empty: + LOGGER.debug('Start request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.Start(request) + LOGGER.debug('Start result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def Stop(self, request : Empty) -> Empty: + LOGGER.debug('Stop request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.Stop(request) + LOGGER.debug('Stop result: {:s}'.format(grpc_message_to_json_string(response))) + return response diff --git a/src/common/orm/__init__.py b/src/load_generator/client/__init__.py similarity index 88% rename from src/common/orm/__init__.py rename to src/load_generator/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/common/orm/__init__.py +++ b/src/load_generator/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/load_generator/command/__init__.py b/src/load_generator/command/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/command/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/tests/tools/load_gen/__main__.py b/src/load_generator/command/__main__.py similarity index 79% rename from src/tests/tools/load_gen/__main__.py rename to src/load_generator/command/__main__.py index 8e732993892d5fb095a273c1d0e31bbe491226c8..5db77fb54bec6eae4d82deade2440bd40eb5f4b4 100644 --- a/src/tests/tools/load_gen/__main__.py +++ b/src/load_generator/command/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,10 +13,11 @@ # limitations under the License. import logging, sys -from .Constants import RequestType -from .Parameters import Parameters -from .RequestGenerator import RequestGenerator -from .RequestScheduler import RequestScheduler +from apscheduler.schedulers.blocking import BlockingScheduler +from load_generator.load_gen.Constants import RequestType +from load_generator.load_gen.Parameters import Parameters +from load_generator.load_gen.RequestGenerator import RequestGenerator +from load_generator.load_gen.RequestScheduler import RequestScheduler logging.basicConfig(level=logging.INFO) LOGGER = logging.getLogger(__name__) @@ -45,7 +46,7 @@ def main(): generator.initialize() LOGGER.info('Running Schedule...') - scheduler = RequestScheduler(parameters, generator) + scheduler = RequestScheduler(parameters, generator, scheduler_class=BlockingScheduler) scheduler.start() LOGGER.info('Done!') diff --git a/src/tests/tools/load_gen/Constants.py b/src/load_generator/load_gen/Constants.py similarity index 92% rename from src/tests/tools/load_gen/Constants.py rename to src/load_generator/load_gen/Constants.py index 32b457bae849a50ccbe61e1997aec944cb6a2257..b71dd9a35329e2aef6ce64739f59103a656b4de3 100644 --- a/src/tests/tools/load_gen/Constants.py +++ b/src/load_generator/load_gen/Constants.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/load_gen/DltTools.py b/src/load_generator/load_gen/DltTools.py similarity index 98% rename from src/tests/tools/load_gen/DltTools.py rename to src/load_generator/load_gen/DltTools.py index 34d195ad701c3af9bd0d32acb786013151ec01f8..8799f7d8a13aff6018ffe06700b4478daa2b3271 100644 --- a/src/tests/tools/load_gen/DltTools.py +++ b/src/load_generator/load_gen/DltTools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/load_gen/Parameters.py b/src/load_generator/load_gen/Parameters.py similarity index 92% rename from src/tests/tools/load_gen/Parameters.py rename to src/load_generator/load_gen/Parameters.py index c74d18248c6000cd6da18d5c7e0e55ef2be41730..f0de3ea1aa268c520fd214f7f621953289ac5bc9 100644 --- a/src/tests/tools/load_gen/Parameters.py +++ b/src/load_generator/load_gen/Parameters.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -17,7 +17,7 @@ from typing import List, Optional 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, + 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 ) -> None: self._num_requests = num_requests @@ -25,6 +25,7 @@ class Parameters: self._offered_load = offered_load self._inter_arrival_time = inter_arrival_time self._holding_time = holding_time + self._do_teardown = do_teardown self._dry_mode = dry_mode self._record_to_dlt = record_to_dlt self._dlt_domain_id = dlt_domain_id @@ -58,6 +59,9 @@ class Parameters: @property def holding_time(self): return self._holding_time + @property + def do_teardown(self): return self._do_teardown + @property def dry_mode(self): return self._dry_mode diff --git a/src/tests/tools/load_gen/RequestGenerator.py b/src/load_generator/load_gen/RequestGenerator.py similarity index 69% rename from src/tests/tools/load_gen/RequestGenerator.py rename to src/load_generator/load_gen/RequestGenerator.py index 8f900d93551773c9af23ad203542f0e92bf19a18..a98d957a0974aed71e9e3a205d3d034e4e279cc2 100644 --- a/src/tests/tools/load_gen/RequestGenerator.py +++ b/src/load_generator/load_gen/RequestGenerator.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -15,6 +15,7 @@ import logging, json, random, threading from typing import Dict, Optional, Set, Tuple from common.proto.context_pb2 import Empty, TopologyId +from common.tools.grpc.Tools import grpc_message_to_json from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.ConfigRule import json_config_rule_set from common.tools.object_factory.Device import json_device_id @@ -25,8 +26,8 @@ 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 tests.tools.load_gen.DltTools import record_device_to_dlt, record_link_to_dlt from .Constants import ENDPOINT_COMPATIBILITY, RequestType +from .DltTools import record_device_to_dlt, record_link_to_dlt from .Parameters import Parameters LOGGER = logging.getLogger(__name__) @@ -35,7 +36,8 @@ ROUTER_ID = { 'R149': '5.5.5.5', 'R155': '5.5.5.1', } -VIRTUALCIRCUIT = { + +VIRTUAL_CIRCUIT = { 'R149': '5.5.5.5', 'R155': '5.5.5.1', } @@ -50,6 +52,9 @@ class RequestGenerator: self._endpoint_ids_to_types : Dict[Tuple[str, str], str] = dict() self._endpoint_types_to_ids : Dict[str, Set[Tuple[str, str]]] = dict() + self._device_data : Dict[str, Dict] = dict() + self._device_endpoint_data : Dict[str, Dict[str, Dict]] = dict() + def initialize(self) -> None: with self._lock: self._available_device_endpoints.clear() @@ -64,9 +69,14 @@ class RequestGenerator: devices = context_client.ListDevices(Empty()) for device in devices.devices: 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: 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) + endpoint_type = endpoint.endpoint_type _endpoints.add(endpoint_uuid) self._endpoint_ids_to_types.setdefault((device_uuid, endpoint_uuid), endpoint_type) @@ -200,7 +210,8 @@ class RequestGenerator: dst_endpoint_types = {dst_endpoint_type} if request_type in {RequestType.SERVICE_TAPI} else None # identify excluded destination devices - exclude_device_uuids = {} if request_type in {RequestType.SERVICE_TAPI, RequestType.SERVICE_MW} else {src_device_uuid} + REQUESTTYPES_REUSING_DEVICES = {RequestType.SERVICE_TAPI, RequestType.SERVICE_MW} + exclude_device_uuids = {} if request_type in REQUESTTYPES_REUSING_DEVICES else {src_device_uuid} # choose feasible destination endpoint dst = self._use_device_endpoint( @@ -226,31 +237,37 @@ class RequestGenerator: json_constraint_custom('latency[ms]', '20.0'), ] vlan_id = num_request % 1000 - circuit_id = vlan_id + 100 - src_router_id = ROUTER_ID.get(src_device_uuid) - if src_router_id is None: src_router_id = '10.0.0.{:d}'.format(int(src_device_uuid.replace('R', ''))) - dst_router_id = ROUTER_ID.get(dst_device_uuid) - if dst_router_id is None: dst_router_id = '10.0.0.{:d}'.format(int(dst_device_uuid.replace('R', ''))) - remote = VIRTUALCIRCUIT.get(src_device_uuid) - + circuit_id = '{:03d}'.format(vlan_id + 100) + + src_device_name = self._device_data[src_device_uuid]['name'] + src_router_id = ROUTER_ID.get(src_device_name, '10.0.0.{:d}'.format(int(src_device_name.replace('R', '')))) + + dst_device_name = self._device_data[dst_device_uuid]['name'] + dst_router_id = ROUTER_ID.get(dst_device_name, '10.0.0.{:d}'.format(int(dst_device_name.replace('R', '')))) + + # TODO: Check if it is needed (TID) + remote = VIRTUAL_CIRCUIT.get(src_device_uuid) + config_rules = [ json_config_rule_set('/settings', { 'mtu': 1512 }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_uuid, src_endpoint_uuid), { - 'router_id': src_router_id, - 'sub_interface_index': vlan_id, - 'vlan_id': vlan_id, - 'remote_router': dst_router_id, - 'circuit_id': circuit_id, - 'remote': remote, + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_name, src_endpoint_name), { + 'router_id': src_router_id, + 'sub_interface_index': vlan_id, + 'vlan_id': vlan_id, + 'remote_router': dst_router_id, + 'circuit_id': circuit_id, + 'remote': remote, }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_uuid, dst_endpoint_uuid), { - 'router_id': dst_router_id, - 'sub_interface_index': vlan_id, - 'vlan_id': vlan_id, - 'remote_router': src_router_id, - 'circuit_id': circuit_id, + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_name, dst_endpoint_name), { + 'router_id': dst_router_id, + 'sub_interface_index': vlan_id, + 'vlan_id': vlan_id, + 'remote_router': src_router_id, + 'circuit_id': circuit_id, }), ] return json_service_l2nm_planned( @@ -261,22 +278,29 @@ class RequestGenerator: json_constraint_custom('bandwidth[gbps]', '10.0'), json_constraint_custom('latency[ms]', '20.0'), ] - + bgp_as = 65000 + (num_request % 10000) - vlan_id = num_request % 100 +100 - x= num_request % 255 - y= num_request % 25 * num_request % 10 + x = num_request % 255 + y = num_request % 25 * num_request % 10 route_distinguisher = '{:5d}:{:03d}'.format(bgp_as, vlan_id) - src_router_id = ROUTER_ID.get(src_device_uuid) - src_router_num = int(src_device_uuid.replace('R', '')) + + 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 = 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_router_num = int(dst_device_uuid.replace('R', '')) - dst_router_id = ROUTER_ID.get(dst_device_uuid) + 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_id = ROUTER_ID.get(dst_device_name) if dst_router_id is None: dst_router_id = '10.0.0.{:d}'.format(dst_router_num) - src_address_ip = '10.{:d}.{:d}.{:d}'.format(x,y,int(src_device_uuid.replace('R', ''))) - dst_address_ip = '10.{:d}.{:d}.{:d}'.format(y,x,int(dst_device_uuid.replace('R', ''))) + dst_address_ip = '10.{:d}.{:d}.{:d}'.format(y, x, dst_router_num) + + # TODO: RENAME TO POLICY AZ Y ZA (name of variable and name of policy) policy_R1 = 'srv_{:d}_a'.format(vlan_id) policy_R2 = 'srv_{:d}_b'.format(vlan_id) @@ -286,24 +310,28 @@ class RequestGenerator: 'route_distinguisher': route_distinguisher, }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_uuid, src_endpoint_uuid), { - 'router_id' : src_router_id, - 'vlan_id' : vlan_id, - 'address_ip' : src_address_ip, - 'address_prefix' : 16, - 'policy_1' : policy_R1, - 'policy_2' : policy_R2, - - }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_uuid, dst_endpoint_uuid), { - 'router_id' : dst_router_id, - 'vlan_id' : vlan_id, - 'address_ip' : dst_address_ip, - 'address_prefix' : 16, - 'policy_1' : policy_R2, - 'policy_2' : policy_R1, - - }), + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_name, src_endpoint_name), { + 'router_id' : src_router_id, + 'route_distinguisher': route_distinguisher, + 'sub_interface_index': vlan_id, + 'vlan_id' : vlan_id, + 'address_ip' : src_address_ip, + 'address_prefix' : 16, + 'policy_1' : policy_R1, + 'policy_2' : policy_R2, + }), + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_name, dst_endpoint_name), { + 'router_id' : dst_router_id, + 'route_distinguisher': route_distinguisher, + 'sub_interface_index': vlan_id, + 'vlan_id' : vlan_id, + 'address_ip' : dst_address_ip, + 'address_prefix' : 16, + 'policy_1' : policy_R2, + 'policy_2' : policy_R1, + }), ] return json_service_l3nm_planned( request_uuid, endpoint_ids=endpoint_ids, constraints=constraints, config_rules=config_rules) @@ -340,7 +368,8 @@ class RequestGenerator: src_device_uuid,src_endpoint_uuid = src # identify excluded destination devices - exclude_device_uuids = {} if request_type in {RequestType.SERVICE_TAPI, RequestType.SERVICE_MW} else {src_device_uuid} + REQUESTTYPES_REUSING_DEVICES = {RequestType.SERVICE_TAPI, RequestType.SERVICE_MW} + exclude_device_uuids = {} if request_type in REQUESTTYPES_REUSING_DEVICES else {src_device_uuid} # choose feasible destination endpoint dst = self._use_device_endpoint(request_uuid, request_type, exclude_device_uuids=exclude_device_uuids) @@ -365,26 +394,33 @@ class RequestGenerator: if request_type == RequestType.SLICE_L2NM: vlan_id = num_request % 1000 circuit_id = '{:03d}'.format(vlan_id) - src_router_id = '10.0.0.{:d}'.format(int(src_device_uuid.replace('R', ''))) - dst_router_id = '10.0.0.{:d}'.format(int(src_device_uuid.replace('R', ''))) + + src_device_name = self._device_data[src_device_uuid]['name'] + src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) + + dst_device_name = self._device_data[dst_device_uuid]['name'] + dst_router_id = '10.0.0.{:d}'.format(int(dst_device_name.replace('R', ''))) + config_rules = [ json_config_rule_set('/settings', { 'mtu': 1512 }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_uuid, src_endpoint_uuid), { - 'router_id': src_router_id, - 'sub_interface_index': vlan_id, - 'vlan_id': vlan_id, - 'remote_router': dst_router_id, - 'circuit_id': circuit_id, - }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_uuid, dst_endpoint_uuid), { - 'router_id': dst_router_id, - 'sub_interface_index': vlan_id, - 'vlan_id': vlan_id, - 'remote_router': src_router_id, - 'circuit_id': circuit_id, - }), + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_uuid, src_endpoint_uuid), { + 'router_id': src_router_id, + 'sub_interface_index': vlan_id, + 'vlan_id': vlan_id, + 'remote_router': dst_router_id, + 'circuit_id': circuit_id, + }), + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_uuid, dst_endpoint_uuid), { + 'router_id': dst_router_id, + 'sub_interface_index': vlan_id, + 'vlan_id': vlan_id, + 'remote_router': src_router_id, + 'circuit_id': circuit_id, + }), ] elif request_type == RequestType.SLICE_L3NM: @@ -392,32 +428,41 @@ class RequestGenerator: 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_router_id = '10.0.0.{:d}'.format(int(src_device_uuid.replace('R', ''))) - dst_router_id = '10.0.0.{:d}'.format(int(src_device_uuid.replace('R', ''))) - src_address_ip = '.'.join([src_device_uuid.replace('R', ''), '0'] + src_endpoint_uuid.split('/')) - dst_address_ip = '.'.join([dst_device_uuid.replace('R', ''), '0'] + dst_endpoint_uuid.split('/')) + + 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('/')) + + 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('/')) + config_rules = [ json_config_rule_set('/settings', { 'mtu' : 1512, 'bgp_as' : bgp_as, 'bgp_route_target': bgp_route_target, }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_uuid, src_endpoint_uuid), { - 'router_id' : src_router_id, - 'route_distinguisher': route_distinguisher, - 'sub_interface_index': vlan_id, - 'vlan_id' : vlan_id, - 'address_ip' : src_address_ip, - 'address_prefix' : 16, - }), - json_config_rule_set('/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_uuid, dst_endpoint_uuid), { - 'router_id' : dst_router_id, - 'route_distinguisher': route_distinguisher, - 'sub_interface_index': vlan_id, - 'vlan_id' : vlan_id, - 'address_ip' : dst_address_ip, - 'address_prefix' : 16, - }), + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(src_device_uuid, src_endpoint_uuid), { + 'router_id' : src_router_id, + 'route_distinguisher': route_distinguisher, + 'sub_interface_index': vlan_id, + 'vlan_id' : vlan_id, + 'address_ip' : src_address_ip, + 'address_prefix' : 16, + }), + json_config_rule_set( + '/device[{:s}]/endpoint[{:s}]/settings'.format(dst_device_uuid, dst_endpoint_uuid), { + 'router_id' : dst_router_id, + 'route_distinguisher': route_distinguisher, + 'sub_interface_index': vlan_id, + 'vlan_id' : vlan_id, + 'address_ip' : dst_address_ip, + 'address_prefix' : 16, + }), ] return json_slice( diff --git a/src/tests/tools/load_gen/RequestScheduler.py b/src/load_generator/load_gen/RequestScheduler.py similarity index 93% rename from src/tests/tools/load_gen/RequestScheduler.py rename to src/load_generator/load_gen/RequestScheduler.py index eafb95c30032e69ab4f2f7874656b11db4f6817f..775da1580a2a6521dbdc8fe32236c1f2adb4b3a7 100644 --- a/src/tests/tools/load_gen/RequestScheduler.py +++ b/src/load_generator/load_gen/RequestScheduler.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -31,8 +31,10 @@ logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING) LOGGER = logging.getLogger(__name__) class RequestScheduler: - def __init__(self, parameters : Parameters, generator : RequestGenerator) -> None: - self._scheduler = BlockingScheduler() + def __init__( + self, parameters : Parameters, generator : RequestGenerator, scheduler_class=BlockingScheduler + ) -> None: + self._scheduler = scheduler_class() self._scheduler.configure( jobstores = {'default': MemoryJobStore()}, executors = {'default': ThreadPoolExecutor(max_workers=10)}, @@ -46,7 +48,9 @@ class RequestScheduler: self._generator = generator def _schedule_request_setup(self) -> None: - if self._generator.num_requests_generated >= self._parameters.num_requests: + infinite_loop = self._parameters.num_requests == 0 + num_requests_generated = self._generator.num_requests_generated - 1 # because it first increases, then checks + if not infinite_loop and (num_requests_generated >= self._parameters.num_requests): LOGGER.info('Generation Done!') #self._scheduler.shutdown() return @@ -65,6 +69,9 @@ class RequestScheduler: self._schedule_request_setup() self._scheduler.start() + def stop(self): + self._scheduler.shutdown() + def _request_setup(self) -> None: self._schedule_request_setup() @@ -93,7 +100,8 @@ class RequestScheduler: slice_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) self._create_update(slice_=request) - self._schedule_request_teardown(request) + if self._parameters.do_teardown: + self._schedule_request_teardown(request) def _request_teardown(self, request : Dict) -> None: if 'service_id' in request: diff --git a/src/load_generator/load_gen/__init__.py b/src/load_generator/load_gen/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/load_gen/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/load_generator/requirements.in b/src/load_generator/requirements.in new file mode 100644 index 0000000000000000000000000000000000000000..03a61d7a3fa8fa880d8877a33025401b95da9e25 --- /dev/null +++ b/src/load_generator/requirements.in @@ -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. + +APScheduler==3.8.1 diff --git a/src/tests/tools/load_gen/run.sh b/src/load_generator/run.sh similarity index 80% rename from src/tests/tools/load_gen/run.sh rename to src/load_generator/run.sh index b16808ab6905927728212185681e2a6d4a5135ba..0ef004598ea91e54b6b054a48a0b830287ce5ed3 100755 --- a/src/tests/tools/load_gen/run.sh +++ b/src/load_generator/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,5 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Use this script to run standalone + source tfs_runtime_env_vars.sh -python -m tests.tools.load_gen +python -m load_generator.command diff --git a/src/load_generator/service/LoadGeneratorService.py b/src/load_generator/service/LoadGeneratorService.py new file mode 100644 index 0000000000000000000000000000000000000000..bdcd33a110580450cfa335bda14e95cb8b01a3a7 --- /dev/null +++ b/src/load_generator/service/LoadGeneratorService.py @@ -0,0 +1,28 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.Constants import ServiceNameEnum +from common.Settings import get_service_port_grpc +from common.proto.load_generator_pb2_grpc import add_LoadGeneratorServiceServicer_to_server +from common.tools.service.GenericGrpcService import GenericGrpcService +from .LoadGeneratorServiceServicerImpl import LoadGeneratorServiceServicerImpl + +class LoadGeneratorService(GenericGrpcService): + def __init__(self, cls_name: str = __name__) -> None: + port = get_service_port_grpc(ServiceNameEnum.LOAD_GENERATOR) + super().__init__(port, cls_name=cls_name) + self.load_generator_servicer = LoadGeneratorServiceServicerImpl() + + def install_servicers(self): + add_LoadGeneratorServiceServicer_to_server(self.load_generator_servicer, self.server) diff --git a/src/load_generator/service/LoadGeneratorServiceServicerImpl.py b/src/load_generator/service/LoadGeneratorServiceServicerImpl.py new file mode 100644 index 0000000000000000000000000000000000000000..c280581ddfab488249ff249e60118ec3030e0447 --- /dev/null +++ b/src/load_generator/service/LoadGeneratorServiceServicerImpl.py @@ -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. + +from typing import Optional +import grpc, logging +from apscheduler.schedulers.background import BackgroundScheduler +from common.proto.context_pb2 import Empty +from common.proto.load_generator_pb2_grpc import LoadGeneratorServiceServicer +from load_generator.load_gen.Constants import RequestType +from load_generator.load_gen.Parameters import Parameters +from load_generator.load_gen.RequestGenerator import RequestGenerator +from load_generator.load_gen.RequestScheduler import RequestScheduler + +LOGGER = logging.getLogger(__name__) + +class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer): + def __init__(self): + LOGGER.debug('Creating Servicer...') + self._parameters = Parameters( + num_requests = 100, + request_types = [ + RequestType.SERVICE_L2NM, + RequestType.SERVICE_L3NM, + #RequestType.SERVICE_MW, + #RequestType.SERVICE_TAPI, + RequestType.SLICE_L2NM, + RequestType.SLICE_L3NM, + ], + offered_load = 50, + holding_time = 10, + do_teardown = True, + 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 + ) + self._generator : Optional[RequestGenerator] = None + self._scheduler : Optional[RequestScheduler] = None + LOGGER.debug('Servicer Created') + + def Start(self, request : Empty, context : grpc.ServicerContext) -> Empty: + LOGGER.info('Initializing Generator...') + self._generator = RequestGenerator(self._parameters) + self._generator.initialize() + + LOGGER.info('Running Schedule...') + self._scheduler = RequestScheduler(self._parameters, self._generator, scheduler_class=BackgroundScheduler) + self._scheduler.start() + return Empty() + + def Stop(self, request : Empty, context : grpc.ServicerContext) -> Empty: + if self._scheduler is not None: + self._scheduler.stop() + return Empty() diff --git a/src/load_generator/service/__init__.py b/src/load_generator/service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/service/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/load_generator/service/__main__.py b/src/load_generator/service/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..227099c59aa57f420c842a6210f3b8b146b23cda --- /dev/null +++ b/src/load_generator/service/__main__.py @@ -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. + +import logging, signal, sys, threading +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, + 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") +LOGGER = logging.getLogger(__name__) + +terminate = threading.Event() + +def signal_handler(signal, frame): # pylint: disable=redefined-outer-name + LOGGER.warning('Terminate signal received') + terminate.set() + +def main(): + 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.SERVICE, ENVVAR_SUFIX_SERVICE_HOST ), + get_env_var_name(ServiceNameEnum.SERVICE, 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), + ]) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + LOGGER.info('Starting...') + + # 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 + + scheduler = grpc_service.load_generator_servicer._scheduler + if scheduler is not None: scheduler.stop() + + LOGGER.info('Terminating...') + grpc_service.stop() + + LOGGER.info('Bye') + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/load_generator/tests/__init__.py b/src/load_generator/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/tests/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/tests/tools/load_gen/deploy_specs.sh b/src/load_generator/tests/deploy_specs.sh old mode 100644 new mode 100755 similarity index 63% rename from src/tests/tools/load_gen/deploy_specs.sh rename to src/load_generator/tests/deploy_specs.sh index a688f1c0ad920bab2fb5157dce72225671ed837e..571990ecabfbf120b517f44fd99b4550a4b8a9a1 --- a/src/tests/tools/load_gen/deploy_specs.sh +++ b/src/load_generator/tests/deploy_specs.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" @@ -7,7 +21,7 @@ export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" # interdomain slice pathcomp dlt # dbscanserving opticalattackmitigator opticalattackdetector # l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector -export TFS_COMPONENTS="context device pathcomp service slice webui" # automation monitoring compute dlt +export TFS_COMPONENTS="context device pathcomp service slice webui load_generator" # automation monitoring compute dlt # Set the tag you want to use for your images. export TFS_IMAGE_TAG="dev" diff --git a/src/tests/tools/load_gen/descriptors.json b/src/load_generator/tests/descriptors.json similarity index 100% rename from src/tests/tools/load_gen/descriptors.json rename to src/load_generator/tests/descriptors.json diff --git a/src/tests/tools/load_gen/test_dlt_functional.py b/src/load_generator/tests/test_dlt_functional.py similarity index 97% rename from src/tests/tools/load_gen/test_dlt_functional.py rename to src/load_generator/tests/test_dlt_functional.py index 9c6c3d5ba65d538628d75b2c0a0010963357f8b7..764b0432053902b5533cc7844fcb12f42888de83 100644 --- a/src/tests/tools/load_gen/test_dlt_functional.py +++ b/src/load_generator/tests/test_dlt_functional.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/.gitlab-ci.yml b/src/monitoring/.gitlab-ci.yml index ef3a8c39a045dd059f8a7942223bdc20775ae92c..ff620c53425f8f447dcb00ea03bc4c9f8ce4c5e9 100644 --- a/src/monitoring/.gitlab-ci.yml +++ b/src/monitoring/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -39,7 +39,7 @@ build monitoring: - .gitlab-ci.yml # Apply unit test to the component -unit test monitoring: +unit_test monitoring: variables: IMAGE_NAME: 'monitoring' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) @@ -84,28 +84,28 @@ unit test monitoring: reports: junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml -# Deployment of the service in Kubernetes Cluster -deploy monitoring: - variables: - IMAGE_NAME: 'monitoring' # name of the microservice - IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) - stage: deploy - needs: - - unit test monitoring - # - 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 +## Deployment of the service in Kubernetes Cluster +#deploy monitoring: +# variables: +# IMAGE_NAME: 'monitoring' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test monitoring +# # - 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/monitoring/Dockerfile b/src/monitoring/Dockerfile index f26741df048572339ee757c7dce8b89604558caf..946f2cd1b5d16923aa1509948c759135c7f78eef 100644 --- a/src/monitoring/Dockerfile +++ b/src/monitoring/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/__init__.py b/src/monitoring/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/monitoring/__init__.py +++ b/src/monitoring/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/client/MonitoringClient.py b/src/monitoring/client/MonitoringClient.py index 5641b9cf3236c5fecfa5c6efe3a03b899c342ea5..751ff6e38e52a9d09d170c440ced0a04a44e10a3 100644 --- a/src/monitoring/client/MonitoringClient.py +++ b/src/monitoring/client/MonitoringClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/client/__init__.py b/src/monitoring/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/monitoring/client/__init__.py +++ b/src/monitoring/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/requirements.in b/src/monitoring/requirements.in index c07f0c8f4079482a20a138d190004fa314fc9860..981b4cdf291b6234d53de185ad83a1df2d1148a4 100644 --- a/src/monitoring/requirements.in +++ b/src/monitoring/requirements.in @@ -1,6 +1,20 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + anytree==2.8.0 APScheduler==3.8.1 -fastcache==1.1.0 +#fastcache==1.1.0 #google-api-core #opencensus[stackdriver] #google-cloud-profiler @@ -13,14 +27,8 @@ influx-line-protocol==0.1.4 python-dateutil==2.8.2 python-json-logger==2.0.2 pytz==2021.3 -redis==4.1.2 +#redis==4.1.2 requests==2.27.1 xmltodict==0.12.0 questdb==1.0.1 psycopg2-binary==2.9.3 - -# pip's dependency resolver does not take into account installed packages. -# p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one -# adding here again grpcio==1.47.* and protobuf==3.20.* with explicit versions to prevent collisions -grpcio==1.47.* -protobuf==3.20.* diff --git a/src/monitoring/service/AlarmManager.py b/src/monitoring/service/AlarmManager.py index 873a65d2c8041e6378f84d979bb1fd98d4d61d6b..495a5f365cb0220a647866de57915c5cee8ab94d 100644 --- a/src/monitoring/service/AlarmManager.py +++ b/src/monitoring/service/AlarmManager.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 pytz from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.executors.pool import ProcessPoolExecutor diff --git a/src/monitoring/service/EventTools.py b/src/monitoring/service/EventTools.py index 189e78ce617c69dc4514e9e0b713dece10ef9669..0d351eee968684f18571f0da9f094a806f577efd 100644 --- a/src/monitoring/service/EventTools.py +++ b/src/monitoring/service/EventTools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,23 +12,28 @@ # See the License for the specific language governing permissions and # limitations under the License. -import threading -from queue import Queue - -import grpc - +from typing import Dict +import grpc, logging, queue, threading from common.method_wrappers.ServiceExceptions import ServiceException +from common.proto import monitoring_pb2 +from common.proto.context_pb2 import DeviceOperationalStatusEnum, Empty, EventTypeEnum +from common.proto.kpi_sample_types_pb2 import KpiSampleType from context.client.ContextClient import ContextClient - -from common.proto.context_pb2 import Empty, EventTypeEnum - from monitoring.client.MonitoringClient import MonitoringClient from monitoring.service.MonitoringServiceServicerImpl import LOGGER -from common.proto import monitoring_pb2 +from monitoring.service.NameMapping import NameMapping + +LOGGER = logging.getLogger(__name__) + +DEVICE_OP_STATUS_UNDEFINED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED +DEVICE_OP_STATUS_DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED +DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED +DEVICE_OP_STATUS_NOT_ENABLED = {DEVICE_OP_STATUS_UNDEFINED, DEVICE_OP_STATUS_DISABLED} +KPISAMPLETYPE_UNKNOWN = KpiSampleType.KPISAMPLETYPE_UNKNOWN class EventsDeviceCollector: - def __init__(self) -> None: # pylint: disable=redefined-outer-name - self._events_queue = Queue() + def __init__(self, name_mapping : NameMapping) -> None: # pylint: disable=redefined-outer-name + self._events_queue = queue.Queue() self._context_client_grpc = ContextClient() self._device_stream = self._context_client_grpc.GetDeviceEvents(Empty()) @@ -38,6 +43,9 @@ class EventsDeviceCollector: self._device_thread = threading.Thread(target=self._collect, args=(self._device_stream,), daemon=False) + self._device_to_state : Dict[str, DeviceOperationalStatusEnum] = dict() + self._name_mapping = name_mapping + def grpc_server_on(self): try: grpc.channel_ready_future(self._channel).result(timeout=15) @@ -56,7 +64,7 @@ class EventsDeviceCollector: def start(self): try: self._device_thread.start() - except RuntimeError as e: + except RuntimeError: LOGGER.exception('Start EventTools exception') def get_event(self, block : bool = True, timeout : float = 0.1): @@ -70,29 +78,56 @@ class EventsDeviceCollector: try: kpi_id_list = [] - while not self._events_queue.empty(): + while True: # LOGGER.info('getting Kpi by KpiID') - event = self.get_event(block=True) - if event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE: + try: + event = self.get_event(block=True, timeout=0.5) + + event_type = event.event.event_type + device_uuid = event.device_id.device_uuid.uuid + if event_type in {EventTypeEnum.EVENTTYPE_REMOVE}: + self._device_to_state.pop(device_uuid, None) + continue + + if event_type not in {EventTypeEnum.EVENTTYPE_CREATE, EventTypeEnum.EVENTTYPE_UPDATE}: + # Unknown event type + continue + device = self._context_client.GetDevice(event.device_id) - for j,end_point in enumerate(device.device_endpoints): - #for i, value in enumerate(kpi_sample_types_pb2.KpiSampleType.values()): - for i, value in enumerate(end_point.kpi_sample_types): - #if value == kpi_sample_types_pb2.KpiSampleType.KPISAMPLETYPE_UNKNOWN: continue + self._name_mapping.set_device_name(device_uuid, device.name) - kpi_descriptor = monitoring_pb2.KpiDescriptor() + old_operational_status = self._device_to_state.get(device_uuid, DEVICE_OP_STATUS_UNDEFINED) + device_was_not_enabled = (old_operational_status in DEVICE_OP_STATUS_NOT_ENABLED) + + new_operational_status = device.device_operational_status + device_is_enabled = (new_operational_status == DEVICE_OP_STATUS_ENABLED) + self._device_to_state[device_uuid] = new_operational_status + + activate_monitoring = device_was_not_enabled and device_is_enabled + if not activate_monitoring: + # device is not ready for monitoring + continue - kpi_descriptor.kpi_description = device.device_type - kpi_descriptor.kpi_sample_type = value - #kpi_descriptor.service_id.service_uuid.uuid = "" - kpi_descriptor.device_id.CopyFrom(device.device_id) - kpi_descriptor.endpoint_id.CopyFrom(end_point.endpoint_id) + for endpoint in device.device_endpoints: + endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid + self._name_mapping.set_endpoint_name(endpoint_uuid, endpoint.name) + + for value in endpoint.kpi_sample_types: + if value == KPISAMPLETYPE_UNKNOWN: continue + + kpi_descriptor = monitoring_pb2.KpiDescriptor() + kpi_descriptor.kpi_description = device.device_type + kpi_descriptor.kpi_sample_type = value + kpi_descriptor.device_id.CopyFrom(device.device_id) # pylint: disable=no-member + kpi_descriptor.endpoint_id.CopyFrom(endpoint.endpoint_id) # pylint: disable=no-member kpi_id = self._monitoring_client.SetKpi(kpi_descriptor) kpi_id_list.append(kpi_id) + except queue.Empty: + break + return kpi_id_list - except ServiceException as e: + except ServiceException: LOGGER.exception('ListenEvents exception') - except Exception as e: # pragma: no cover + except Exception: # pragma: no cover # pylint: disable=broad-except LOGGER.exception('ListenEvents exception') - diff --git a/src/monitoring/service/InfluxTools.py b/src/monitoring/service/InfluxTools.py index f19555437000acc3b44e2872f45d8a8e118a9b22..f2f877d9203974dbb91681e08be54f687071f463 100644 --- a/src/monitoring/service/InfluxTools.py +++ b/src/monitoring/service/InfluxTools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/service/ManagementDBTools.py b/src/monitoring/service/ManagementDBTools.py index 2185a3986532ad1b8e629cdcdb66079f23995c8f..a2beddccd633a1961238a6affa4b8d069c26762e 100644 --- a/src/monitoring/service/ManagementDBTools.py +++ b/src/monitoring/service/ManagementDBTools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/service/MetricsDBTools.py b/src/monitoring/service/MetricsDBTools.py index 1d3888d5348bdbe2995f077310ca448827290382..6b98255411aa88ac18bd01474830b3bf268d3483 100644 --- a/src/monitoring/service/MetricsDBTools.py +++ b/src/monitoring/service/MetricsDBTools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -23,14 +23,18 @@ import datetime from common.tools.timestamp.Converters import timestamp_float_to_string, timestamp_utcnow_to_float import psycopg2 +from monitoring.service.NameMapping import NameMapping + LOGGER = logging.getLogger(__name__) class MetricsDB(): - def __init__(self, host, ilp_port=9009, rest_port=9000, table="monitoring", commit_lag_ms=1000, retries=10, - postgre=False, postgre_port=8812, postgre_user='admin', postgre_password='quest'): + def __init__(self, host, name_mapping : NameMapping, ilp_port=9009, rest_port=9000, table="monitoring", + commit_lag_ms=1000, retries=10, postgre=False, postgre_port=8812, postgre_user='admin', + postgre_password='quest'): try: self.host = host + self.name_mapping = name_mapping self.ilp_port = int(ilp_port) self.rest_port = rest_port self.table = table @@ -85,7 +89,9 @@ class MetricsDB(): '(kpi_id SYMBOL,' \ 'kpi_sample_type SYMBOL,' \ 'device_id SYMBOL,' \ + 'device_name SYMBOL,' \ 'endpoint_id SYMBOL,' \ + 'endpoint_name SYMBOL,' \ 'service_id SYMBOL,' \ 'slice_id SYMBOL,' \ 'connection_id SYMBOL,' \ @@ -100,6 +106,9 @@ class MetricsDB(): raise Exception def write_KPI(self, time, kpi_id, kpi_sample_type, device_id, endpoint_id, service_id, slice_id, connection_id, kpi_value): + device_name = self.name_mapping.get_device_name(device_id) or '' + endpoint_name = self.name_mapping.get_endpoint_name(endpoint_id) or '' + counter = 0 while (counter < self.retries): try: @@ -110,7 +119,9 @@ class MetricsDB(): 'kpi_id': kpi_id, 'kpi_sample_type': kpi_sample_type, 'device_id': device_id, + 'device_name': device_name, 'endpoint_id': endpoint_id, + 'endpoint_name': endpoint_name, 'service_id': service_id, 'slice_id': slice_id, 'connection_id': connection_id,}, diff --git a/src/monitoring/service/MonitoringService.py b/src/monitoring/service/MonitoringService.py index e2cbe2862894aec7b571ae857ad4c4fffa3c94c6..5680a80943144db0e9a8f156c65ff0b15013482e 100644 --- a/src/monitoring/service/MonitoringService.py +++ b/src/monitoring/service/MonitoringService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -17,12 +17,13 @@ from common.Settings import get_service_port_grpc from common.proto.monitoring_pb2_grpc import add_MonitoringServiceServicer_to_server from common.tools.service.GenericGrpcService import GenericGrpcService from monitoring.service.MonitoringServiceServicerImpl import MonitoringServiceServicerImpl +from monitoring.service.NameMapping import NameMapping class MonitoringService(GenericGrpcService): - def __init__(self, cls_name: str = __name__) -> None: + def __init__(self, name_mapping : NameMapping, cls_name: str = __name__) -> None: port = get_service_port_grpc(ServiceNameEnum.MONITORING) super().__init__(port, cls_name=cls_name) - self.monitoring_servicer = MonitoringServiceServicerImpl() + self.monitoring_servicer = MonitoringServiceServicerImpl(name_mapping) def install_servicers(self): add_MonitoringServiceServicer_to_server(self.monitoring_servicer, self.server) diff --git a/src/monitoring/service/MonitoringServiceServicerImpl.py b/src/monitoring/service/MonitoringServiceServicerImpl.py index c2bceefd794e3c5bd6acb35e41cef78dc1c205e9..0bbce15094b87a17e332aad21bf34a565e8dd087 100644 --- a/src/monitoring/service/MonitoringServiceServicerImpl.py +++ b/src/monitoring/service/MonitoringServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -17,8 +17,6 @@ from queue import Queue from typing import Iterator -from common.Constants import ServiceNameEnum -from common.Settings import get_setting, get_service_port_grpc, get_service_host from common.logger import getJSONLogger from common.proto.context_pb2 import Empty from common.proto.device_pb2 import MonitoringSettings @@ -36,6 +34,7 @@ from device.client.DeviceClient import DeviceClient from prometheus_client import Counter, Summary from monitoring.service.AlarmManager import AlarmManager +from monitoring.service.NameMapping import NameMapping from monitoring.service.SubscriptionManager import SubscriptionManager LOGGER = getJSONLogger('monitoringservice-server') @@ -50,22 +49,15 @@ METRICSDB_ILP_PORT = os.environ.get("METRICSDB_ILP_PORT") METRICSDB_REST_PORT = os.environ.get("METRICSDB_REST_PORT") METRICSDB_TABLE = os.environ.get("METRICSDB_TABLE") -DEVICESERVICE_SERVICE_HOST = get_setting('DEVICESERVICE_SERVICE_HOST', default=get_service_host(ServiceNameEnum.DEVICE)) -DEVICESERVICE_SERVICE_PORT_GRPC = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC', - default=get_service_port_grpc(ServiceNameEnum.DEVICE)) - - class MonitoringServiceServicerImpl(MonitoringServiceServicer): - def __init__(self): + def __init__(self, name_mapping : NameMapping): LOGGER.info('Init monitoringService') # Init sqlite monitoring db self.management_db = ManagementDBTools.ManagementDB('monitoring.db') - self.deviceClient = DeviceClient(host=DEVICESERVICE_SERVICE_HOST, - port=DEVICESERVICE_SERVICE_PORT_GRPC) # instantiate the client - - self.metrics_db = MetricsDBTools.MetricsDB(METRICSDB_HOSTNAME, METRICSDB_ILP_PORT, METRICSDB_REST_PORT, - METRICSDB_TABLE) + self.deviceClient = DeviceClient() + self.metrics_db = MetricsDBTools.MetricsDB( + METRICSDB_HOSTNAME, name_mapping, METRICSDB_ILP_PORT, METRICSDB_REST_PORT, METRICSDB_TABLE) self.subs_manager = SubscriptionManager(self.metrics_db) self.alarm_manager = AlarmManager(self.metrics_db) LOGGER.info('MetricsDB initialized') @@ -600,7 +592,7 @@ class MonitoringServiceServicerImpl(MonitoringServiceServicer): 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 monitoring WHERE kpi_id = '{kpi_id}' " \ + query = f"SELECT kpi_id, timestamp, kpi_value FROM {METRICSDB_TABLE} WHERE kpi_id = '{kpi_id}' " \ f"LATEST ON timestamp PARTITION BY kpi_id" data = self.metrics_db.run_query(query) LOGGER.debug(data) diff --git a/src/monitoring/service/NameMapping.py b/src/monitoring/service/NameMapping.py new file mode 100644 index 0000000000000000000000000000000000000000..17a48b3cd686f27ad5ad8c6f9027588d84f4feba --- /dev/null +++ b/src/monitoring/service/NameMapping.py @@ -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. + +import threading +from typing import Dict, Optional + +class NameMapping: + def __init__(self) -> None: + self.__lock = threading.Lock() + self.__device_to_name : Dict[str, str] = dict() + self.__endpoint_to_name : Dict[str, str] = dict() + + def get_device_name(self, device_uuid : str) -> Optional[str]: + with self.__lock: + return self.__device_to_name.get(device_uuid) + + def get_endpoint_name(self, endpoint_uuid : str) -> Optional[str]: + with self.__lock: + return self.__endpoint_to_name.get(endpoint_uuid) + + def set_device_name(self, device_uuid : str, device_name : str) -> None: + with self.__lock: + self.__device_to_name[device_uuid] = device_name + + def set_endpoint_name(self, endpoint_uuid : str, endpoint_name : str) -> None: + with self.__lock: + self.__endpoint_to_name[endpoint_uuid] = endpoint_name + + def delete_device_name(self, device_uuid : str) -> None: + with self.__lock: + self.__device_to_name.pop(device_uuid, None) + + def delete_endpoint_name(self, endpoint_uuid : str) -> None: + with self.__lock: + self.__endpoint_to_name.pop(endpoint_uuid, None) diff --git a/src/monitoring/service/SubscriptionManager.py b/src/monitoring/service/SubscriptionManager.py index 3d1da36b7c5f66c28d3885a305660d6971f695b1..7c2b930cefcc620f97d1f759bda00d51ea5d6dd5 100644 --- a/src/monitoring/service/SubscriptionManager.py +++ b/src/monitoring/service/SubscriptionManager.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/service/__init__.py b/src/monitoring/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/monitoring/service/__init__.py +++ b/src/monitoring/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/service/__main__.py b/src/monitoring/service/__main__.py index 3334a860ccd94d51390ab5f5869d25e2475084ee..fc460151b370c0eb5335787ed4677f7008881ad2 100644 --- a/src/monitoring/service/__main__.py +++ b/src/monitoring/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, signal, sys, threading +import logging, signal, sys, threading, time from prometheus_client import start_http_server from common.Constants import ServiceNameEnum from common.Settings import ( @@ -21,6 +21,7 @@ from common.Settings import ( from common.proto import monitoring_pb2 from .EventTools import EventsDeviceCollector from .MonitoringService import MonitoringService +from .NameMapping import NameMapping terminate = threading.Event() LOGGER = None @@ -29,12 +30,14 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name LOGGER.warning('Terminate signal received') terminate.set() -def start_monitoring(): +def start_monitoring(name_mapping : NameMapping): LOGGER.info('Start Monitoring...',) - events_collector = EventsDeviceCollector() + events_collector = EventsDeviceCollector(name_mapping) events_collector.start() + # TODO: redesign this method to be more clear and clean + # Iterate while terminate is not set while not terminate.is_set(): list_new_kpi_ids = events_collector.listen_events() @@ -48,6 +51,8 @@ def start_monitoring(): monitor_kpi_request.monitoring_window_s = 86400 monitor_kpi_request.sampling_rate_s = 30 events_collector._monitoring_client.MonitorKpi(monitor_kpi_request) + + time.sleep(0.5) # let other tasks run; do not overload CPU else: # Terminate is set, looping terminates LOGGER.warning("Stopping execution...") @@ -75,11 +80,13 @@ def main(): metrics_port = get_metrics_port() start_http_server(metrics_port) + name_mapping = NameMapping() + # Starting monitoring service - grpc_service = MonitoringService() + grpc_service = MonitoringService(name_mapping) grpc_service.start() - start_monitoring() + start_monitoring(name_mapping) # Wait for Ctrl+C or termination signal while not terminate.wait(timeout=0.1): pass diff --git a/src/monitoring/tests/Messages.py b/src/monitoring/tests/Messages.py index f15cb5ec2c1d14ed95731cd37e54cb714b29e8b7..a56207d9a74869ef625631f6a21762608ad59c14 100644 --- a/src/monitoring/tests/Messages.py +++ b/src/monitoring/tests/Messages.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -55,6 +55,17 @@ def create_kpi_request_c(): _create_kpi_request.connection_id.connection_uuid.uuid = 'CON3' # pylint: disable=maybe-no-member return _create_kpi_request +def create_kpi_request_d(): + _create_kpi_request = monitoring_pb2.KpiDescriptor() + _create_kpi_request.kpi_description = 'KPI Description Test' + _create_kpi_request.kpi_sample_type = KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED + _create_kpi_request.device_id.device_uuid.uuid = 'DEV4' # pylint: disable=maybe-no-member + _create_kpi_request.service_id.service_uuid.uuid = 'SERV4' # pylint: disable=maybe-no-member + _create_kpi_request.slice_id.slice_uuid.uuid = 'SLC4' # pylint: disable=maybe-no-member + _create_kpi_request.endpoint_id.endpoint_uuid.uuid = 'END4' # pylint: disable=maybe-no-member + _create_kpi_request.connection_id.connection_uuid.uuid = 'CON4' # pylint: disable=maybe-no-member + return _create_kpi_request + def monitor_kpi_request(kpi_uuid, monitoring_window_s, sampling_rate_s): _monitor_kpi_request = monitoring_pb2.MonitorKpiRequest() _monitor_kpi_request.kpi_id.kpi_id.uuid = kpi_uuid # pylint: disable=maybe-no-member diff --git a/src/monitoring/tests/Objects.py b/src/monitoring/tests/Objects.py index 699e9e9913dde47773d79094d8737a924f012f7b..447ed0d601bd7079e55dc30e5cab66d25eb1fd88 100644 --- a/src/monitoring/tests/Objects.py +++ b/src/monitoring/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/tests/__init__.py b/src/monitoring/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/monitoring/tests/__init__.py +++ b/src/monitoring/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py index b113f5a7822841e17274300dc7102664bce1c409..1428b0ed56dbb24a24af8fde42e4d073a48c931d 100644 --- a/src/monitoring/tests/test_unitary.py +++ b/src/monitoring/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,58 +12,47 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy, os, pytest -import threading -import time -from queue import Queue +import copy, os, pytest #, threading, time +import logging +#from queue import Queue from random import random from time import sleep -from typing import Tuple - +from typing import Union #, Tuple from apscheduler.executors.pool import ProcessPoolExecutor from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.base import STATE_STOPPED 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.orm.Database import Database -from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum -from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum -from common.message_broker.MessageBroker import MessageBroker -from common.proto import monitoring_pb2 +#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 -from common.proto.monitoring_pb2 import KpiId, KpiDescriptor, KpiList, SubsDescriptor, SubsList, AlarmID, \ - AlarmDescriptor, AlarmList, Kpi, KpiDescriptorList, SubsResponse, AlarmResponse, RawKpiTable -from common.tools.timestamp.Converters import timestamp_utcnow_to_float, timestamp_string_to_float - +from common.proto.monitoring_pb2 import KpiId, KpiDescriptor, SubsDescriptor, SubsList, AlarmID, \ + AlarmDescriptor, AlarmList, KpiDescriptorList, SubsResponse, AlarmResponse, RawKpiTable #, Kpi, KpiList +from common.tests.MockServicerImpl_Context import MockServicerImpl_Context +from common.tools.service.GenericGrpcService import GenericGrpcService +from common.tools.timestamp.Converters import timestamp_utcnow_to_float #, timestamp_string_to_float from context.client.ContextClient import ContextClient -from context.service.grpc_server.ContextService import ContextService -from common.proto.context_pb2 import EventTypeEnum, DeviceEvent, Device, Empty - from device.client.DeviceClient import DeviceClient from device.service.DeviceService import DeviceService from device.service.driver_api.DriverFactory import DriverFactory from device.service.driver_api.DriverInstanceCache import DriverInstanceCache -from monitoring.service.AlarmManager import AlarmManager -from monitoring.service.MetricsDBTools import MetricsDB -from monitoring.service.SubscriptionManager import SubscriptionManager - -os.environ['DEVICE_EMULATED_ONLY'] = 'TRUE' -from device.service.drivers import DRIVERS # pylint: disable=wrong-import-position - from monitoring.client.MonitoringClient import MonitoringClient -from monitoring.service import ManagementDBTools, MetricsDBTools -from monitoring.service.MonitoringService import MonitoringService +#from monitoring.service.AlarmManager import AlarmManager from monitoring.service.EventTools import EventsDeviceCollector -from monitoring.tests.Messages import create_kpi_request, include_kpi_request, monitor_kpi_request, \ - create_kpi_request_b, create_kpi_request_c, kpi_query, subs_descriptor, alarm_descriptor, \ - alarm_subscription +from monitoring.service.ManagementDBTools import ManagementDB +from monitoring.service.MetricsDBTools import MetricsDB +from monitoring.service.MonitoringService import MonitoringService +from monitoring.service.NameMapping import NameMapping +#from monitoring.service.SubscriptionManager import SubscriptionManager +from monitoring.tests.Messages import create_kpi_request, create_kpi_request_d, include_kpi_request, monitor_kpi_request, \ + create_kpi_request_c, kpi_query, subs_descriptor, alarm_descriptor, alarm_subscription #, create_kpi_request_b from monitoring.tests.Objects import DEVICE_DEV1, DEVICE_DEV1_CONNECT_RULES, DEVICE_DEV1_UUID -from monitoring.service.MonitoringServiceServicerImpl import LOGGER +os.environ['DEVICE_EMULATED_ONLY'] = 'TRUE' +from device.service.drivers import DRIVERS # pylint: disable=wrong-import-position,ungrouped-imports ########################### @@ -71,49 +60,66 @@ from monitoring.service.MonitoringServiceServicerImpl import LOGGER ########################### LOCAL_HOST = '127.0.0.1' - -CONTEXT_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.CONTEXT) # avoid privileged ports +MOCKSERVICE_PORT = 10000 os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST )] = str(LOCAL_HOST) -os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(CONTEXT_SERVICE_PORT) +os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(MOCKSERVICE_PORT) -DEVICE_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.DEVICE) # avoid privileged ports +DEVICE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.DEVICE) # avoid privileged ports os.environ[get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_HOST )] = str(LOCAL_HOST) os.environ[get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(DEVICE_SERVICE_PORT) -MONITORING_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.MONITORING) # avoid privileged ports +MONITORING_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.MONITORING) # avoid privileged ports os.environ[get_env_var_name(ServiceNameEnum.MONITORING, ENVVAR_SUFIX_SERVICE_HOST )] = str(LOCAL_HOST) os.environ[get_env_var_name(ServiceNameEnum.MONITORING, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(MONITORING_SERVICE_PORT) -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 = os.environ.get("METRICSDB_TABLE") +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 = os.environ.get('METRICSDB_TABLE') +LOGGER = logging.getLogger(__name__) -@pytest.fixture(scope='session') -def context_db_mb() -> Tuple[Database, MessageBroker]: - _database = Database(get_database_backend(backend=DatabaseBackendEnum.INMEMORY)) - _message_broker = MessageBroker(get_messagebroker_backend(backend=MessageBrokerBackendEnum.INMEMORY)) - yield _database, _message_broker - _message_broker.terminate() +class MockContextService(GenericGrpcService): + # Mock Service implementing Context to simplify unitary tests of Monitoring + + def __init__(self, bind_port: Union[str, int]) -> None: + super().__init__(bind_port, LOCAL_HOST, enable_health_servicer=False, cls_name='MockService') + + # pylint: disable=attribute-defined-outside-init + def install_servicers(self): + self.context_servicer = MockServicerImpl_Context() + add_ContextServiceServicer_to_server(self.context_servicer, self.server) @pytest.fixture(scope='session') -def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name - database, message_broker = context_db_mb - database.clear_all() - _service = ContextService(database, message_broker) +def context_service(): + LOGGER.info('Initializing MockContextService...') + _service = MockContextService(MOCKSERVICE_PORT) _service.start() + + LOGGER.info('Yielding MockContextService...') yield _service + + LOGGER.info('Terminating MockContextService...') + _service.context_servicer.msg_broker.terminate() _service.stop() + LOGGER.info('Terminated MockContextService...') + @pytest.fixture(scope='session') -def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name +def context_client(context_service : MockContextService): # pylint: disable=redefined-outer-name,unused-argument + LOGGER.info('Initializing ContextClient...') _client = ContextClient() + + LOGGER.info('Yielding ContextClient...') yield _client + + LOGGER.info('Closing ContextClient...') _client.close() + LOGGER.info('Closed ContextClient...') + @pytest.fixture(scope='session') -def device_service(context_service : ContextService): # pylint: disable=redefined-outer-name +def device_service(context_service : MockContextService): # pylint: disable=redefined-outer-name,unused-argument LOGGER.info('Initializing DeviceService...') driver_factory = DriverFactory(DRIVERS) driver_instance_cache = DriverInstanceCache(driver_factory) @@ -127,20 +133,30 @@ def device_service(context_service : ContextService): # pylint: disable=redefine LOGGER.info('Terminating DeviceService...') _service.stop() + LOGGER.info('Terminated DeviceService...') + @pytest.fixture(scope='session') -def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name +def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name,unused-argument + LOGGER.info('Initializing DeviceClient...') _client = DeviceClient() + + LOGGER.info('Yielding DeviceClient...') yield _client + + LOGGER.info('Closing DeviceClient...') _client.close() + LOGGER.info('Closed DeviceClient...') + # This fixture will be requested by test cases and last during testing session @pytest.fixture(scope='session') def monitoring_service( - context_service : ContextService, # pylint: disable=redefined-outer-name - device_service : DeviceService # pylint: disable=redefined-outer-name + context_service : MockContextService, # pylint: disable=redefined-outer-name,unused-argument + device_service : DeviceService # pylint: disable=redefined-outer-name,unused-argument ): LOGGER.info('Initializing MonitoringService...') - _service = MonitoringService() + name_mapping = NameMapping() + _service = MonitoringService(name_mapping) _service.start() # yield the server, when test finishes, execution will resume to stop it @@ -150,10 +166,12 @@ def monitoring_service( LOGGER.info('Terminating MonitoringService...') _service.stop() + LOGGER.info('Terminated MonitoringService...') + # This fixture will be requested by test cases and last during testing session. # The client requires the server, so client fixture has the server as dependency. @pytest.fixture(scope='session') -def monitoring_client(monitoring_service : MonitoringService): # pylint: disable=redefined-outer-name +def monitoring_client(monitoring_service : MonitoringService): # pylint: disable=redefined-outer-name,unused-argument LOGGER.info('Initializing MonitoringClient...') _client = MonitoringClient() @@ -164,16 +182,19 @@ def monitoring_client(monitoring_service : MonitoringService): # pylint: disable LOGGER.info('Closing MonitoringClient...') _client.close() + LOGGER.info('Closed MonitoringClient...') + @pytest.fixture(scope='session') def management_db(): - _management_db = ManagementDBTools.ManagementDB('monitoring.db') + _management_db = ManagementDB('monitoring.db') return _management_db @pytest.fixture(scope='session') -def metrics_db(): - _metrics_db = MetricsDBTools.MetricsDB( - METRICSDB_HOSTNAME, METRICSDB_ILP_PORT, METRICSDB_REST_PORT, METRICSDB_TABLE) - return _metrics_db +def metrics_db(monitoring_service : MonitoringService): # pylint: disable=redefined-outer-name + return monitoring_service.monitoring_servicer.metrics_db + #_metrics_db = MetricsDBTools.MetricsDB( + # METRICSDB_HOSTNAME, METRICSDB_ILP_PORT, METRICSDB_REST_PORT, METRICSDB_TABLE) + #return _metrics_db @pytest.fixture(scope='session') def subs_scheduler(): @@ -183,10 +204,13 @@ def subs_scheduler(): return _scheduler def ingestion_data(kpi_id_int): - metrics_db = MetricsDB("localhost", "9009", "9000", "monitoring") + # pylint: disable=redefined-outer-name,unused-argument + metrics_db = MetricsDB('localhost', '9009', '9000', 'monitoring') - for i in range(50): - kpiSampleType = KpiSampleType.Name(KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED).upper().replace('KPISAMPLETYPE_', '') + kpiSampleType = KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED + kpiSampleType_name = KpiSampleType.Name(kpiSampleType).upper().replace('KPISAMPLETYPE_', '') + for _ in range(50): + kpiSampleType = kpiSampleType_name kpiId = kpi_id_int deviceId = 'DEV'+ str(kpi_id_int) endpointId = 'END' + str(kpi_id_int) @@ -250,32 +274,18 @@ def test_include_kpi(monitoring_client): # pylint: disable=redefined-outer-name # Test case that makes use of client fixture to test server's MonitorKpi method def test_monitor_kpi( - context_client : ContextClient, # pylint: disable=redefined-outer-name + context_client : ContextClient, # pylint: disable=redefined-outer-name,unused-argument device_client : DeviceClient, # pylint: disable=redefined-outer-name monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name - context_db_mb : Tuple[Database, MessageBroker] # pylint: disable=redefined-outer-name ): LOGGER.info('test_monitor_kpi begin') - context_database = context_db_mb[0] - - # ----- Clean the database ----------------------------------------------------------------------------------------- - context_database.clear_all() - - # ----- Dump state of database before create the object ------------------------------------------------------------ - db_entries = context_database.dump() - LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) - for db_entry in db_entries: - LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover - LOGGER.info('-----------------------------------------------------------') - assert len(db_entries) == 0 - # ----- Update the object ------------------------------------------------------------------------------------------ LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID)) device_with_connect_rules = copy.deepcopy(DEVICE_DEV1) device_with_connect_rules['device_config']['config_rules'].extend(DEVICE_DEV1_CONNECT_RULES) - response = device_client.AddDevice(Device(**device_with_connect_rules)) - assert response.device_uuid.uuid == DEVICE_DEV1_UUID + device_id = device_client.AddDevice(Device(**device_with_connect_rules)) + assert device_id.device_uuid.uuid == DEVICE_DEV1_UUID response = monitoring_client.SetKpi(create_kpi_request('1')) _monitor_kpi_request = monitor_kpi_request(response.kpi_id.uuid, 120, 5) # pylint: disable=maybe-no-member @@ -283,6 +293,8 @@ def test_monitor_kpi( LOGGER.debug(str(response)) assert isinstance(response, Empty) + device_client.DeleteDevice(device_id) + # Test case that makes use of client fixture to test server's QueryKpiData method def test_query_kpi_data(monitoring_client,subs_scheduler): # pylint: disable=redefined-outer-name @@ -313,7 +325,7 @@ def test_set_kpi_subscription(monitoring_client,subs_scheduler): # pylint: disab subs_scheduler.shutdown() # Test case that makes use of client fixture to test server's GetSubsDescriptor method -def test_get_subs_descriptor(monitoring_client): +def test_get_subs_descriptor(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_get_subs_descriptor') kpi_id = monitoring_client.SetKpi(create_kpi_request_c()) monitoring_client.IncludeKpi(include_kpi_request(kpi_id)) @@ -324,14 +336,14 @@ def test_get_subs_descriptor(monitoring_client): assert isinstance(response, SubsDescriptor) # Test case that makes use of client fixture to test server's GetSubscriptions method -def test_get_subscriptions(monitoring_client): +def test_get_subscriptions(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_get_subscriptions') response = monitoring_client.GetSubscriptions(Empty()) LOGGER.debug(response) assert isinstance(response, SubsList) # Test case that makes use of client fixture to test server's DeleteSubscription method -def test_delete_subscription(monitoring_client): +def test_delete_subscription(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_delete_subscription') kpi_id = monitoring_client.SetKpi(create_kpi_request_c()) monitoring_client.IncludeKpi(include_kpi_request(kpi_id)) @@ -341,7 +353,7 @@ def test_delete_subscription(monitoring_client): assert isinstance(response, Empty) # Test case that makes use of client fixture to test server's SetKpiAlarm method -def test_set_kpi_alarm(monitoring_client): +def test_set_kpi_alarm(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_set_kpi_alarm') kpi_id = monitoring_client.SetKpi(create_kpi_request_c()) response = monitoring_client.SetKpiAlarm(alarm_descriptor(kpi_id)) @@ -349,14 +361,14 @@ def test_set_kpi_alarm(monitoring_client): assert isinstance(response, AlarmID) # Test case that makes use of client fixture to test server's GetAlarms method -def test_get_alarms(monitoring_client): +def test_get_alarms(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_get_alarms') response = monitoring_client.GetAlarms(Empty()) LOGGER.debug(response) assert isinstance(response, AlarmList) # Test case that makes use of client fixture to test server's GetAlarmDescriptor method -def test_get_alarm_descriptor(monitoring_client): +def test_get_alarm_descriptor(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_get_alarm_descriptor') _kpi_id = monitoring_client.SetKpi(create_kpi_request_c()) _alarm_id = monitoring_client.SetKpiAlarm(alarm_descriptor(_kpi_id)) @@ -365,7 +377,7 @@ def test_get_alarm_descriptor(monitoring_client): assert isinstance(_response, AlarmDescriptor) # Test case that makes use of client fixture to test server's GetAlarmResponseStream method -def test_get_alarm_response_stream(monitoring_client,subs_scheduler): +def test_get_alarm_response_stream(monitoring_client,subs_scheduler): # pylint: disable=redefined-outer-name LOGGER.warning('test_get_alarm_descriptor') _kpi_id = monitoring_client.SetKpi(create_kpi_request('3')) _alarm_id = monitoring_client.SetKpiAlarm(alarm_descriptor(_kpi_id)) @@ -380,7 +392,7 @@ def test_get_alarm_response_stream(monitoring_client,subs_scheduler): subs_scheduler.shutdown() # Test case that makes use of client fixture to test server's DeleteAlarm method -def test_delete_alarm(monitoring_client): +def test_delete_alarm(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_delete_alarm') _kpi_id = monitoring_client.SetKpi(create_kpi_request_c()) _alarm_id = monitoring_client.SetKpiAlarm(alarm_descriptor(_kpi_id)) @@ -391,7 +403,8 @@ def test_delete_alarm(monitoring_client): # Test case that makes use of client fixture to test server's GetStreamKpi method def test_get_stream_kpi(monitoring_client): # pylint: disable=redefined-outer-name LOGGER.warning('test_getstream_kpi begin') - response = monitoring_client.GetStreamKpi(monitoring_pb2.Kpi()) + _kpi_id = monitoring_client.SetKpi(create_kpi_request_d()) + response = monitoring_client.GetStreamKpi(_kpi_id) LOGGER.debug(str(response)) assert isinstance(response, _MultiThreadedRendezvous) @@ -408,15 +421,17 @@ def test_get_stream_kpi(monitoring_client): # pylint: disable=redefined-outer-na def test_managementdb_tools_kpis(management_db): # pylint: disable=redefined-outer-name LOGGER.warning('test_managementdb_tools_kpis begin') _create_kpi_request = create_kpi_request('5') - kpi_description = _create_kpi_request.kpi_description # pylint: disable=maybe-no-member - kpi_sample_type = _create_kpi_request.kpi_sample_type # pylint: disable=maybe-no-member - kpi_device_id = _create_kpi_request.device_id.device_uuid.uuid # pylint: disable=maybe-no-member - kpi_endpoint_id = _create_kpi_request.endpoint_id.endpoint_uuid.uuid # pylint: disable=maybe-no-member - kpi_service_id = _create_kpi_request.service_id.service_uuid.uuid # pylint: disable=maybe-no-member - kpi_slice_id = _create_kpi_request.slice_id.slice_uuid.uuid - kpi_connection_id = _create_kpi_request.connection_id.connection_uuid.uuid - - _kpi_id = management_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id,kpi_slice_id,kpi_connection_id) + kpi_description = _create_kpi_request.kpi_description # pylint: disable=maybe-no-member + kpi_sample_type = _create_kpi_request.kpi_sample_type # pylint: disable=maybe-no-member + kpi_device_id = _create_kpi_request.device_id.device_uuid.uuid # pylint: disable=maybe-no-member + kpi_endpoint_id = _create_kpi_request.endpoint_id.endpoint_uuid.uuid # pylint: disable=maybe-no-member + kpi_service_id = _create_kpi_request.service_id.service_uuid.uuid # pylint: disable=maybe-no-member + kpi_slice_id = _create_kpi_request.slice_id.slice_uuid.uuid # pylint: disable=maybe-no-member + kpi_connection_id = _create_kpi_request.connection_id.connection_uuid.uuid # pylint: disable=maybe-no-member + + _kpi_id = management_db.insert_KPI( + kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id, + kpi_slice_id, kpi_connection_id) assert isinstance(_kpi_id, int) response = management_db.get_KPI(_kpi_id) @@ -517,30 +532,17 @@ def test_managementdb_tools_insert_alarm(management_db): # assert total_points != 0 def test_events_tools( - context_client : ContextClient, # pylint: disable=redefined-outer-name + context_client : ContextClient, # pylint: disable=redefined-outer-name,unused-argument device_client : DeviceClient, # pylint: disable=redefined-outer-name - monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name - context_db_mb : Tuple[Database, MessageBroker] # pylint: disable=redefined-outer-name + monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name,unused-argument + metrics_db : MetricsDB, # pylint: disable=redefined-outer-name ): LOGGER.warning('test_get_device_events begin') - context_database = context_db_mb[0] - - # ----- Clean the database ----------------------------------------------------------------------------------------- - context_database.clear_all() - # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- - events_collector = EventsDeviceCollector() + events_collector = EventsDeviceCollector(metrics_db.name_mapping) events_collector.start() - # ----- Dump state of database before create the object ------------------------------------------------------------ - db_entries = context_database.dump() - LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) - for db_entry in db_entries: - LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover - LOGGER.info('-----------------------------------------------------------') - assert len(db_entries) == 0 - # ----- Update the object ------------------------------------------------------------------------------------------ LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID)) device_with_connect_rules = copy.deepcopy(DEVICE_DEV1) @@ -548,35 +550,25 @@ def test_events_tools( response = device_client.AddDevice(Device(**device_with_connect_rules)) assert response.device_uuid.uuid == DEVICE_DEV1_UUID + device_client.DeleteDevice(response) events_collector.stop() + LOGGER.warning('test_get_device_events end') + def test_get_device_events( - context_client : ContextClient, # pylint: disable=redefined-outer-name + context_client : ContextClient, # pylint: disable=redefined-outer-name,unused-argument device_client : DeviceClient, # pylint: disable=redefined-outer-name - monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name - context_db_mb : Tuple[Database, MessageBroker] # pylint: disable=redefined-outer-name + monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name,unused-argument + metrics_db : MetricsDB, # pylint: disable=redefined-outer-name ): LOGGER.warning('test_get_device_events begin') - context_database = context_db_mb[0] - - # ----- Clean the database ----------------------------------------------------------------------------------------- - context_database.clear_all() - # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- - events_collector = EventsDeviceCollector() + events_collector = EventsDeviceCollector(metrics_db.name_mapping) events_collector.start() - # ----- Dump state of database before create the object ------------------------------------------------------------ - db_entries = context_database.dump() - LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) - for db_entry in db_entries: - LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover - LOGGER.info('-----------------------------------------------------------') - assert len(db_entries) == 0 - # ----- Check create event ----------------------------------------------------------------------------------------- LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID)) device_with_connect_rules = copy.deepcopy(DEVICE_DEV1) @@ -589,43 +581,45 @@ def test_get_device_events( assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE assert event.device_id.device_uuid.uuid == DEVICE_DEV1_UUID + device_client.DeleteDevice(response) events_collector.stop() + LOGGER.warning('test_get_device_events end') + def test_listen_events( - context_client : ContextClient, # pylint: disable=redefined-outer-name + context_client : ContextClient, # pylint: disable=redefined-outer-name,unused-argument device_client : DeviceClient, # pylint: disable=redefined-outer-name - monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name - context_db_mb : Tuple[Database, MessageBroker] # pylint: disable=redefined-outer-name + monitoring_client : MonitoringClient, # pylint: disable=redefined-outer-name,unused-argument + metrics_db : MetricsDB, # pylint: disable=redefined-outer-name ): LOGGER.warning('test_listen_events begin') - context_database = context_db_mb[0] - - # ----- Clean the database ----------------------------------------------------------------------------------------- - context_database.clear_all() - # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- - events_collector = EventsDeviceCollector() + events_collector = EventsDeviceCollector(metrics_db.name_mapping) events_collector.start() - # ----- Dump state of database before create the object ------------------------------------------------------------ - db_entries = context_database.dump() - LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) - for db_entry in db_entries: - LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover - LOGGER.info('-----------------------------------------------------------') - assert len(db_entries) == 0 - LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID)) device_with_connect_rules = copy.deepcopy(DEVICE_DEV1) device_with_connect_rules['device_config']['config_rules'].extend(DEVICE_DEV1_CONNECT_RULES) response = device_client.AddDevice(Device(**device_with_connect_rules)) assert response.device_uuid.uuid == DEVICE_DEV1_UUID - sleep(0.1) + LOGGER.info('Activating Device {:s}'.format(DEVICE_DEV1_UUID)) - kpi_id_list = events_collector.listen_events() + device = context_client.GetDevice(response) + device_with_op_state = Device() + device_with_op_state.CopyFrom(device) + device_with_op_state.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + response = context_client.SetDevice(device_with_op_state) + assert response.device_uuid.uuid == DEVICE_DEV1_UUID + + sleep(1.0) + kpi_id_list = events_collector.listen_events() assert len(kpi_id_list) > 0 + + device_client.DeleteDevice(response) events_collector.stop() + + LOGGER.warning('test_listen_events end') diff --git a/src/opticalattackmitigator/.gitlab-ci.yml b/src/opticalattackmitigator/.gitlab-ci.yml index 5b9a133bd0cbf4b7dc4a4b6cf290a3be9adf663e..92968348b3f7ad9b35f39e6f6d86e5df180499ac 100644 --- a/src/opticalattackmitigator/.gitlab-ci.yml +++ b/src/opticalattackmitigator/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/Config.py b/src/opticalattackmitigator/Config.py index 130381d8bd1db49803aefa992435808bed3a87d3..09ae554ad2e0abce66c7638144c07b2e0b740ae9 100644 --- a/src/opticalattackmitigator/Config.py +++ b/src/opticalattackmitigator/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/Dockerfile b/src/opticalattackmitigator/Dockerfile index 40469805410e26b145d8a84beda8247fb7c7a56d..e3ba175b7616c88b7208c7476195786dffaa83d1 100644 --- a/src/opticalattackmitigator/Dockerfile +++ b/src/opticalattackmitigator/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/__init__.py b/src/opticalattackmitigator/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalattackmitigator/__init__.py +++ b/src/opticalattackmitigator/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py b/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py index d0c53e57ee54a42955210308492e27d0bb332729..9aa24c696d346f8fb9874412cc1e2e18cfd018fe 100644 --- a/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py +++ b/src/opticalattackmitigator/client/OpticalAttackMitigatorClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/client/__init__.py b/src/opticalattackmitigator/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalattackmitigator/client/__init__.py +++ b/src/opticalattackmitigator/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/genproto.sh b/src/opticalattackmitigator/genproto.sh index 500fd19301599b1e0370bf4a9fe8d1a6f298b6bb..4cb0103b2428605c32cebc142c39dcdc764a3551 100755 --- a/src/opticalattackmitigator/genproto.sh +++ b/src/opticalattackmitigator/genproto.sh @@ -1,6 +1,6 @@ #!/bin/bash -eu # -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -20,7 +20,7 @@ cd $(dirname $0) rm -rf proto/*.py rm -rf proto/__pycache__ tee proto/__init__.py << EOF > /dev/null -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/proto/__init__.py b/src/opticalattackmitigator/proto/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalattackmitigator/proto/__init__.py +++ b/src/opticalattackmitigator/proto/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/requirements.in b/src/opticalattackmitigator/requirements.in index ea6b450c9c240c76b9f54ce4f3c0c6c25ec62289..378e9a10a70f6a41a264c6a76f47239d7515989a 100644 --- a/src/opticalattackmitigator/requirements.in +++ b/src/opticalattackmitigator/requirements.in @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 diff --git a/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py b/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py index 875276b4ce80335b9eb0081a05d38bfa2c378e43..e2783e6ca6907cccad0e344cf2f058acabe53b93 100644 --- a/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py +++ b/src/opticalattackmitigator/service/OpticalAttackMitigatorService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py b/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py index 39a783ac40218930b1c08bd0a1cf55788ce7f0b9..16777e799deef7e50905b70b049f25765ebe7d96 100644 --- a/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py +++ b/src/opticalattackmitigator/service/OpticalAttackMitigatorServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/service/__init__.py b/src/opticalattackmitigator/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalattackmitigator/service/__init__.py +++ b/src/opticalattackmitigator/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/service/__main__.py b/src/opticalattackmitigator/service/__main__.py index 10b50ac8ba5f5c7a11c5963eb8533bf6d05dfee2..649d079c0cee6347e452acbaf35263d77150bd45 100644 --- a/src/opticalattackmitigator/service/__main__.py +++ b/src/opticalattackmitigator/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/tests/__init__.py b/src/opticalattackmitigator/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalattackmitigator/tests/__init__.py +++ b/src/opticalattackmitigator/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalattackmitigator/tests/test_unitary.py b/src/opticalattackmitigator/tests/test_unitary.py index 74f91a837bf0c83026c88b28ae45f21493a2599d..24d0853b90a7b9f30fd25bfe7431f4e3e7e5fd0f 100644 --- a/src/opticalattackmitigator/tests/test_unitary.py +++ b/src/opticalattackmitigator/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/.gitlab-ci.yml b/src/opticalcentralizedattackdetector/.gitlab-ci.yml index c3d91aec6e10c7450cfda0b74d0bc3bbe613558b..3db4de3f177cfb1478bc306067564e9a293e0737 100644 --- a/src/opticalcentralizedattackdetector/.gitlab-ci.yml +++ b/src/opticalcentralizedattackdetector/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/Config.py b/src/opticalcentralizedattackdetector/Config.py index 5fd3e97e9f590bea9cdfc6ebf8e93e90fb0a4fea..c9bfe106b8d69ca52016ccc9512ec4598d3914bf 100644 --- a/src/opticalcentralizedattackdetector/Config.py +++ b/src/opticalcentralizedattackdetector/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/Dockerfile b/src/opticalcentralizedattackdetector/Dockerfile index 190df9beae66e82900a8ab78a12d062e4d319fda..a7b32ccc6ee94f0fe741885452a44ca9fb7a0f3f 100644 --- a/src/opticalcentralizedattackdetector/Dockerfile +++ b/src/opticalcentralizedattackdetector/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/__init__.py b/src/opticalcentralizedattackdetector/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalcentralizedattackdetector/__init__.py +++ b/src/opticalcentralizedattackdetector/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py b/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py index cfb78b41ec6a6d5385692813e1a839566d1c90e7..3dc2f3ae8f3837fe1c12d530d61fe70acf2563b6 100644 --- a/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py +++ b/src/opticalcentralizedattackdetector/client/OpticalCentralizedAttackDetectorClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/client/__init__.py b/src/opticalcentralizedattackdetector/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalcentralizedattackdetector/client/__init__.py +++ b/src/opticalcentralizedattackdetector/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/genproto.sh b/src/opticalcentralizedattackdetector/genproto.sh index 855231cce17081a359cc510423f877d58833430d..85941a266c1def6f352d5ade7bfe5b9e99309fd9 100755 --- a/src/opticalcentralizedattackdetector/genproto.sh +++ b/src/opticalcentralizedattackdetector/genproto.sh @@ -1,6 +1,6 @@ #!/bin/bash -eu # -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -20,7 +20,7 @@ cd $(dirname $0) rm -rf proto/*.py rm -rf proto/__pycache__ tee proto/__init__.py << EOF > /dev/null -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/proto/__init__.py b/src/opticalcentralizedattackdetector/proto/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalcentralizedattackdetector/proto/__init__.py +++ b/src/opticalcentralizedattackdetector/proto/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/requirements.in b/src/opticalcentralizedattackdetector/requirements.in index ea6b450c9c240c76b9f54ce4f3c0c6c25ec62289..378e9a10a70f6a41a264c6a76f47239d7515989a 100644 --- a/src/opticalcentralizedattackdetector/requirements.in +++ b/src/opticalcentralizedattackdetector/requirements.in @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 diff --git a/src/opticalcentralizedattackdetector/requirements.txt b/src/opticalcentralizedattackdetector/requirements.txt index fca44cbb133ae3c6d5ba2a6d12882ecad9a2c467..5d13e7bc5d318c65e5cc0fe8a4501631aa5428ff 100644 --- a/src/opticalcentralizedattackdetector/requirements.txt +++ b/src/opticalcentralizedattackdetector/requirements.txt @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py index e29566833a781afc8bf85b41b7d5dd10f2a4a2f5..f281063f47cd7ef79b06640a5588286699d55848 100644 --- a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py +++ b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py index 0009f8d9128983b412ecadb3f1011faa0d29dd88..c3ca1c1cfc21dd22c3f2f801a8d1c1321274ad29 100644 --- a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py +++ b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/service/__init__.py b/src/opticalcentralizedattackdetector/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalcentralizedattackdetector/service/__init__.py +++ b/src/opticalcentralizedattackdetector/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/service/__main__.py b/src/opticalcentralizedattackdetector/service/__main__.py index d21b96cf8adc6f9d9968f3553c9249a3b8cedf31..89dfe277d1b642727cca1199e250153264aeb5c2 100644 --- a/src/opticalcentralizedattackdetector/service/__main__.py +++ b/src/opticalcentralizedattackdetector/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/tests/__init__.py b/src/opticalcentralizedattackdetector/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/opticalcentralizedattackdetector/tests/__init__.py +++ b/src/opticalcentralizedattackdetector/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/opticalcentralizedattackdetector/tests/example_objects.py b/src/opticalcentralizedattackdetector/tests/example_objects.py index 3c5a26b6d0bde888560741f052906e0d2694c91d..a6859bfb4defd4ccb9df318222237efb8e9cb036 100644 --- a/src/opticalcentralizedattackdetector/tests/example_objects.py +++ b/src/opticalcentralizedattackdetector/tests/example_objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. from copy import deepcopy -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from context.proto.context_pb2 import ( ConfigActionEnum, DeviceDriverEnum, DeviceOperationalStatusEnum, ServiceStatusEnum, ServiceTypeEnum) @@ -31,7 +31,7 @@ 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_ID = {'context_uuid': {'uuid': DEFAULT_CONTEXT_NAME}} CONTEXT = { 'context_id': deepcopy(CONTEXT_ID), 'topology_ids': [], @@ -47,7 +47,7 @@ CONTEXT_2 = { TOPOLOGY_ID = { 'context_id': deepcopy(CONTEXT_ID), - 'topology_uuid': {'uuid': DEFAULT_TOPOLOGY_UUID}, + 'topology_uuid': {'uuid': DEFAULT_TOPOLOGY_NAME}, } TOPOLOGY = { 'topology_id': deepcopy(TOPOLOGY_ID), diff --git a/src/opticalcentralizedattackdetector/tests/test_unitary.py b/src/opticalcentralizedattackdetector/tests/test_unitary.py index da0f4ca9f78478073354d8645cf0b455a5f7a874..d89ef2fe27a7d284b655698e7ee89e79b230b04b 100644 --- a/src/opticalcentralizedattackdetector/tests/test_unitary.py +++ b/src/opticalcentralizedattackdetector/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/.gitlab-ci.yml b/src/pathcomp/.gitlab-ci.yml index a45e735e4c07299c4853abdff5b6c39963a87a78..20ec4e728837b87e061b2ecffa4b7549c658258f 100644 --- a/src/pathcomp/.gitlab-ci.yml +++ b/src/pathcomp/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -48,7 +48,7 @@ build pathcomp: - .gitlab-ci.yml # Apply unit test to the component -unit test pathcomp-backend: +unit_test pathcomp-backend: variables: IMAGE_NAME: 'pathcomp' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) @@ -62,6 +62,7 @@ unit test pathcomp-backend: - if docker container ls | grep ${IMAGE_NAME}-backend; then docker rm -f ${IMAGE_NAME}-backend; else echo "${IMAGE_NAME}-backend image is not in the system"; fi script: - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG" + - docker ps -a #- docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 -v "$PWD/src/${IMAGE_NAME}/backend/tests:/opt/results" --network=teraflowbridge ${IMAGE_NAME}-backend:${IMAGE_TAG}-builder - docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 --network=teraflowbridge ${IMAGE_NAME}-backend:${IMAGE_TAG}-builder - sleep 5 @@ -93,7 +94,7 @@ unit test pathcomp-backend: # junit: src/$IMAGE_NAME/backend/tests/${IMAGE_NAME}-backend_report.xml # Apply unit test to the component -unit test pathcomp-frontend: +unit_test pathcomp-frontend: variables: IMAGE_NAME: 'pathcomp' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) @@ -102,22 +103,35 @@ unit test pathcomp-frontend: - build pathcomp 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 --driver=bridge --subnet=172.28.0.0/24 --gateway=172.28.0.254 teraflowbridge; fi + - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create --driver=bridge teraflowbridge; fi - if docker container ls | grep ${IMAGE_NAME}-frontend; then docker rm -f ${IMAGE_NAME}-frontend; else echo "${IMAGE_NAME}-frontend image is not in the system"; fi - if docker container ls | grep ${IMAGE_NAME}-backend; then docker rm -f ${IMAGE_NAME}-backend; else echo "${IMAGE_NAME}-backend image is not in the system"; fi script: - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG" - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG" - - docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 -v "$PWD/src/${IMAGE_NAME}/backend/tests:/opt/results" --network=teraflowbridge --ip 172.28.0.1 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG + - > + docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 --network=teraflowbridge + --volume "$PWD/src/${IMAGE_NAME}/backend/tests:/opt/results" + $CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG + - PATHCOMP_BACKEND_HOST=$(docker inspect ${IMAGE_NAME}-backend --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}") + - echo $PATHCOMP_BACKEND_HOST + - sleep 1 + - > + docker run --name ${IMAGE_NAME}-frontend -d -p 10020:10020 --network=teraflowbridge + --volume "$PWD/src/${IMAGE_NAME}/frontend/tests:/opt/results" + --env "PATHCOMP_BACKEND_HOST=${PATHCOMP_BACKEND_HOST}" + --env "PATHCOMP_BACKEND_PORT=8081" + $CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG - sleep 1 - - docker run --name ${IMAGE_NAME}-frontend -d -p 10020:10020 --env "PATHCOMP_BACKEND_HOST=172.28.0.1" --env "PATHCOMP_BACKEND_PORT=8081" -v "$PWD/src/${IMAGE_NAME}/frontend/tests:/opt/results" --network=teraflowbridge --ip 172.28.0.2 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG - docker exec -i ${IMAGE_NAME}-frontend bash -c "env" - docker exec -i ${IMAGE_NAME}-backend bash -c "env" - sleep 5 - docker ps -a - docker logs ${IMAGE_NAME}-frontend - docker logs ${IMAGE_NAME}-backend - - docker exec -i ${IMAGE_NAME}-frontend bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/frontend/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}-frontend_report.xml" + - > + docker exec -i ${IMAGE_NAME}-frontend bash -c + "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/frontend/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}-frontend_report.xml" - docker exec -i ${IMAGE_NAME}-frontend bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing" coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' after_script: @@ -147,29 +161,29 @@ unit test pathcomp-frontend: reports: junit: src/$IMAGE_NAME/frontend/tests/${IMAGE_NAME}-frontend_report.xml -# Deployment of the service in Kubernetes Cluster -deploy pathcomp: - variables: - IMAGE_NAME: 'pathcomp' # name of the microservice - IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) - stage: deploy - needs: - - unit test pathcomp-backend - - unit test pathcomp-frontend - # - 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 +## Deployment of the service in Kubernetes Cluster +#deploy pathcomp: +# variables: +# IMAGE_NAME: 'pathcomp' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test pathcomp-backend +# - unit test pathcomp-frontend +# # - 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/pathcomp/__init__.py b/src/pathcomp/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/pathcomp/__init__.py +++ b/src/pathcomp/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/backend/Dockerfile b/src/pathcomp/backend/Dockerfile index b351d4715d99ee8a9b518a0cfc827c17cf2bba49..bbe5adc26c4b2b98d3efaaf4d13415f7487d5fa1 100644 --- a/src/pathcomp/backend/Dockerfile +++ b/src/pathcomp/backend/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/backend/Dockerfile-gdb b/src/pathcomp/backend/Dockerfile-gdb index dcf2dbd2fefb22618677b746d1a6cc82a5412e13..c505022e3180a1d182d7a3fbc43c57a1be19dea2 100644 --- a/src/pathcomp/backend/Dockerfile-gdb +++ b/src/pathcomp/backend/Dockerfile-gdb @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/backend/Makefile b/src/pathcomp/backend/Makefile index f4fc1996bb32e87515bb6a1145213cd4e74a4f3b..058701098308620cd1a71f3718b934c63646d42a 100644 --- a/src/pathcomp/backend/Makefile +++ b/src/pathcomp/backend/Makefile @@ -1,19 +1,16 @@ -# -# # Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this 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. -# -# Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es) CC = gcc CFLAGS = -I. -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ diff --git a/src/pathcomp/backend/pathComp.c b/src/pathcomp/backend/pathComp.c index 2a719c92481557424925b09e940dcf73ba09595c..aa6c2b7341862a0115581abee7f977edabe93126 100644 --- a/src/pathcomp/backend/pathComp.c +++ b/src/pathcomp/backend/pathComp.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es) */ -///////////////////////////////////////////////////////////////////////////////////////// #include #include diff --git a/src/pathcomp/backend/pathComp.h b/src/pathcomp/backend/pathComp.h index 76b97fd606854f8aee5ecd4536ca9f2da906f9aa..decded67e9e760c4e4905691f2c1ce834f27eb38 100644 --- a/src/pathcomp/backend/pathComp.h +++ b/src/pathcomp/backend/pathComp.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +12,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ #ifndef _PATHCOMP_H diff --git a/src/pathcomp/backend/pathComp_RESTapi.c b/src/pathcomp/backend/pathComp_RESTapi.c index 709d3dc004027e7eb4e847f73ae1bae25653316e..8ee7f6d82537b7eab297334a0a0dcfad13f8af44 100644 --- a/src/pathcomp/backend/pathComp_RESTapi.c +++ b/src/pathcomp/backend/pathComp_RESTapi.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es) */ -///////////////////////////////////////////////////////////////////////////////////////// + #include #include #include diff --git a/src/pathcomp/backend/pathComp_RESTapi.h b/src/pathcomp/backend/pathComp_RESTapi.h index 80e63da7c13c353592931be9d72f53e30a8aca5b..3b662955959fd8ddad27e337338440b6834f9741 100644 --- a/src/pathcomp/backend/pathComp_RESTapi.h +++ b/src/pathcomp/backend/pathComp_RESTapi.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +12,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ #ifndef _PATH_COMP_REST_API_H diff --git a/src/pathcomp/backend/pathComp_cjson.c b/src/pathcomp/backend/pathComp_cjson.c index 093d80a6d5a342c7719b231cf1aeb8dcc2e90956..f030da9df934bd22295f12b68494f551cab0b79e 100644 --- a/src/pathcomp/backend/pathComp_cjson.c +++ b/src/pathcomp/backend/pathComp_cjson.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es) */ - //////////////////////////////////////////////////////////////////////////////////////// #include #include diff --git a/src/pathcomp/backend/pathComp_cjson.h b/src/pathcomp/backend/pathComp_cjson.h index 47c2830ef3cb1bf6c72c5e3897a066035936b247..dbd233889fc04b8da3a04334d1c8b1e622771690 100644 --- a/src/pathcomp/backend/pathComp_cjson.h +++ b/src/pathcomp/backend/pathComp_cjson.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ - //////////////////////////////////////////////////////////////////////////////////////// #ifndef _PATHCOMP_CJSON_H #define _PATHCOMP_CJSON_H diff --git a/src/pathcomp/backend/pathComp_ksp.c b/src/pathcomp/backend/pathComp_ksp.c index 85c5e750506d56fb7c5511f6c675598adea49ee8..4ea413d5eabbccbe1f86a3bc94edca822ffc4e8d 100644 --- a/src/pathcomp/backend/pathComp_ksp.c +++ b/src/pathcomp/backend/pathComp_ksp.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es) */ - //////////////////////////////////////////////////////////////////////////////////////// + #include #include #include diff --git a/src/pathcomp/backend/pathComp_ksp.h b/src/pathcomp/backend/pathComp_ksp.h index d542c493143ffe2187164c19711425aca7b7fcdf..ef52d315903d234568a88b024882654b459b94ff 100644 --- a/src/pathcomp/backend/pathComp_ksp.h +++ b/src/pathcomp/backend/pathComp_ksp.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +12,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ #ifndef _PATHCOMP_KSP_H diff --git a/src/pathcomp/backend/pathComp_log.c b/src/pathcomp/backend/pathComp_log.c index 5f66e5a1edc8538dffcb20d89cbe2028a08d64d0..1f78ce098888ed198744c8c59bf6458bf4ae8d00 100644 --- a/src/pathcomp/backend/pathComp_log.c +++ b/src/pathcomp/backend/pathComp_log.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ - ///////////////////////////////////////////////////////////////////////////////////////// + #include #include #include @@ -40,7 +37,7 @@ * * @param size * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// @@ -77,7 +74,7 @@ struct stream* stream_new(size_t size) * * @param stream * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// @@ -100,7 +97,7 @@ void stream_free(struct stream* s) * * @param stream * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// @@ -128,7 +125,7 @@ void stream_reset(struct stream* s) * @param ptr * @nbytes * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/pathcomp/backend/pathComp_log.h b/src/pathcomp/backend/pathComp_log.h index d9a14209cb2790fed45c93f0b134251f6a990b16..e9f12a5f1c40a4835915393e8f154cda46b4e918 100644 --- a/src/pathcomp/backend/pathComp_log.h +++ b/src/pathcomp/backend/pathComp_log.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ - //////////////////////////////////////////////////////////////////////////////////////// #ifndef _PATHCOMP_LOG_H #define _PATHCOMP_LOG_H diff --git a/src/pathcomp/backend/pathComp_sp.c b/src/pathcomp/backend/pathComp_sp.c index 735027fafcde1a6dfb9ce82faf3ba71a0bee56e5..447b0d2a6d002d12808f80c855c74f8d0b489743 100644 --- a/src/pathcomp/backend/pathComp_sp.c +++ b/src/pathcomp/backend/pathComp_sp.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ - //////////////////////////////////////////////////////////////////////////////////////// + #include #include #include @@ -53,7 +50,7 @@ struct contextSet_t* contextSet; * @param g * @param s * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// @@ -117,7 +114,7 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv * @param g * @param s * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// @@ -172,7 +169,7 @@ gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s) { * @param path * @param g * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// @@ -257,7 +254,7 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa * * @param outputList * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ void sp_execution_services(struct compRouteOutputList_t* oPathList) @@ -313,7 +310,7 @@ void sp_execution_services(struct compRouteOutputList_t* oPathList) * * @param compRouteOutput * - * @author Ricardo Martnez + * @author Ricardo Mart�nez * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/pathcomp/backend/pathComp_sp.h b/src/pathcomp/backend/pathComp_sp.h index fd0807fea36a69e0456e7e839265505c37ac9f86..5b2d31d43566bbdf9d9f927cfe4bca08be0a920b 100644 --- a/src/pathcomp/backend/pathComp_sp.h +++ b/src/pathcomp/backend/pathComp_sp.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +12,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es) */ #ifndef _PATHCOMP_SP_H diff --git a/src/pathcomp/backend/pathComp_tools.c b/src/pathcomp/backend/pathComp_tools.c index 84cf63994405a07ff6c7fbb1da3fc667b0f0500f..5f1748b1a58a0d1b935c064ef4b92ac8ee0da389 100644 --- a/src/pathcomp/backend/pathComp_tools.c +++ b/src/pathcomp/backend/pathComp_tools.c @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es) */ -///////////////////////////////////////////////////////////////////////////////////////// #include #include diff --git a/src/pathcomp/backend/pathComp_tools.h b/src/pathcomp/backend/pathComp_tools.h index adbbf30c4fda48564c126369b0aace839cdf5d93..b6bcea04c8aa01b6cf730460e0075327f872f344 100644 --- a/src/pathcomp/backend/pathComp_tools.h +++ b/src/pathcomp/backend/pathComp_tools.h @@ -1,6 +1,5 @@ -//////////////////////////////////////////////////////////////////////////////////////// -/** - * # Copyright 2022 Centre Tecnol�gic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es +/* + * Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - * Author: CTTC/CERCA PONS RU Ricardo Mart�nez (ricardo.martinez@cttc.es) */ -///////////////////////////////////////////////////////////////////////////////////////// #ifndef _PATHCOMP_TOOLS_H #define _PATHCOMP_TOOLS_H @@ -121,7 +117,7 @@ struct map_nodes_t { }; #define MAX_NUM_VERTICES 20 // 100 # LGR: reduced from 100 to 20 to divide by 5 the memory used -#define MAX_NUM_EDGES 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 // Structures for the graph composition struct targetNodes_t { // remote / targeted node @@ -154,7 +150,7 @@ struct context_t { //////////////////////////////////////////////////// // Structure for the Set of Contexts /////////////////////////////////////////////////// -#define MAX_NUMBER_CONTEXT 5 // 100 # LGR: reduced from 100 to 5 to divide by 20 the memory used +#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; @@ -251,7 +247,7 @@ struct endPoint_t { // Structure for the device contents /////////////////////////////////////////////////////////////////// #define MAX_DEV_TYPE_SIZE 128 -#define MAX_DEV_ENDPOINT_LENGTH 10 +#define MAX_DEV_ENDPOINT_LENGTH 40 // 10 # LGR: controllers might have large number of endpoints struct device_t { gchar deviceId[UUID_CHAR_LENGTH]; // device ID using UUID (128 bits) diff --git a/src/pathcomp/backend/tests/run-test.sh b/src/pathcomp/backend/tests/run-test.sh old mode 100644 new mode 100755 index 214acdf1b8172a8bbd43056b3e3842583ffff645..1f6a4bd4556b380b9ea254341eee640e28e7095d --- a/src/pathcomp/backend/tests/run-test.sh +++ b/src/pathcomp/backend/tests/run-test.sh @@ -1 +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. + curl -0 -v -X POST -H "Expect:" -H "Content-Type: application/json" http://172.17.0.2:8081/pathComp/api/v1/compRoute -d @inter_domain_test.txt \ No newline at end of file diff --git a/src/pathcomp/frontend/Config.py b/src/pathcomp/frontend/Config.py index f59ca45035ab0efecdf4297467626df18b74fa4d..f17a9f5377b5abcbd9001d1d3773e26998cb3211 100644 --- a/src/pathcomp/frontend/Config.py +++ b/src/pathcomp/frontend/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/Dockerfile b/src/pathcomp/frontend/Dockerfile index 2c511bc073b8d0631bbf120cff98d14a07187c3f..352de75f31366b65e62e2f6357d1bd5f28bd2b0f 100644 --- a/src/pathcomp/frontend/Dockerfile +++ b/src/pathcomp/frontend/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/__init__.py b/src/pathcomp/frontend/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/pathcomp/frontend/__init__.py +++ b/src/pathcomp/frontend/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/client/PathCompClient.py b/src/pathcomp/frontend/client/PathCompClient.py index b5a85b533907ce7744df833aad753c8c38475d02..3ce5b2f33c2c0fac530363dd21f3eac26e42a2c7 100644 --- a/src/pathcomp/frontend/client/PathCompClient.py +++ b/src/pathcomp/frontend/client/PathCompClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/client/__init__.py b/src/pathcomp/frontend/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/pathcomp/frontend/client/__init__.py +++ b/src/pathcomp/frontend/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/requirements.in b/src/pathcomp/frontend/requirements.in index a743bbe341f33f5668aef1fa28c8252af2fc8c00..d99d4cd02b1a9fa39633b35d998b228b3b9e9fc7 100644 --- a/src/pathcomp/frontend/requirements.in +++ b/src/pathcomp/frontend/requirements.in @@ -1 +1,16 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + requests==2.27.1 diff --git a/src/pathcomp/frontend/service/PathCompService.py b/src/pathcomp/frontend/service/PathCompService.py index 88dc5134754cc1b198a505ca9d1cd1f98f2ace22..d86cea7559758b846f668577b2c3b2c67f4cd6c8 100644 --- a/src/pathcomp/frontend/service/PathCompService.py +++ b/src/pathcomp/frontend/service/PathCompService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py index ca4132754fc4886704cb2984519ebc21a19bfd9c..6fc33dbd45a92405fb2fa115e12cb460a9111d54 100644 --- a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py +++ b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import grpc, logging, threading -from common.Constants import DEFAULT_CONTEXT_UUID, INTERDOMAIN_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_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.pathcomp_pb2 import PathCompReply, PathCompRequest @@ -30,7 +30,7 @@ LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool('PathComp', 'RPC') -ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_UUID)) +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) class PathCompServiceServicerImpl(PathCompServiceServicer): def __init__(self) -> None: @@ -45,8 +45,8 @@ class PathCompServiceServicerImpl(PathCompServiceServicer): context_client = ContextClient() 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_UUID) - links = get_links_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_UUID) + 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) else: # TODO: improve filtering of devices and links # TODO: add contexts, topologies, and membership of devices/links in topologies diff --git a/src/pathcomp/frontend/service/__init__.py b/src/pathcomp/frontend/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/pathcomp/frontend/service/__init__.py +++ b/src/pathcomp/frontend/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/__main__.py b/src/pathcomp/frontend/service/__main__.py index 24a5b77418839153839a4fcf92f1a2b42d9cf91d..e3f7d36196be4319cf8364d8569d5289bec2dd89 100644 --- a/src/pathcomp/frontend/service/__main__.py +++ b/src/pathcomp/frontend/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/Factory.py b/src/pathcomp/frontend/service/algorithms/Factory.py index 80d329a9d6d2f3adf824132aca7e4d5a35cffa99..0e00dc11b707467b4e36d80d559502deb26d226b 100644 --- a/src/pathcomp/frontend/service/algorithms/Factory.py +++ b/src/pathcomp/frontend/service/algorithms/Factory.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py index 76b49bc8bd4a5ded840ccad13f0941d05070d344..a9fc4fa3d499f634f021d9ebbb4a749b4f8715c7 100644 --- a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -63,7 +63,9 @@ class KDisjointPathAlgorithm(_Algorithm): if constraint.WhichOneof('constraint') == 'endpoint_location': endpoint_id = constraint.endpoint_location.endpoint_id device_uuid = endpoint_id.device_id.device_uuid.uuid + device_uuid = self.device_name_mapping.get(device_uuid, device_uuid) endpoint_uuid = endpoint_id.endpoint_uuid.uuid + endpoint_uuid = self.endpoint_name_mapping.get((device_uuid, endpoint_uuid), endpoint_uuid) location_kind = constraint.endpoint_location.location.WhichOneof('location') if location_kind != 'region': MSG = 'Unsupported LocationType({:s}) in Constraint({:s})' @@ -74,7 +76,9 @@ class KDisjointPathAlgorithm(_Algorithm): if constraint.WhichOneof('constraint') == 'endpoint_priority': endpoint_id = constraint.endpoint_priority.endpoint_id device_uuid = endpoint_id.device_id.device_uuid.uuid + device_uuid = self.device_name_mapping.get(device_uuid, device_uuid) endpoint_uuid = endpoint_id.endpoint_uuid.uuid + endpoint_uuid = self.endpoint_name_mapping.get((device_uuid, endpoint_uuid), endpoint_uuid) priority = constraint.endpoint_priority.priority endpoints.setdefault((device_uuid, endpoint_uuid), dict())['priority'] = priority @@ -116,8 +120,10 @@ class KDisjointPathAlgorithm(_Algorithm): algorithm = KShortestPathAlgorithm(Algorithm_KShortestPath(k_inspection=0, k_return=1)) algorithm.sync_paths = True algorithm.device_list = self.device_list + algorithm.device_name_mapping = self.device_name_mapping algorithm.device_dict = self.device_dict algorithm.endpoint_dict = self.endpoint_dict + algorithm.endpoint_name_mapping = self.endpoint_name_mapping algorithm.link_list = self.link_list algorithm.link_dict = self.link_dict algorithm.endpoint_to_link_dict = self.endpoint_to_link_dict @@ -135,10 +141,11 @@ class KDisjointPathAlgorithm(_Algorithm): _request = PathCompRequest() for service_key, service_details in self.services_details.items(): service_type, constraints, endpoints = service_details - _service = _request.services.add() + _service = _request.services.add() # pylint: disable=no-member _service.service_id.context_id.context_uuid.uuid = service_key[0] _service.service_id.service_uuid.uuid = service_key[1] _service.service_type = service_type + for constraint_type, constraint_value in constraints.items(): constraint = _service.service_constraints.add() constraint.custom.constraint_type = constraint_type diff --git a/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py index 11da9daa59268b78768c1733333e0d2cc7882335..920d72e828f6f84bc064f1c7357105907ffdac4c 100644 --- a/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py index e0a2441823627843f1e14bde905da4f82ed7a593..4719b8703b4810ad23fcb6e4aa973c7b55088bab 100644 --- a/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/_Algorithm.py b/src/pathcomp/frontend/service/algorithms/_Algorithm.py index a24ef769313c7d71d28e6bcc5526cbc398e05c08..b6316774921171eb8ed6cf3faafd4b607bdcb831 100644 --- a/src/pathcomp/frontend/service/algorithms/_Algorithm.py +++ b/src/pathcomp/frontend/service/algorithms/_Algorithm.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -40,7 +40,9 @@ class _Algorithm: self.device_list : List[Dict] = list() self.device_dict : Dict[str, Tuple[Dict, Device]] = dict() + self.device_name_mapping : Dict[str, str] = dict() self.endpoint_dict : Dict[str, Dict[str, Tuple[Dict, EndPointId]]] = dict() + 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() @@ -56,18 +58,28 @@ class _Algorithm: device_uuid = json_device['device_Id'] self.device_dict[device_uuid] = (json_device, grpc_device) + _device_uuid = grpc_device.device_id.device_uuid.uuid + _device_name = grpc_device.name + self.device_name_mapping[_device_name] = _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): endpoint_uuid = json_endpoint['endpoint_id']['endpoint_uuid'] endpoint_tuple = (json_endpoint['endpoint_id'], grpc_endpoint.endpoint_id) device_endpoint_dict[endpoint_uuid] = endpoint_tuple + _endpoint_uuid = grpc_endpoint.endpoint_id.endpoint_uuid.uuid + _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_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: json_link = compose_link(grpc_link) + if len(json_link['link_endpoint_ids']) != 2: continue self.link_list.append(json_link) link_uuid = json_link['link_Id'] @@ -93,7 +105,7 @@ class _Algorithm: def execute(self, dump_request_filename : Optional[str] = None, dump_reply_filename : Optional[str] = None) -> None: request = {'serviceList': self.service_list, 'deviceList': self.device_list, 'linkList': self.link_list} - self.logger.debug('[execute] request={:s}'.format(str(request))) + self.logger.debug('[execute] request={:s}'.format(json.dumps(request, sort_keys=True, indent=4))) if dump_request_filename is not None: with open(dump_request_filename, 'w', encoding='UTF-8') as f: f.write(json.dumps(request, sort_keys=True, indent=4)) diff --git a/src/pathcomp/frontend/service/algorithms/__init__.py b/src/pathcomp/frontend/service/algorithms/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/pathcomp/frontend/service/algorithms/__init__.py +++ b/src/pathcomp/frontend/service/algorithms/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py index 17a7e74ef573e4926d53045ab8888c71a3dd73d7..bfb4da05fb57bef03fb94fc8973271ceb45f619a 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import logging from typing import Dict -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.proto.context_pb2 import Constraint, Device, EndPointId, Link, Service, ServiceId, TopologyId from common.tools.grpc.Tools import grpc_message_to_json_string from .ConstantsMappings import ( @@ -22,23 +22,27 @@ from .ConstantsMappings import ( LOGGER = logging.getLogger(__name__) -LOGGER = logging.getLogger(__name__) +def compose_topology_id(topology_id : TopologyId) -> Dict: # pylint: disable=unused-argument + # force context_uuid and topology_uuid to be always DEFAULT_CONTEXT_NAME and DEFAULT_TOPOLOGY_NAME for simplicity + # for interdomain, contexts and topologies are managed in particular ways -def compose_topology_id(topology_id : TopologyId) -> Dict: - context_uuid = topology_id.context_id.context_uuid.uuid - topology_uuid = topology_id.topology_uuid.uuid + context_uuid = DEFAULT_CONTEXT_NAME + #context_uuid = topology_id.context_id.context_uuid.uuid + #if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_NAME - if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_UUID - if len(topology_uuid) == 0: topology_uuid = DEFAULT_TOPOLOGY_UUID + topology_uuid = DEFAULT_TOPOLOGY_NAME + #topology_uuid = topology_id.topology_uuid.uuid + #if len(topology_uuid) == 0: topology_uuid = DEFAULT_TOPOLOGY_NAME return {'contextId': context_uuid, 'topology_uuid': topology_uuid} def compose_service_id(service_id : ServiceId) -> Dict: - # force context_uuid to be always DEFAULT_CONTEXT_UUID for simplicity - # for interdomain contexts are managed in a particular way + # force context_uuid to be always DEFAULT_CONTEXT_NAME for simplicity + # for interdomain, contexts are managed in particular ways + #context_uuid = service_id.context_id.context_uuid.uuid - #if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_UUID - context_uuid = DEFAULT_CONTEXT_UUID + #if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_NAME + context_uuid = DEFAULT_CONTEXT_NAME service_uuid = service_id.service_uuid.uuid return {'contextId': context_uuid, 'service_uuid': service_uuid} diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py b/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py index 7c7b62e2d039d2e6bad979b3601e09ca1c54ea51..b92a19b52c4887e01f7f1bc58de897c783683eeb 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py b/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py index 56e11b1b4a0293bcdbed2f1d3cd7c08814d7b161..cd1956a873dd2170c7a75db0c677db34162449ee 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py b/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py index a885ddb29c3fa70d6bccea18f43fef5b038aae68..c8a902999ddfb5011fd7ec09fa99ff6fa697ea40 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py +++ b/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/service/algorithms/tools/__init__.py b/src/pathcomp/frontend/service/algorithms/tools/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/__init__.py +++ b/src/pathcomp/frontend/service/algorithms/tools/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/tests/MockService_Dependencies.py b/src/pathcomp/frontend/tests/MockService_Dependencies.py index 16ff9a5efca5827fdb531dad74aabff29507a580..e903bc0e028c7ef97f21d7422f37255574547338 100644 --- a/src/pathcomp/frontend/tests/MockService_Dependencies.py +++ b/src/pathcomp/frontend/tests/MockService_Dependencies.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/tests/Objects_A_B_C.py b/src/pathcomp/frontend/tests/Objects_A_B_C.py index 510ebb6746ccb8d050d5eb6ea91ec6354f224459..ca9764a34ef0550351c4a0ebcdbd041805c49dde 100644 --- a/src/pathcomp/frontend/tests/Objects_A_B_C.py +++ b/src/pathcomp/frontend/tests/Objects_A_B_C.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import json_device_emulated_packet_router_disabled, json_device_id @@ -41,11 +41,11 @@ def compose_service(endpoint_a, endpoint_z, constraints=[]): return service # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Domains -------------------------------------------------------------------------------------------------------- -TOPOLOGY_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPOLOGY_ADMIN_UUID = DEFAULT_TOPOLOGY_NAME TOPOLOGY_ADMIN_ID = json_topology_id(TOPOLOGY_ADMIN_UUID, context_id=CONTEXT_ID) TOPOLOGY_ADMIN = json_topology(TOPOLOGY_ADMIN_UUID, context_id=CONTEXT_ID) diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py index 06e9bbbc715a85a2c0d979584c58b268bff687e6..1d057c10edcea30e1bf38f63d8a1ad0c6a0a4d46 100644 --- a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py +++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( @@ -58,12 +58,12 @@ def compose_service(endpoint_a, endpoint_z, constraints=[]): return service # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Domains -------------------------------------------------------------------------------------------------------- # Overall network topology -TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_NAME TOPO_ADMIN_ID = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) TOPO_ADMIN = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_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 99fd83ed9e1a7ca27faa6acb11b07abd573423ef..8f6e88719f4019edbeea36c7b4a641fbd7abbea4 100644 --- a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py +++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import uuid -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( @@ -68,12 +68,12 @@ def compose_service(endpoint_a, endpoint_z, constraints=[]): return service # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Domains -------------------------------------------------------------------------------------------------------- # Overall network topology -TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_NAME TOPO_ADMIN_ID = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) TOPO_ADMIN = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) diff --git a/src/pathcomp/frontend/tests/PrepareTestScenario.py b/src/pathcomp/frontend/tests/PrepareTestScenario.py index 2e7002b0f70b81f0bbe728a7b8139730d004221e..387f6aedef1a88559f974a0b792ac1499d42a3f7 100644 --- a/src/pathcomp/frontend/tests/PrepareTestScenario.py +++ b/src/pathcomp/frontend/tests/PrepareTestScenario.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/tests/__init__.py b/src/pathcomp/frontend/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/pathcomp/frontend/tests/__init__.py +++ b/src/pathcomp/frontend/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/frontend/tests/test_unitary.py b/src/pathcomp/frontend/tests/test_unitary.py index 53f4d7065e5ee847cd99f431c87c1231e52bbd63..fd14c8a7aed4ec6e1a1c73aaa9425008abe7db60 100644 --- a/src/pathcomp/frontend/tests/test_unitary.py +++ b/src/pathcomp/frontend/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/pathcomp/misc/my_deploy-tests.sh b/src/pathcomp/misc/my_deploy-tests.sh old mode 100644 new mode 100755 index d744dd5ab491ac9fc0f9f1c69231105276f4dd5b..66564e9a07a6a9ea8eb7cc6ba545c551f614a526 --- a/src/pathcomp/misc/my_deploy-tests.sh +++ b/src/pathcomp/misc/my_deploy-tests.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/pathcomp/misc/test-commands.sh b/src/pathcomp/misc/test-commands.sh old mode 100644 new mode 100755 index 262cb8ed0d035c0abba0178d08cad6e60e72831f..c52b6ce50d761cd2d2d469ad5e55c26bfe84a035 --- a/src/pathcomp/misc/test-commands.sh +++ b/src/pathcomp/misc/test-commands.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/policy/.gitlab-ci.yml b/src/policy/.gitlab-ci.yml index 164540a05172666375f503549f098ef3a90cdf06..8c326ff16e77e2bfef7e065b1e11921e65ec8e9b 100644 --- a/src/policy/.gitlab-ci.yml +++ b/src/policy/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -79,21 +79,21 @@ unit_test policy: - manifests/${IMAGE_NAME_POLICY}service.yaml - .gitlab-ci.yml -# Deployment of policy service in Kubernetes Cluster -deploy policy: - stage: deploy - needs: - - build policy - - unit_test policy - script: - - kubectl version - - kubectl get all - - kubectl delete --ignore-not-found=true -f "manifests/policyservice.yaml" - - kubectl apply -f "manifests/policyservice.yaml" - - kubectl delete pods --selector app=policyservice - - kubectl get all - 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 policy service in Kubernetes Cluster +#deploy policy: +# stage: deploy +# needs: +# - build policy +# - unit_test policy +# script: +# - kubectl version +# - kubectl get all +# - kubectl delete --ignore-not-found=true -f "manifests/policyservice.yaml" +# - kubectl apply -f "manifests/policyservice.yaml" +# - kubectl delete pods --selector app=policyservice +# - kubectl get all +# 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/policy/mvnw b/src/policy/mvnw old mode 100755 new mode 100644 diff --git a/src/policy/pom.xml b/src/policy/pom.xml index 24b1bf2004074abceb6f1c560abc542daec1857f..6ea28421abedf6916e998b6cfdebe23c34908c4a 100644 --- a/src/policy/pom.xml +++ b/src/policy/pom.xml @@ -1,6 +1,6 @@ '/endpoints/endpoint[172.26.60.243:9]' - node_id_src, tp_id_src = check_endpoint(endpoints[0][1], service_uuid) - node_id_dst, tp_id_dst = check_endpoint(endpoints[1][1], service_uuid) - - device_uuid = endpoints[0][0] - device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) + node_id_src, tp_id_src = check_endpoint(endpoint_name_src, service_uuid) + node_id_dst, tp_id_dst = check_endpoint(endpoint_name_dst, service_uuid) + json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { 'uuid' : service_uuid, 'node_id_src': node_id_src, @@ -89,9 +80,9 @@ class MicrowaveServiceHandler(_ServiceHandler): 'tp_id_dst' : tp_id_dst, 'vlan_id' : vlan_id, }) - del device.device_config.config_rules[:] - device.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device) + 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) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to SetEndpoint for Service({:s})'.format(str(service_uuid))) @@ -103,24 +94,29 @@ class MicrowaveServiceHandler(_ServiceHandler): def DeleteEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None ) -> List[Union[bool, Exception]]: - LOGGER.info('[DeleteEndpoint] endpoints={:s}'.format(str(endpoints))) - LOGGER.info('[DeleteEndpoint] connection_uuid={:s}'.format(str(connection_uuid))) + + chk_type('endpoints', endpoints, list) + if len(endpoints) != 2: return [] service_uuid = self.__service.service_id.service_uuid.uuid results = [] try: - chk_type('endpoints', endpoints, list) - if len(endpoints) < 1: raise Exception('len(endpoints) < 1') + device_uuid_src, _ = get_device_endpoint_uuids(endpoints[0]) + 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') + device_uuid = device_uuid_src + + device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - device_uuid = endpoints[0][0] - device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) json_config_rule = json_config_rule_delete('/services/service[{:s}]'.format(service_uuid), { 'uuid': service_uuid }) - del device.device_config.config_rules[:] - device.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device) + 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) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteEndpoint for Service({:s})'.format(str(service_uuid))) @@ -154,9 +150,8 @@ class MicrowaveServiceHandler(_ServiceHandler): results = [] for resource in resources: try: - resource_key, resource_value = resource - resource_value = json.loads(resource_value) - set_subnode_value(self.__resolver, self.__config, resource_key, resource_value) + 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))) @@ -172,8 +167,7 @@ class MicrowaveServiceHandler(_ServiceHandler): results = [] for resource in resources: try: - resource_key, _ = resource - delete_subnode(self.__resolver, self.__config, resource_key) + 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) diff --git a/src/service/service/service_handlers/microwave/__init__.py b/src/service/service/service_handlers/microwave/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/service/service/service_handlers/microwave/__init__.py +++ b/src/service/service/service_handlers/microwave/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/service_handlers/p4/__init__.py b/src/service/service/service_handlers/p4/__init__.py index 9953c820575d42fa88351cc8de022d880ba96e6a..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644 --- a/src/service/service/service_handlers/p4/__init__.py +++ b/src/service/service/service_handlers/p4/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. 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 48b9715b7bb89bc53d6888299836e9b2bf89f1d4..500c50378401c016a6cf30c73c78149e2097d2b8 100644 --- a/src/service/service/service_handlers/p4/p4_service_handler.py +++ b/src/service/service/service_handlers/p4/p4_service_handler.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py index 24371203ad599d7ad9a7f66e5ad96874471be00b..8abd12b2a24c49a6c5e50cebe7a2d65dc7ce4eb1 100644 --- a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py +++ b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,15 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -import anytree, json, logging +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 ConfigActionEnum, ConfigRule, DeviceId, Service +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.AnyTreeTools import TreeNode, delete_subnode, get_subnode, set_subnode_value +from service.service.service_handler_api.SettingsHandler import SettingsHandler from service.service.task_scheduler.TaskExecutor import TaskExecutor LOGGER = logging.getLogger(__name__) @@ -32,37 +33,20 @@ class TapiServiceHandler(_ServiceHandler): self, service : Service, task_executor : TaskExecutor, **settings ) -> None: self.__service = service - self.__task_executor = task_executor # pylint: disable=unused-private-member - self.__resolver = anytree.Resolver(pathattr='name') - self.__config = TreeNode('.') - for config_rule in service.service_config.config_rules: - action = config_rule.action - if config_rule.WhichOneof('config_rule') != 'custom': continue - resource_key = config_rule.custom.resource_key - resource_value = config_rule.custom.resource_value - if action == ConfigActionEnum.CONFIGACTION_SET: - try: - resource_value = json.loads(resource_value) - except: # pylint: disable=bare-except - pass - set_subnode_value(self.__resolver, self.__config, resource_key, resource_value) - elif action == ConfigActionEnum.CONFIGACTION_DELETE: - delete_subnode(self.__resolver, self.__config, resource_key) + 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]]: - LOGGER.info('[SetEndpoint] endpoints={:s}'.format(str(endpoints))) - LOGGER.info('[SetEndpoint] connection_uuid={:s}'.format(str(connection_uuid))) + chk_type('endpoints', endpoints, list) if len(endpoints) != 2: return [] service_uuid = self.__service.service_id.service_uuid.uuid - settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None) - if settings is None: raise Exception('Unable to retrieve settings for Service({:s})'.format(str(service_uuid))) - - json_settings : Dict = settings.value + 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') layer_proto_name = json_settings.get('layer_proto_name', 'PHOTONIC_MEDIA') @@ -71,24 +55,33 @@ class TapiServiceHandler(_ServiceHandler): results = [] try: - device_uuid = endpoints[0][0] - device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - json_config_rule = json_config_rule_set('/service[{:s}]'.format(service_uuid), { + device_uuid_src, endpoint_uuid_src = get_device_endpoint_uuids(endpoints[0]) + 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') + device_uuid = device_uuid_src + + 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 + + json_config_rule = json_config_rule_set('/services/service[{:s}]'.format(service_uuid), { 'uuid' : service_uuid, - 'input_sip' : endpoints[0][1], - 'output_sip' : endpoints[1][1], + 'input_sip' : endpoint_name_src, + 'output_sip' : endpoint_name_dst, 'capacity_unit' : capacity_unit, 'capacity_value' : capacity_value, 'layer_protocol_name' : layer_proto_name, 'layer_protocol_qualifier': layer_proto_qual, 'direction' : direction, }) - del device.device_config.config_rules[:] - device.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device) + 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) results.append(True) except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Unable to configure Service({:s})'.format(str(service_uuid))) + LOGGER.exception('Unable to SetEndpoint for Service({:s})'.format(str(service_uuid))) results.append(e) return results @@ -97,21 +90,29 @@ class TapiServiceHandler(_ServiceHandler): def DeleteEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None ) -> List[Union[bool, Exception]]: - LOGGER.info('[DeleteEndpoint] endpoints={:s}'.format(str(endpoints))) - LOGGER.info('[DeleteEndpoint] connection_uuid={:s}'.format(str(connection_uuid))) chk_type('endpoints', endpoints, list) if len(endpoints) != 2: return [] service_uuid = self.__service.service_id.service_uuid.uuid + results = [] try: - device_uuid = endpoints[0][0] - device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) - json_config_rule = json_config_rule_delete('/service[{:s}]'.format(service_uuid), {'uuid': service_uuid}) - del device.device_config.config_rules[:] - device.device_config.config_rules.append(ConfigRule(**json_config_rule)) - self.__task_executor.configure_device(device) + device_uuid_src, _ = get_device_endpoint_uuids(endpoints[0]) + 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') + device_uuid = device_uuid_src + + device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid))) + + 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) results.append(True) except Exception as e: # pylint: disable=broad-except LOGGER.exception('Unable to DeleteEndpoint for Service({:s})'.format(str(service_uuid))) @@ -145,9 +146,8 @@ class TapiServiceHandler(_ServiceHandler): results = [] for resource in resources: try: - resource_key, resource_value = resource - resource_value = json.loads(resource_value) - set_subnode_value(self.__resolver, self.__config, resource_key, resource_value) + 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))) @@ -163,8 +163,7 @@ class TapiServiceHandler(_ServiceHandler): results = [] for resource in resources: try: - resource_key, _ = resource - delete_subnode(self.__resolver, self.__config, resource_key) + 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) diff --git a/src/service/service/service_handlers/tapi_tapi/__init__.py b/src/service/service/service_handlers/tapi_tapi/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/service/service/service_handlers/tapi_tapi/__init__.py +++ b/src/service/service/service_handlers/tapi_tapi/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/ConnectionExpander.py b/src/service/service/task_scheduler/ConnectionExpander.py index 39c91b1ba7129d6915ab578f2e85b670049def04..fa51c36ce4bf9dd9f1dd465e07e804b068ebae57 100644 --- a/src/service/service/task_scheduler/ConnectionExpander.py +++ b/src/service/service/task_scheduler/ConnectionExpander.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py index 7c96eb665e75a08f2a47fa9d78a0bd9cc37a876e..932c56e2b1934e12e7849a60c22d3ca1be7f8093 100644 --- a/src/service/service/task_scheduler/TaskExecutor.py +++ b/src/service/service/task_scheduler/TaskExecutor.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/TaskScheduler.py b/src/service/service/task_scheduler/TaskScheduler.py index 6f2bdba3e14a799e361b2543b4160b69b230d66a..f55527e4756022fc4941605f54ab82b74c0937f0 100644 --- a/src/service/service/task_scheduler/TaskScheduler.py +++ b/src/service/service/task_scheduler/TaskScheduler.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/__init__.py b/src/service/service/task_scheduler/__init__.py index 70bfa5118f47eb93d5cdd0832ee7928030369286..9d49eb5e732045445c7e63944bf79229da3c3bcd 100644 --- a/src/service/service/task_scheduler/__init__.py +++ b/src/service/service/task_scheduler/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py index cfafd54e51f73b78d18d13a1c6d9e2c18ac4c944..5a47005b304836050dd8c0882214dd9cebd5d8b5 100644 --- a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py +++ b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py index 4c8b75b2f365724215a690b97e98198405f4632c..5736054febd2fb9e8a36b5a2235ca3f412e0e174 100644 --- a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py +++ b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py index 15da1ffedbb3235e6697dcd6c4b0c0429cad0450..6a4e11b540cd9b85028d92cf86899ee098056c36 100644 --- a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py +++ b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py index 163954f1b786916ad8c5fde5e8a04def84af259b..815cb33c3d540755704153b661e889fc2660d268 100644 --- a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py +++ b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/tasks/_Task.py b/src/service/service/task_scheduler/tasks/_Task.py index c36f92973bfa3847c86d2d745792062ec828492f..c2dbcdf659b05ab082eb76aa1fe8f4b46394ed83 100644 --- a/src/service/service/task_scheduler/tasks/_Task.py +++ b/src/service/service/task_scheduler/tasks/_Task.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/task_scheduler/tasks/__init__.py b/src/service/service/task_scheduler/tasks/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/service/service/task_scheduler/tasks/__init__.py +++ b/src/service/service/task_scheduler/tasks/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/tools/ContextGetters.py b/src/service/service/tools/ContextGetters.py index 79ccf956b26e914bfbe6bdedd005d9f98e216d38..9b1d6224d1e4201cbc0720e7ce818a86e5ae2042 100644 --- a/src/service/service/tools/ContextGetters.py +++ b/src/service/service/tools/ContextGetters.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/tools/EndpointIdFormatters.py b/src/service/service/tools/EndpointIdFormatters.py index 2435df42cfa10d336553945e7e70171838f69237..ff1d5081671109d6c09cd46166d50585317789ec 100644 --- a/src/service/service/tools/EndpointIdFormatters.py +++ b/src/service/service/tools/EndpointIdFormatters.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/tools/ObjectKeys.py b/src/service/service/tools/ObjectKeys.py index e58d8bd3e9e5c992a3b9be9c3275f3b40c7ba5e9..14c4cdf3ad661df0aa8f22599a294fe50db4a1a9 100644 --- a/src/service/service/tools/ObjectKeys.py +++ b/src/service/service/tools/ObjectKeys.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/service/tools/__init__.py b/src/service/service/tools/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/service/service/tools/__init__.py +++ b/src/service/service/tools/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/CommonObjects.py b/src/service/tests/CommonObjects.py index 7792ad61d0e537911f593ec29d8366bb59fbb9f6..4cd233349ae4f0e7b39b5597fdbd6ff9d00e5189 100644 --- a/src/service/tests/CommonObjects.py +++ b/src/service/tests/CommonObjects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,18 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Topology import json_topology, json_topology_id # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- Monitoring Samples --------------------------------------------------------------------------------------------- PACKET_PORT_SAMPLE_TYPES = [ diff --git a/src/service/tests/MockService_Dependencies.py b/src/service/tests/MockService_Dependencies.py index 3774e22088e95b2325adf2fb46c386ebd6f8f7a8..eb3059d5a28f3686861a1fad3de03f97d502545f 100644 --- a/src/service/tests/MockService_Dependencies.py +++ b/src/service/tests/MockService_Dependencies.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/PrepareTestScenario.py b/src/service/tests/PrepareTestScenario.py index bcf3cd156ab04e932e440837dc8ca0df645dc0cc..e4609ec416803312926422aca16cb02a6785a789 100644 --- a/src/service/tests/PrepareTestScenario.py +++ b/src/service/tests/PrepareTestScenario.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/ServiceHandler_L3NM_EMU.py b/src/service/tests/ServiceHandler_L3NM_EMU.py index 45df80e4265018e802be587285fce318fc6b0736..3df27b439626dad652e443cca4195ce36f4ac86f 100644 --- a/src/service/tests/ServiceHandler_L3NM_EMU.py +++ b/src/service/tests/ServiceHandler_L3NM_EMU.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/ServiceHandler_L3NM_OC.py b/src/service/tests/ServiceHandler_L3NM_OC.py index 717536f6d1ee60564752f3107cd366796e3a36e2..a8f1e315a136838cdea4e2c7c4c9e444be250a4b 100644 --- a/src/service/tests/ServiceHandler_L3NM_OC.py +++ b/src/service/tests/ServiceHandler_L3NM_OC.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/ServiceHandlersToTest.py b/src/service/tests/ServiceHandlersToTest.py index 43f2a2eb2e720eea5b9f690e374ec3b5830eac1d..c50a0b45774f15497578a9c5b365e1e331d6d95e 100644 --- a/src/service/tests/ServiceHandlersToTest.py +++ b/src/service/tests/ServiceHandlersToTest.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/__init__.py b/src/service/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/service/tests/__init__.py +++ b/src/service/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/test_unitary.py b/src/service/tests/test_unitary.py index e12ec2bc4dda856d76acd50c90af4b7d7941fb00..f99f9b191083db017486d03d0bc93b0d9152b35f 100644 --- a/src/service/tests/test_unitary.py +++ b/src/service/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/service/tests/test_unitary_task_scheduler.py b/src/service/tests/test_unitary_task_scheduler.py index 020386d764ddc508d8fe6806ab1de6887620e33f..cd77934f6681b0e50c2ddba4b529e4a662b1b63f 100644 --- a/src/service/tests/test_unitary_task_scheduler.py +++ b/src/service/tests/test_unitary_task_scheduler.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/.gitlab-ci.yml b/src/slice/.gitlab-ci.yml index 9393e6b29a2fbe180e74944375c871af4c4ae3d6..39edd20b325c60c40dafddd4dd220b2615042f60 100644 --- a/src/slice/.gitlab-ci.yml +++ b/src/slice/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -39,13 +39,14 @@ build slice: - .gitlab-ci.yml # Apply unit test to the component -unit test slice: +unit_test slice: variables: IMAGE_NAME: 'slice' # name of the microservice IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) stage: unit_test needs: - build slice + - unit_test service 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 @@ -79,28 +80,28 @@ unit test slice: reports: junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml -# Deployment of the service in Kubernetes Cluster -deploy slice: - variables: - IMAGE_NAME: 'slice' # name of the microservice - IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) - stage: deploy - needs: - - unit test slice - # - 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 +## Deployment of the service in Kubernetes Cluster +#deploy slice: +# variables: +# IMAGE_NAME: 'slice' # name of the microservice +# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) +# stage: deploy +# needs: +# - unit test slice +# # - 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/slice/Config.py b/src/slice/Config.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/slice/Config.py +++ b/src/slice/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/Dockerfile b/src/slice/Dockerfile index 7dadc477f70667c827d4a9eb0ddd013c85b97344..4c434e212da441c5a56e58e9a9509195c202355f 100644 --- a/src/slice/Dockerfile +++ b/src/slice/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/__init__.py b/src/slice/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/slice/__init__.py +++ b/src/slice/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/client/SliceClient.py b/src/slice/client/SliceClient.py index 520f00e6cafa98a3247ea4655c5d36ddeb7c2309..a3e5d649032bbf939f9ba6d812b270ca3384cc06 100644 --- a/src/slice/client/SliceClient.py +++ b/src/slice/client/SliceClient.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/client/__init__.py b/src/slice/client/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/slice/client/__init__.py +++ b/src/slice/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/old_code/ConstraintsChecker.py b/src/slice/old_code/ConstraintsChecker.py index f87dab65feff7275966ba8dc43ea0cdb396f32fc..a9e244f76a65dbf68f499096f315944db3272b33 100644 --- a/src/slice/old_code/ConstraintsChecker.py +++ b/src/slice/old_code/ConstraintsChecker.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/old_code/SliceCheckers.py b/src/slice/old_code/SliceCheckers.py index 660a522d082fdc918eaa895e09f8469ede05713b..a4412065fad758dc8ca3bdfc19f7b12effde6d67 100644 --- a/src/slice/old_code/SliceCheckers.py +++ b/src/slice/old_code/SliceCheckers.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/old_code/SliceStatus.py b/src/slice/old_code/SliceStatus.py index d97b3944999e58cc2ad54f28ed6e22232b5fcd71..2104c4dbe8d7a60f5c1ff7489566cd0263949fb9 100644 --- a/src/slice/old_code/SliceStatus.py +++ b/src/slice/old_code/SliceStatus.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 class SliceStatus(Enum): diff --git a/src/slice/old_code/Tools.py b/src/slice/old_code/Tools.py index 08323f935195d8a0221b3f8889c0e6beeef94cb2..8260a817711b699b2a0515e360a27ff724960e40 100644 --- a/src/slice/old_code/Tools.py +++ b/src/slice/old_code/Tools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/old_code/Tools_2.py b/src/slice/old_code/Tools_2.py index c29a11a06bc7e4258fe4798ebf632a1f00db3170..fffc9eed3eadc19df361f8fe1521164034b3e140 100644 --- a/src/slice/old_code/Tools_2.py +++ b/src/slice/old_code/Tools_2.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/requirements.in b/src/slice/requirements.in index 0a2c39895c9a1f642470bcc26cb67bd8dfb169b1..daef740da4729659fb3117eadff31994acdf5746 100644 --- a/src/slice/requirements.in +++ b/src/slice/requirements.in @@ -1 +1,16 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + #deepdiff==5.8.* diff --git a/src/slice/service/SliceService.py b/src/slice/service/SliceService.py index 7a404d188b783a4f0051195ddf5f35ab26cf6846..4289e5e81a2b0ded58a69368402adfeef6a2e1c0 100644 --- a/src/slice/service/SliceService.py +++ b/src/slice/service/SliceService.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py index aa41a77ac7b5ce1ec6dabba0f841692ce2f8f42e..21d820089aad9531834187e129d893e90f3c93a8 100644 --- a/src/slice/service/SliceServiceServicerImpl.py +++ b/src/slice/service/SliceServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,12 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Optional import grpc, json, logging #, deepdiff from common.proto.context_pb2 import ( Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum) 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.grpc.ConfigRules import copy_config_rules from common.tools.grpc.Constraints import copy_constraints from common.tools.grpc.EndPointIds import copy_endpoint_ids @@ -37,29 +39,32 @@ class SliceServiceServicerImpl(SliceServiceServicer): LOGGER.debug('Servicer Created') def create_update(self, request : Slice) -> SliceId: + # Set slice status to "SERVICESTATUS_PLANNED" to ensure rest of components are aware the slice is + # being modified. context_client = ContextClient() - try: - _slice = context_client.GetSlice(request.slice_id) - #json_current_slice = grpc_message_to_json(_slice) - except: # pylint: disable=bare-except - #json_current_slice = {} - slice_request = Slice() - slice_request.slice_id.CopyFrom(request.slice_id) # pylint: disable=no-member - slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED # pylint: disable=no-member - context_client.SetSlice(slice_request) - _slice = context_client.GetSlice(request.slice_id) + 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_rw = Slice() + slice_rw.CopyFrom(request if slice_ro is None else slice_ro) + slice_rw.name = request.name + slice_rw.slice_owner.CopyFrom(request.slice_owner) # pylint: disable=no-member + slice_rw.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED # pylint: disable=no-member - slice_request = Slice() - slice_request.CopyFrom(_slice) + copy_endpoint_ids(request.slice_endpoint_ids, slice_rw.slice_endpoint_ids ) # pylint: disable=no-member + copy_constraints (request.slice_constraints, slice_rw.slice_constraints ) # pylint: disable=no-member + copy_config_rules(request.slice_config.config_rules, slice_rw.slice_config.config_rules) # pylint: disable=no-member - if len(request.slice_endpoint_ids) < 2: + slice_id_with_uuids = context_client.SetSlice(slice_rw) + + if len(slice_rw.slice_endpoint_ids) < 2: # pylint: disable=no-member # unable to identify the kind of slice; just update endpoints, constraints and config rules # update the slice in database, and return # pylint: disable=no-member - copy_endpoint_ids(request.slice_endpoint_ids, slice_request.slice_endpoint_ids) - copy_constraints(request.slice_constraints, slice_request.slice_constraints) - copy_config_rules(request.slice_config.config_rules, slice_request.slice_config.config_rules) - return context_client.SetSlice(slice_request) + return context_client.SetSlice(slice_rw) + + slice_with_uuids = context_client.GetSlice(slice_id_with_uuids) #LOGGER.info('json_current_slice = {:s}'.format(str(json_current_slice))) #json_updated_slice = grpc_message_to_json(request) @@ -67,9 +72,9 @@ class SliceServiceServicerImpl(SliceServiceServicer): #changes = deepdiff.DeepDiff(json_current_slice, json_updated_slice) #LOGGER.info('changes = {:s}'.format(str(changes))) - if is_multi_domain(context_client, request.slice_endpoint_ids): + if is_multi_domain(context_client, slice_with_uuids.slice_endpoint_ids): interdomain_client = InterdomainClient() - slice_id = interdomain_client.RequestSlice(request) + slice_id = interdomain_client.RequestSlice(slice_with_uuids) slice_ = context_client.GetSlice(slice_id) slice_active = Slice() slice_active.CopyFrom(slice_) @@ -80,8 +85,8 @@ class SliceServiceServicerImpl(SliceServiceServicer): # Local domain slice service_id = ServiceId() # pylint: disable=no-member - context_uuid = service_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid - slice_uuid = service_uuid = service_id.service_uuid.uuid = request.slice_id.slice_uuid.uuid + context_uuid = service_id.context_id.context_uuid.uuid = slice_with_uuids.slice_id.context_id.context_uuid.uuid + service_uuid = service_id.service_uuid.uuid = slice_with_uuids.slice_id.slice_uuid.uuid service_client = ServiceClient() try: @@ -92,10 +97,7 @@ class SliceServiceServicerImpl(SliceServiceServicer): service_request.service_id.CopyFrom(service_id) service_request.service_type = ServiceTypeEnum.SERVICETYPE_UNKNOWN service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED - service_reply = service_client.CreateService(service_request) - if service_reply != service_request.service_id: # pylint: disable=no-member - # pylint: disable=raise-missing-from - raise Exception('Service creation failed. Wrong Service Id was returned') + service_client.CreateService(service_request) _service = context_client.GetService(service_id) service_request = Service() service_request.CopyFrom(_service) @@ -137,17 +139,15 @@ class SliceServiceServicerImpl(SliceServiceServicer): service_request.service_type = ServiceTypeEnum.SERVICETYPE_L2NM LOGGER.info('assume L2') - service_reply = service_client.UpdateService(service_request) - if service_reply != service_request.service_id: # pylint: disable=no-member - raise Exception('Service update failed. Wrong Service Id was returned') + service_client.UpdateService(service_request) - copy_endpoint_ids(request.slice_endpoint_ids, slice_request.slice_endpoint_ids) - copy_constraints(request.slice_constraints, slice_request.slice_constraints) - copy_config_rules(request.slice_config.config_rules, slice_request.slice_config.config_rules) + #copy_endpoint_ids(request.slice_endpoint_ids, slice_with_uuids.slice_endpoint_ids) + #copy_constraints(request.slice_constraints, slice_with_uuids.slice_constraints) + #copy_config_rules(request.slice_config.config_rules, slice_with_uuids.slice_config.config_rules) - update_service_ids(slice_request.slice_service_ids, context_uuid, service_uuid) - context_client.SetSlice(slice_request) - slice_id = slice_request.slice_id + update_service_ids(slice_with_uuids.slice_service_ids, context_uuid, service_uuid) + context_client.SetSlice(slice_with_uuids) + slice_id = slice_with_uuids.slice_id slice_ = context_client.GetSlice(slice_id) slice_active = Slice() @@ -199,14 +199,14 @@ class SliceServiceServicerImpl(SliceServiceServicer): else: current_slice = Slice() current_slice.CopyFrom(_slice) - current_slice.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_DEINIT + current_slice.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_DEINIT # pylint: disable=no-member context_client.SetSlice(current_slice) service_client = ServiceClient() for service_id in _slice.slice_service_ids: current_slice = Slice() - current_slice.slice_id.CopyFrom(_slice.slice_id) - slice_service_id = current_slice.slice_service_ids.add() + current_slice.slice_id.CopyFrom(_slice.slice_id) # pylint: disable=no-member + slice_service_id = current_slice.slice_service_ids.add() # pylint: disable=no-member slice_service_id.CopyFrom(service_id) context_client.UnsetSlice(current_slice) diff --git a/src/slice/service/__init__.py b/src/slice/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/slice/service/__init__.py +++ b/src/slice/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/service/__main__.py b/src/slice/service/__main__.py index b2f4536503ac176628c42cf0211315089697c50e..aef1c4b82a540ddb40f35f4af2340ead539a0451 100644 --- a/src/slice/service/__main__.py +++ b/src/slice/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/tests/__init__.py b/src/slice/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/slice/tests/__init__.py +++ b/src/slice/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/slice/tests/test_unitary.py b/src/slice/tests/test_unitary.py index 1fd5a75b4dc1bb0192c8eeda6a0d452c0a9465dd..a61ccbcd603cc69025b98051d5480570bd4018ff 100644 --- a/src/slice/tests/test_unitary.py +++ b/src/slice/tests/test_unitary.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/start.sh b/src/start.sh index dc9db79d27d4d1b459092bf2f9a8f43bb5581511..32a016cc07d2602d5e00b7540b03355f539ed61d 100755 --- a/src/start.sh +++ b/src/start.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/start_webui_dev_mode.sh b/src/start_webui_dev_mode.sh index 74540bcb36115dc175f371acbb3f80930404eac9..fe2587c1a596bb49558fe8f1cd9238727277bbfe 100755 --- a/src/start_webui_dev_mode.sh +++ b/src/start_webui_dev_mode.sh @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,19 +14,23 @@ # for development purposes only -K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'} +# K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'} -export CONTEXTSERVICE_SERVICE_HOST=`kubectl get service/contextservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` +# export CONTEXTSERVICE_SERVICE_HOST=`kubectl get service/contextservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` -echo Context IP: $CONTEXTSERVICE_SERVICE_HOST +# echo Context IP: $CONTEXTSERVICE_SERVICE_HOST -export DEVICESERVICE_SERVICE_HOST=`kubectl get service/deviceservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` +# export DEVICESERVICE_SERVICE_HOST=`kubectl get service/deviceservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'` -echo Device IP: $DEVICESERVICE_SERVICE_HOST +# echo Device IP: $DEVICESERVICE_SERVICE_HOST + +source tfs_runtime_env_vars.sh export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION='python' export HOST="127.0.0.1" +export HOSTNAME="test" export FLASK_ENV="development" +export LOG_LEVEL="DEBUG" # python3 -m webbrowser http://${HOST}:8004 diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml index 6fcac64803e92b238eb1a63ce92814e67e3138ab..db44b9e4a8d29475a0b6cd620ffd9a6961f8cdc5 100644 --- a/src/tests/.gitlab-ci.yml +++ b/src/tests/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/Fixtures.py b/src/tests/Fixtures.py index 25b73e1de143b8c60d9a726ddf2bd3cea97d17a5..ecb44a7588d62e14f4295141adb3acc7bbe89532 100644 --- a/src/tests/Fixtures.py +++ b/src/tests/Fixtures.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/__init__.py b/src/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/__init__.py +++ b/src/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/ZtpAdd.js b/src/tests/benchmark/automation/ZtpAdd.js index 0f649b8ccfbd910faadcc41549eddf34b83c6795..d7740ad32c8b685a31a31c5fc09a7a7cc6ef27a0 100644 --- a/src/tests/benchmark/automation/ZtpAdd.js +++ b/src/tests/benchmark/automation/ZtpAdd.js @@ -1,3 +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. + */ + import grpc from 'k6/net/grpc'; import exec from "k6/execution"; import { check, sleep } from 'k6'; diff --git a/src/tests/benchmark/automation/ZtpDelete.js b/src/tests/benchmark/automation/ZtpDelete.js index 58af9f25d924dda254e142dcf3962b62359ff42c..b1b7f3a09734d484ef14868cbf93c87dce79f357 100644 --- a/src/tests/benchmark/automation/ZtpDelete.js +++ b/src/tests/benchmark/automation/ZtpDelete.js @@ -1,3 +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. + */ + import grpc from 'k6/net/grpc'; import exec from "k6/execution"; import { check, sleep } from 'k6'; diff --git a/src/tests/benchmark/automation/ZtpUpdate.js b/src/tests/benchmark/automation/ZtpUpdate.js old mode 100755 new mode 100644 index 39135ec58643339562ff87c96a03be3968c198d4..c274d22861ae6df52906d57cfb545eb1dc3c94c2 --- a/src/tests/benchmark/automation/ZtpUpdate.js +++ b/src/tests/benchmark/automation/ZtpUpdate.js @@ -1,3 +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. + */ + import grpc from 'k6/net/grpc'; import exec from "k6/execution"; import { check, sleep } from 'k6'; diff --git a/src/tests/benchmark/automation/__init__.py b/src/tests/benchmark/automation/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/benchmark/automation/__init__.py +++ b/src/tests/benchmark/automation/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/run_test_01_bootstrap.sh b/src/tests/benchmark/automation/run_test_01_bootstrap.sh index dee1739270944bc19e370bb249b083f740e60737..2382521b26cbf6217aacea7c2f9d86fdac1209be 100755 --- a/src/tests/benchmark/automation/run_test_01_bootstrap.sh +++ b/src/tests/benchmark/automation/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/run_test_02_cleanup.sh b/src/tests/benchmark/automation/run_test_02_cleanup.sh index 8f68302d6abfeac6750fff7183524c644355008e..56965d2007b441ab76ab07777a04c25b38eb8b28 100755 --- a/src/tests/benchmark/automation/run_test_02_cleanup.sh +++ b/src/tests/benchmark/automation/run_test_02_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/tests/Fixtures.py b/src/tests/benchmark/automation/tests/Fixtures.py index 3b35a12e299ba776e909fbdd2739e971431083a6..89dda54cf945d7078cd61c4b94b282f650429309 100644 --- a/src/tests/benchmark/automation/tests/Fixtures.py +++ b/src/tests/benchmark/automation/tests/Fixtures.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/tests/Objects.py b/src/tests/benchmark/automation/tests/Objects.py index 8ea6f500807e3dbcc2e34dbd559614ff91c955d8..8558d1fe7af84f1e312bc44eb458a3624ed694ae 100644 --- a/src/tests/benchmark/automation/tests/Objects.py +++ b/src/tests/benchmark/automation/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. from typing import Dict, List, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_connect_rules, json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, @@ -24,12 +24,12 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from common.proto.kpi_sample_types_pb2 import KpiSampleType # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- Monitoring Samples --------------------------------------------------------------------------------------------- PACKET_PORT_SAMPLE_TYPES = [ diff --git a/src/tests/benchmark/automation/tests/__init__.py b/src/tests/benchmark/automation/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/benchmark/automation/tests/__init__.py +++ b/src/tests/benchmark/automation/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/tests/test_functional_bootstrap.py b/src/tests/benchmark/automation/tests/test_functional_bootstrap.py index 3d588801511ae3bc6b5be87566c61b04bf54e467..f61125a8c2bbb9e96785d176b14eabf08e9419a1 100644 --- a/src/tests/benchmark/automation/tests/test_functional_bootstrap.py +++ b/src/tests/benchmark/automation/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/automation/tests/test_functional_cleanup.py b/src/tests/benchmark/automation/tests/test_functional_cleanup.py index 9b6e51c3e296261e52669980f656c6fdf12ceb65..4b0c52dd4aea4ec7e4adb576c9557d53713ba332 100644 --- a/src/tests/benchmark/automation/tests/test_functional_cleanup.py +++ b/src/tests/benchmark/automation/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/PolicyAddService.js b/src/tests/benchmark/policy/PolicyAddService.js index 708209ba01862a169dd7007a05e2ba29a198282a..d765709975d8ed14cb7696b14cdf1a07a2707b3d 100644 --- a/src/tests/benchmark/policy/PolicyAddService.js +++ b/src/tests/benchmark/policy/PolicyAddService.js @@ -1,3 +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. + */ + import grpc from 'k6/net/grpc'; import exec from "k6/execution"; import { check, sleep } from 'k6'; diff --git a/src/tests/benchmark/policy/PolicyDelete.js b/src/tests/benchmark/policy/PolicyDelete.js index 85946837eb1123bd698f907e13415b7281a779d2..6ec85a6a3c30b7b8af258918a49cb8e8e7adeb67 100644 --- a/src/tests/benchmark/policy/PolicyDelete.js +++ b/src/tests/benchmark/policy/PolicyDelete.js @@ -1,3 +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. + */ + import grpc from 'k6/net/grpc'; import exec from "k6/execution"; import { check, sleep } from 'k6'; diff --git a/src/tests/benchmark/policy/PolicyUpdateService.js b/src/tests/benchmark/policy/PolicyUpdateService.js index a3774f9dac0dec420b88e6e236e8dcd2e698e3cd..ddf7836b595b7021a8ca7b2c7b37c89b653c1999 100644 --- a/src/tests/benchmark/policy/PolicyUpdateService.js +++ b/src/tests/benchmark/policy/PolicyUpdateService.js @@ -1,3 +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. + */ + import grpc from 'k6/net/grpc'; import exec from "k6/execution"; import { check, sleep } from 'k6'; diff --git a/src/tests/benchmark/policy/__init__.py b/src/tests/benchmark/policy/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/benchmark/policy/__init__.py +++ b/src/tests/benchmark/policy/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/deploy_specs.sh b/src/tests/benchmark/policy/deploy_specs.sh old mode 100644 new mode 100755 index ffd91da35186fe21f418950493ef797a9af1b522..12a45ef92a538ff48682fe45172a27d77b2800a0 --- a/src/tests/benchmark/policy/deploy_specs.sh +++ b/src/tests/benchmark/policy/deploy_specs.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/tests/benchmark/policy/run_test_01_bootstrap.sh b/src/tests/benchmark/policy/run_test_01_bootstrap.sh index 10b18257b937a5aae82a66cd5e3df83abd44e1d8..a60f962c8ae14c89cccb53ac2fd27f6ffe5c98ea 100755 --- a/src/tests/benchmark/policy/run_test_01_bootstrap.sh +++ b/src/tests/benchmark/policy/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/run_test_02_create_service.sh b/src/tests/benchmark/policy/run_test_02_create_service.sh index 69ef34ff954d550fbe2c22719f0afb2eb3360525..d899a1455cba2fa92418746373a825a383d3e25c 100755 --- a/src/tests/benchmark/policy/run_test_02_create_service.sh +++ b/src/tests/benchmark/policy/run_test_02_create_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/run_test_03_delete_service.sh b/src/tests/benchmark/policy/run_test_03_delete_service.sh index 01eb521310053b06538c91cbfaae80aa3b2fdd45..2cfe25effbaa5dd64a1b445fa2063d91f6348440 100755 --- a/src/tests/benchmark/policy/run_test_03_delete_service.sh +++ b/src/tests/benchmark/policy/run_test_03_delete_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/run_test_04_cleanup.sh b/src/tests/benchmark/policy/run_test_04_cleanup.sh index a2be265de04552cbebe83decba538656232bf904..d93f798cb24f59e06dc9445e373f74d2dad01c74 100755 --- a/src/tests/benchmark/policy/run_test_04_cleanup.sh +++ b/src/tests/benchmark/policy/run_test_04_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/Fixtures.py b/src/tests/benchmark/policy/tests/Fixtures.py index 3b35a12e299ba776e909fbdd2739e971431083a6..89dda54cf945d7078cd61c4b94b282f650429309 100644 --- a/src/tests/benchmark/policy/tests/Fixtures.py +++ b/src/tests/benchmark/policy/tests/Fixtures.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/Objects.py b/src/tests/benchmark/policy/tests/Objects.py index 7bfbe9fce558d6a86d965ecb6421369d7f544d4d..887407bf4a472d183002856716a65bf23ea0e586 100644 --- a/src/tests/benchmark/policy/tests/Objects.py +++ b/src/tests/benchmark/policy/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/__init__.py b/src/tests/benchmark/policy/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/benchmark/policy/tests/__init__.py +++ b/src/tests/benchmark/policy/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/test_functional_bootstrap.py b/src/tests/benchmark/policy/tests/test_functional_bootstrap.py index 71deb9d596b1494e148b140902ca927e5d664dd3..65c46b4eb5aea8d5762484d1558c14745acf83ed 100644 --- a/src/tests/benchmark/policy/tests/test_functional_bootstrap.py +++ b/src/tests/benchmark/policy/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/test_functional_cleanup.py b/src/tests/benchmark/policy/tests/test_functional_cleanup.py index be807eaa0242f2363b5b6c189ce4de264528a54c..e00c5ceeea6c59bf11bd2961802a9a3b805c5d2c 100644 --- a/src/tests/benchmark/policy/tests/test_functional_cleanup.py +++ b/src/tests/benchmark/policy/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/test_functional_create_service.py b/src/tests/benchmark/policy/tests/test_functional_create_service.py index e606d060d52631ba72e191d7c025bd7b43048b39..919f81979305831b69a82f13fbe4b70bd20ea70f 100644 --- a/src/tests/benchmark/policy/tests/test_functional_create_service.py +++ b/src/tests/benchmark/policy/tests/test_functional_create_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/benchmark/policy/tests/test_functional_delete_service.py b/src/tests/benchmark/policy/tests/test_functional_delete_service.py index 0f8d088012bed164e4603a813bfe9154eda8f568..6f6ca602980fb05ffafd17f44a5bc64671c4c7b0 100644 --- a/src/tests/benchmark/policy/tests/test_functional_delete_service.py +++ b/src/tests/benchmark/policy/tests/test_functional_delete_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import logging -from common.Constants import DEFAULT_CONTEXT_UUID +from common.Constants import DEFAULT_CONTEXT_NAME from common.DeviceTypes import DeviceTypeEnum from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum from common.tools.descriptor.Loader import DescriptorLoader @@ -55,7 +55,7 @@ def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # p assert len(response.links) == descriptor_loader.num_links l3nm_service_uuids = set() - response = context_client.ListServices(ContextId(**json_context_id(DEFAULT_CONTEXT_UUID))) + response = context_client.ListServices(ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))) assert len(response.services) == 2 # OLS & L3NM => (L3NM + TAPI) for service in response.services: service_id = service.service_id diff --git a/src/tests/ecoc22/__init__.py b/src/tests/ecoc22/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/ecoc22/__init__.py +++ b/src/tests/ecoc22/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ecoc22/deploy_specs.sh b/src/tests/ecoc22/deploy_specs.sh old mode 100644 new mode 100755 index 8afd683843d4882e75c3cbca8363aa3d63edda7f..874774e1ca50830832e842e49b6fff1114cb85d8 --- a/src/tests/ecoc22/deploy_specs.sh +++ b/src/tests/ecoc22/deploy_specs.sh @@ -1,17 +1,94 @@ -# Set the URL of your local Docker registry where the images will be uploaded to. -export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" +#!/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 load_generator" export TFS_COMPONENTS="context device automation monitoring 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 to. +# Set the name of the Kubernetes namespace to deploy TFS to. export TFS_K8S_NAMESPACE="tfs" # Set additional manifest files to be applied after the deployment export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" -# Set the neew Grafana admin password +# 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 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" + +# 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 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" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# If not already set, set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb" + +# If not already set, set the database username to be used by Monitoring. +export QDB_USERNAME="admin" + +# If not already set, set the database user's password to be used by Monitoring. +export QDB_PASSWORD="quest" + +# If not already set, set the table name to be used by Monitoring. +export QDB_TABLE="tfs_monitoring" + +## If not already set, disable flag for dropping table if exists. +#export QDB_DROP_TABLE_IF_EXISTS="" + +# If not already set, disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/src/tests/ecoc22/descriptors_emulated.json b/src/tests/ecoc22/descriptors_emulated.json index 46e518b246f76472e978bbe5841b9ca53c7aaa46..f55954d92fbe3cf75b3464286f897c3f931c0c39 100644 --- a/src/tests/ecoc22/descriptors_emulated.json +++ b/src/tests/ecoc22/descriptors_emulated.json @@ -1,15 +1,9 @@ { "contexts": [ - { - "context_id": {"context_uuid": {"uuid": "admin"}}, - "topology_ids": [], "service_ids": [] - } + {"context_id": {"context_uuid": {"uuid": "admin"}}} ], "topologies": [ - { - "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}, - "device_ids": [], "link_ids": [] - } + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} ], "devices": [ { @@ -17,7 +11,11 @@ "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\": \"eth1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"int\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "eth1"}, + {"sample_types": [], "type": "copper", "uuid": "eth2"}, + {"sample_types": [], "type": "copper", "uuid": "int"} + ]}}} ]} }, { @@ -25,39 +23,55 @@ "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\": \"eth1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"int\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "eth1"}, + {"sample_types": [], "type": "copper", "uuid": "eth2"}, + {"sample_types": [], "type": "copper", "uuid": "int"} + ]}}} ]} }, { - "device_id": {"device_uuid": {"uuid": "CS1-GW1"}}, "device_type": "packet-router", "device_drivers": [1], + "device_id": {"device_uuid": {"uuid": "CS1-GW1"}}, "device_type": "emu-packet-router", "device_drivers": [1], "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\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "10/1"}, + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "1/1"} + ]}}} ]} }, { - "device_id": {"device_uuid": {"uuid": "CS1-GW2"}}, "device_type": "packet-router", "device_drivers": [1], + "device_id": {"device_uuid": {"uuid": "CS1-GW2"}}, "device_type": "emu-packet-router", "device_drivers": [1], "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\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "10/1"}, + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "1/1"} + ]}}} ]} }, { - "device_id": {"device_uuid": {"uuid": "CS2-GW1"}}, "device_type": "packet-router", "device_drivers": [1], + "device_id": {"device_uuid": {"uuid": "CS2-GW1"}}, "device_type": "emu-packet-router", "device_drivers": [1], "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\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "10/1"}, + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "1/1"} + ]}}} ]} }, { - "device_id": {"device_uuid": {"uuid": "CS2-GW2"}}, "device_type": "packet-router", "device_drivers": [1], + "device_id": {"device_uuid": {"uuid": "CS2-GW2"}}, "device_type": "emu-packet-router", "device_drivers": [1], "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\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "10/1"}, + {"sample_types": [101, 102, 201, 202], "type": "copper", "uuid": "1/1"} + ]}}} ]} }, { @@ -65,7 +79,12 @@ "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\": \"optical\", \"uuid\": \"aade6001-f00b-5e2f-a357-6a0a9d3de870\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"eb287d83-f05e-53ec-ab5a-adf6bd2b5418\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"0ef74f99-1acc-57bd-ab9d-4b958b06c513\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"50296d99-58cc-5ce7-82f5-fc8ee4eec2ec\"}]}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "optical", "uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}, + {"sample_types": [], "type": "optical", "uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}, + {"sample_types": [], "type": "optical", "uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}, + {"sample_types": [], "type": "optical", "uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"} + ]}}} ]} } ], diff --git a/src/tests/ecoc22/redeploy.sh b/src/tests/ecoc22/redeploy.sh index 3f3986debb9aec57e7bc7f67b549b960679a987f..740546128e31b46ea1c03a17a42a372cc331da87 100755 --- a/src/tests/ecoc22/redeploy.sh +++ b/src/tests/ecoc22/redeploy.sh @@ -1,4 +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. + source ecoc22/deploy_specs.sh -./deploy.sh +./deploy/all.sh source tfs_runtime_env_vars.sh diff --git a/src/tests/ecoc22/run_test_01_bootstrap.sh b/src/tests/ecoc22/run_test_01_bootstrap.sh index 819991d78a499c6d6e4a10e96f6439ee5b56ed8d..1d20cb98b9056153b08cfba4eaa153ad34579241 100755 --- a/src/tests/ecoc22/run_test_01_bootstrap.sh +++ b/src/tests/ecoc22/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose src/tests/ecoc22/tests/test_functional_bootstrap.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_bootstrap.py diff --git a/src/tests/ecoc22/run_test_02_create_service.sh b/src/tests/ecoc22/run_test_02_create_service.sh index 5a54d39d496e203ee669efda636067dcc1aa27a9..bc8a53fea1d710f2f34f3ecd9a1c32c709957beb 100755 --- a/src/tests/ecoc22/run_test_02_create_service.sh +++ b/src/tests/ecoc22/run_test_02_create_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose src/tests/ecoc22/tests/test_functional_create_service.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_create_service.py diff --git a/src/tests/ecoc22/run_test_03_delete_service.sh b/src/tests/ecoc22/run_test_03_delete_service.sh index 900e09b658c1a73664dd28dc60ef6a50a9e68570..4c30511d96c83fde63a01b1c50b6ecd182db06c6 100755 --- a/src/tests/ecoc22/run_test_03_delete_service.sh +++ b/src/tests/ecoc22/run_test_03_delete_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose src/tests/ecoc22/tests/test_functional_delete_service.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_delete_service.py diff --git a/src/tests/ecoc22/run_test_04_cleanup.sh b/src/tests/ecoc22/run_test_04_cleanup.sh index 4e0622e6b22d470d842d99bb4202e23e88b72982..fc8c13f61dd799515b0f0e4c1a8933adac20774d 100755 --- a/src/tests/ecoc22/run_test_04_cleanup.sh +++ b/src/tests/ecoc22/run_test_04_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose src/tests/ecoc22/tests/test_functional_cleanup.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_cleanup.py diff --git a/src/tests/ecoc22/run_tests.sh b/src/tests/ecoc22/run_tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..a97ed9eca7b59ba634d526785bd0aae476469021 --- /dev/null +++ b/src/tests/ecoc22/run_tests.sh @@ -0,0 +1,21 @@ +#!/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. + +# Run functional tests +source tfs_runtime_env_vars.sh +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_bootstrap.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_create_service.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_delete_service.py +pytest --verbose --log-level=INFO src/tests/ecoc22/tests/test_functional_cleanup.py diff --git a/src/tests/ecoc22/run_tests_and_coverage.sh b/src/tests/ecoc22/run_tests_and_coverage.sh deleted file mode 100755 index 4517cc1ea7eec7027219517720c99bfea3b4250b..0000000000000000000000000000000000000000 --- a/src/tests/ecoc22/run_tests_and_coverage.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -PROJECTDIR=`pwd` - -RCFILE=$PROJECTDIR/coverage/.coveragerc -COVERAGEFILE=$PROJECTDIR/coverage/.coverage - -# Configure the correct folder on the .coveragerc file -cat $PROJECTDIR/coverage/.coveragerc.template | sed s+~/teraflow/controller+$PROJECTDIR+g > $RCFILE - -# Destroy old coverage file -rm -f $COVERAGEFILE - -source tfs_runtime_env_vars.sh - -# Force a flush of Context database -kubectl --namespace $TFS_K8S_NAMESPACE exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL - -# Run functional tests and analyze code coverage at the same time -coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ - src/tests/ecoc22/tests/test_functional_bootstrap.py - -coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ - src/tests/ecoc22/tests/test_functional_create_service.py - -coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ - src/tests/ecoc22/tests/test_functional_delete_service.py - -coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ - src/tests/ecoc22/tests/test_functional_cleanup.py diff --git a/src/tests/ecoc22/tests/.gitignore b/src/tests/ecoc22/tests/.gitignore index 6b97d6fe3ad32f39097745229ab7f547f26ecb12..76cb708d1b532c9b69166e55f36bcb912fd5e370 100644 --- a/src/tests/ecoc22/tests/.gitignore +++ b/src/tests/ecoc22/tests/.gitignore @@ -1 +1,2 @@ # Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc. +Credentials.py diff --git a/src/tests/ecoc22/tests/Fixtures.py b/src/tests/ecoc22/tests/Fixtures.py index 0e5c7fbe3107ea55ba8243be18e9b100571d1c4b..89dda54cf945d7078cd61c4b94b282f650429309 100644 --- a/src/tests/ecoc22/tests/Fixtures.py +++ b/src/tests/ecoc22/tests/Fixtures.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,15 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest +import pytest, logging from common.Settings import get_setting -from compute.tests.mock_osm.MockOSM import MockOSM -#from .Objects_BigNet import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME -from .Objects_DC_CSGW_TN import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME -#from .Objects_DC_CSGW_TN_OLS import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME +from tests.tools.mock_osm.Constants import WIM_PASSWORD, WIM_USERNAME +from tests.tools.mock_osm.MockOSM import MockOSM +from .Objects import WIM_MAPPING + +LOGGER = logging.getLogger(__name__) @pytest.fixture(scope='session') def osm_wim(): wim_url = 'http://{:s}:{:s}'.format( get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP'))) + LOGGER.info('WIM_MAPPING = {:s}'.format(str(WIM_MAPPING))) return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD) diff --git a/src/tests/ecoc22/tests/Objects.py b/src/tests/ecoc22/tests/Objects.py new file mode 100644 index 0000000000000000000000000000000000000000..4fbd5508e7819d9272c47f8e7f81f74c56925de6 --- /dev/null +++ b/src/tests/ecoc22/tests/Objects.py @@ -0,0 +1,51 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.tools.object_factory.Device import json_device_id +from common.tools.object_factory.EndPoint import json_endpoint_id +from tests.tools.mock_osm.Tools import connection_point, wim_mapping + +# ----- WIM Service Settings ------------------------------------------------------------------------------------------- +# PRI = primary // BKP = backup + +SITE_ID_DC1 = 'DC1' +DEV_ID_DC1 = json_device_id('DC1-GW') +EP_ID_DC1_PRI = json_endpoint_id(DEV_ID_DC1, 'eth1') +EP_ID_DC1_BKP = json_endpoint_id(DEV_ID_DC1, 'eth2') +DEV_ID_CS1GW1 = json_device_id('CS1-GW1') +DEV_ID_CS1GW2 = json_device_id('CS1-GW2') + +SITE_ID_DC2 = 'DC2' +DEV_ID_DC2 = json_device_id('DC2-GW') +EP_ID_DC2_PRI = json_endpoint_id(DEV_ID_DC2, 'eth1') +EP_ID_DC2_BKP = json_endpoint_id(DEV_ID_DC2, 'eth2') +DEV_ID_CS2GW1 = json_device_id('CS2-GW1') +DEV_ID_CS2GW2 = json_device_id('CS2-GW2') + +WIM_SEP_DC1_PRI, WIM_MAP_DC1_PRI = wim_mapping(SITE_ID_DC1, EP_ID_DC1_PRI, DEV_ID_CS1GW1, priority=10, redundant=['DC1:DC1-GW:eth2']) +WIM_SEP_DC1_BKP, WIM_MAP_DC1_BKP = wim_mapping(SITE_ID_DC1, EP_ID_DC1_BKP, DEV_ID_CS1GW2, priority=20, redundant=['DC1:DC1-GW:eth1']) +WIM_SEP_DC2_PRI, WIM_MAP_DC2_PRI = wim_mapping(SITE_ID_DC2, EP_ID_DC2_PRI, DEV_ID_CS2GW1, priority=10, redundant=['DC2:DC2-GW:eth2']) +WIM_SEP_DC2_BKP, WIM_MAP_DC2_BKP = wim_mapping(SITE_ID_DC2, EP_ID_DC2_BKP, DEV_ID_CS2GW2, priority=20, redundant=['DC2:DC2-GW:eth1']) + +WIM_MAPPING = [ + WIM_MAP_DC1_PRI, WIM_MAP_DC1_BKP, + WIM_MAP_DC2_PRI, WIM_MAP_DC2_BKP, +] + +WIM_SRV_VLAN_ID = 300 +WIM_SERVICE_TYPE = 'ELAN' +WIM_SERVICE_CONNECTION_POINTS = [ + connection_point(WIM_SEP_DC1_PRI, 'dot1q', WIM_SRV_VLAN_ID), + connection_point(WIM_SEP_DC2_PRI, 'dot1q', WIM_SRV_VLAN_ID), +] diff --git a/src/tests/ecoc22/tests/Tools.py b/src/tests/ecoc22/tests/Tools.py index 33205da9baeb6c9fe93a389e9744053aea664b16..26a3eda7101907f63fc51bc042bd59dee463d7d9 100644 --- a/src/tests/ecoc22/tests/Tools.py +++ b/src/tests/ecoc22/tests/Tools.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from typing import Dict, List, Tuple from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id from common.tools.object_factory.Link import json_link, json_link_id diff --git a/src/tests/ecoc22/tests/__init__.py b/src/tests/ecoc22/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/ecoc22/tests/__init__.py +++ b/src/tests/ecoc22/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ecoc22/tests/BuildDescriptors.py b/src/tests/ecoc22/tests/old_code/BuildDescriptors.py similarity index 97% rename from src/tests/ecoc22/tests/BuildDescriptors.py rename to src/tests/ecoc22/tests/old_code/BuildDescriptors.py index b0075c0639c70092ed60bafd06c9f62b581faa33..b6a26a4a0843d4859799c073e34b33505548d7c7 100644 --- a/src/tests/ecoc22/tests/BuildDescriptors.py +++ b/src/tests/ecoc22/tests/old_code/BuildDescriptors.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ecoc22/tests/LoadDescriptors.py b/src/tests/ecoc22/tests/old_code/LoadDescriptors.py similarity index 95% rename from src/tests/ecoc22/tests/LoadDescriptors.py rename to src/tests/ecoc22/tests/old_code/LoadDescriptors.py index bd7e48366795d47624f1b8e295cbe6fa105bf8c7..5041d854eba9eaf733b163f922716fe9891da5ae 100644 --- a/src/tests/ecoc22/tests/LoadDescriptors.py +++ b/src/tests/ecoc22/tests/old_code/LoadDescriptors.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ecoc22/tests/Objects_BigNet.py b/src/tests/ecoc22/tests/old_code/Objects_BigNet.py similarity index 97% rename from src/tests/ecoc22/tests/Objects_BigNet.py rename to src/tests/ecoc22/tests/old_code/Objects_BigNet.py index 592376ff9dbaebbf4d8d02b04189e5d4f24584e3..fb96914678e646840400e5270892b82428c428ee 100644 --- a/src/tests/ecoc22/tests/Objects_BigNet.py +++ b/src/tests/ecoc22/tests/old_code/Objects_BigNet.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_datacenter_disabled, @@ -21,13 +21,13 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from .Tools import compose_bearer, compose_service_endpoint_id, json_endpoint_ids, link # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- Customer Equipment (CE) Devices -------------------------------------------------------------------------------- diff --git a/src/tests/ecoc22/tests/Objects_DC_CSGW_OLS.py b/src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_OLS.py similarity index 97% rename from src/tests/ecoc22/tests/Objects_DC_CSGW_OLS.py rename to src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_OLS.py index 94d205a64681c7b1978524c1938cbc6b944afb58..522c25d6b272247093edb72cdbfa0ba515ed8cf8 100644 --- a/src/tests/ecoc22/tests/Objects_DC_CSGW_OLS.py +++ b/src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_OLS.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import os, uuid -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_datacenter_disabled, @@ -68,12 +68,12 @@ def compose_service(endpoint_a, endpoint_z, constraints=[]): return service # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Domains -------------------------------------------------------------------------------------------------------- # Overall network topology -TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_NAME TOPO_ADMIN_ID = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) TOPO_ADMIN = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) diff --git a/src/tests/ecoc22/tests/Objects_DC_CSGW_TN.py b/src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_TN.py similarity index 97% rename from src/tests/ecoc22/tests/Objects_DC_CSGW_TN.py rename to src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_TN.py index 229e3d5fe3cee54fb7295ac0049507ec4e348a04..c02f5d0c880f4bf570b7d14278c4bcbb1cffe72d 100644 --- a/src/tests/ecoc22/tests/Objects_DC_CSGW_TN.py +++ b/src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_TN.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import os -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_datacenter_disabled, @@ -59,12 +59,12 @@ def compose_service(endpoint_a, endpoint_z, constraints=[]): return service # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Domains -------------------------------------------------------------------------------------------------------- # Overall network topology -TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_NAME TOPO_ADMIN_ID = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) TOPO_ADMIN = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) diff --git a/src/tests/ecoc22/tests/Objects_DC_CSGW_TN_OLS.py b/src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_TN_OLS.py similarity index 97% rename from src/tests/ecoc22/tests/Objects_DC_CSGW_TN_OLS.py rename to src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_TN_OLS.py index 7063265f47344555d5b99c9c9747029227a494e0..6c34ec01d4c9b466aa81d306078a0ab242a334ad 100644 --- a/src/tests/ecoc22/tests/Objects_DC_CSGW_TN_OLS.py +++ b/src/tests/ecoc22/tests/old_code/Objects_DC_CSGW_TN_OLS.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. import os, uuid -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_datacenter_disabled, @@ -68,12 +68,12 @@ def compose_service(endpoint_a, endpoint_z, constraints=[]): return service # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Domains -------------------------------------------------------------------------------------------------------- # Overall network topology -TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_NAME TOPO_ADMIN_ID = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) TOPO_ADMIN = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) diff --git a/src/tests/ecoc22/tests/test_functional_bootstrap.py b/src/tests/ecoc22/tests/test_functional_bootstrap.py index 75f2bddf2c3bb21084efb6be3f5957df122da429..3b7b5009c0dbe9d95b4ee8e2cdbe33d39008a7a1 100644 --- a/src/tests/ecoc22/tests/test_functional_bootstrap.py +++ b/src/tests/ecoc22/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,21 +13,24 @@ # limitations under the License. import logging -from common.proto.context_pb2 import Context, ContextId, Device, DeviceId, Empty, Link, LinkId, Topology, TopologyId +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, Empty +from common.tests.LoadScenario import load_scenario_from_descriptor +from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient -from tests.Fixtures import context_client, device_client -#from .Objects_BigNet import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES -#from .Objects_DC_CSGW_TN import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, OBJECTS_PER_TOPOLOGY -#from .Objects_DC_CSGW_TN_OLS import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, OBJECTS_PER_TOPOLOGY -from .Objects_DC_CSGW_OLS import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, OBJECTS_PER_TOPOLOGY - +from tests.Fixtures import context_client, device_client # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) +DESCRIPTOR_FILE = 'ecoc22/descriptors_emulated.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) -def test_scenario_empty(context_client : ContextClient): # pylint: disable=redefined-outer-name +def test_scenario_bootstrap( + context_client : ContextClient, # pylint: disable=redefined-outer-name + device_client : DeviceClient, # pylint: disable=redefined-outer-name +) -> None: # ----- List entities - Ensure database is empty ------------------------------------------------------------------- response = context_client.ListContexts(Empty()) assert len(response.contexts) == 0 @@ -39,53 +42,34 @@ def test_scenario_empty(context_client : ContextClient): # pylint: disable=rede assert len(response.links) == 0 -def test_prepare_environment( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient): # 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 : device_client .AddDevice (Device (**device )) - for topology_id, device_ids, _ in OBJECTS_PER_TOPOLOGY: - topology = Topology() - topology.CopyFrom(context_client.GetTopology(TopologyId(**topology_id))) - - 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) + # ----- Load Scenario ---------------------------------------------------------------------------------------------- + descriptor_loader = load_scenario_from_descriptor( + DESCRIPTOR_FILE, context_client, device_client, None, None) - context_client.SetTopology(topology) - for link in LINKS : context_client.SetLink (Link (**link )) - for topology_id, _, link_ids in OBJECTS_PER_TOPOLOGY: - topology = Topology() - topology.CopyFrom(context_client.GetTopology(TopologyId(**topology_id))) - - 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) - - context_client.SetTopology(topology) - - -def test_scenario_ready(context_client : ContextClient): # pylint: disable=redefined-outer-name # ----- List entities - Ensure scenario is ready ------------------------------------------------------------------- response = context_client.ListContexts(Empty()) - assert len(response.contexts) == len(CONTEXTS) + assert len(response.contexts) == descriptor_loader.num_contexts - response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) - assert len(response.topologies) == len(TOPOLOGIES) + for context_uuid, num_topologies in descriptor_loader.num_topologies.items(): + response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid))) + assert len(response.topologies) == num_topologies response = context_client.ListDevices(Empty()) - assert len(response.devices) == len(DEVICES) + assert len(response.devices) == descriptor_loader.num_devices response = context_client.ListLinks(Empty()) - assert len(response.links) == len(LINKS) + assert len(response.links) == descriptor_loader.num_links + + for context_uuid, _ in descriptor_loader.num_services.items(): + response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) + assert len(response.services) == 0 + + for context_uuid, _ in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == 0 - response = context_client.ListServices(ContextId(**CONTEXT_ID)) - assert len(response.services) == 0 + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 diff --git a/src/tests/ecoc22/tests/test_functional_cleanup.py b/src/tests/ecoc22/tests/test_functional_cleanup.py index 017cc991dd5bb49f6f02f178fc4354653b7bea43..3e8b5ea65fe8249102ba17b9d4ce3f2cf2296dda 100644 --- a/src/tests/ecoc22/tests/test_functional_cleanup.py +++ b/src/tests/ecoc22/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,49 +13,72 @@ # limitations under the License. import logging +from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId +from common.tools.descriptor.Loader import DescriptorLoader from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient -from tests.Fixtures import context_client, device_client -#from .Objects_BigNet import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES -#from .Objects_DC_CSGW_TN import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES -#from .Objects_DC_CSGW_TN_OLS import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES -from .Objects_DC_CSGW_OLS import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES - +from tests.Fixtures import context_client, device_client # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) +DESCRIPTOR_FILE = 'ecoc22/descriptors_emulated.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) -def test_services_removed(context_client : ContextClient): # pylint: disable=redefined-outer-name +def test_services_removed( + context_client : ContextClient, # pylint: disable=redefined-outer-name + device_client : DeviceClient, # pylint: disable=redefined-outer-name +) -> None: # ----- List entities - Ensure service is removed ------------------------------------------------------------------ + with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f: + descriptors = f.read() + + descriptor_loader = DescriptorLoader(descriptors) + response = context_client.ListContexts(Empty()) - assert len(response.contexts) == len(CONTEXTS) + assert len(response.contexts) == descriptor_loader.num_contexts - response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) - assert len(response.topologies) == len(TOPOLOGIES) + for context_uuid, num_topologies in descriptor_loader.num_topologies.items(): + response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid))) + assert len(response.topologies) == num_topologies response = context_client.ListDevices(Empty()) - assert len(response.devices) == len(DEVICES) + assert len(response.devices) == descriptor_loader.num_devices response = context_client.ListLinks(Empty()) - assert len(response.links) == len(LINKS) + assert len(response.links) == descriptor_loader.num_links + + for context_uuid, _ in descriptor_loader.num_services.items(): + response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) + assert len(response.services) == 0 + + for context_uuid, _ in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == 0 + + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 + - response = context_client.ListServices(ContextId(**CONTEXT_ID)) - assert len(response.services) == 0 + # ----- Delete Links, Devices, Topologies, Contexts ---------------------------------------------------------------- + for link in descriptor_loader.links: + context_client.RemoveLink(LinkId(**link['link_id'])) + for device in descriptor_loader.devices: + device_client .DeleteDevice(DeviceId(**device['device_id'])) -def test_scenario_cleanup( - context_client : ContextClient, device_client : DeviceClient): # pylint: disable=redefined-outer-name + for context_uuid, topology_list in descriptor_loader.topologies.items(): + for topology in topology_list: + context_client.RemoveTopology(TopologyId(**topology['topology_id'])) - for link in LINKS : context_client.RemoveLink (LinkId (**link ['link_id' ])) - for device in DEVICES : device_client .DeleteDevice (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' ])) + for context in descriptor_loader.contexts: + context_client.RemoveContext(ContextId(**context['context_id'])) -def test_scenario_empty_again(context_client : ContextClient): # pylint: disable=redefined-outer-name # ----- List entities - Ensure database is empty again ------------------------------------------------------------- response = context_client.ListContexts(Empty()) assert len(response.contexts) == 0 diff --git a/src/tests/ecoc22/tests/test_functional_create_service.py b/src/tests/ecoc22/tests/test_functional_create_service.py index 8c9ca36a96d161f10ed69c1a86794abf78555571..6dd4eb827c0fbafdf0bce81c7702af5fd5fe007b 100644 --- a/src/tests/ecoc22/tests/test_functional_create_service.py +++ b/src/tests/ecoc22/tests/test_functional_create_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,73 +13,90 @@ # limitations under the License. import logging +from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum +from common.tools.descriptor.Loader import DescriptorLoader from common.tools.grpc.Tools import grpc_message_to_json_string -from compute.tests.mock_osm.MockOSM import MockOSM +from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient -from tests.Fixtures import context_client -from .Fixtures import osm_wim -#from .Objects_BigNet import ( -# CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) -#from .Objects_DC_CSGW_TN import ( -# CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) -#from .Objects_DC_CSGW_TN_OLS import ( -# CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) -from .Objects_DC_CSGW_OLS import ( - CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) - +from tests.Fixtures import context_client # pylint: disable=unused-import +from tests.tools.mock_osm.MockOSM import MockOSM +from .Fixtures import osm_wim # pylint: disable=unused-import +from .Objects import WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) +DESCRIPTOR_FILE = 'ecoc22/descriptors_emulated.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) + +def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name + # ----- List entities - Ensure scenario is ready ------------------------------------------------------------------- + with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f: + descriptors = f.read() + + descriptor_loader = DescriptorLoader(descriptors) -def test_scenario_is_correct(context_client : ContextClient): # pylint: disable=redefined-outer-name - # ----- List entities - Ensure links are created ------------------------------------------------------------------- response = context_client.ListContexts(Empty()) - assert len(response.contexts) == len(CONTEXTS) + assert len(response.contexts) == descriptor_loader.num_contexts - response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) - assert len(response.topologies) == len(TOPOLOGIES) + for context_uuid, num_topologies in descriptor_loader.num_topologies.items(): + response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid))) + assert len(response.topologies) == num_topologies response = context_client.ListDevices(Empty()) - assert len(response.devices) == len(DEVICES) + assert len(response.devices) == descriptor_loader.num_devices response = context_client.ListLinks(Empty()) - assert len(response.links) == len(LINKS) + assert len(response.links) == descriptor_loader.num_links - response = context_client.ListServices(ContextId(**CONTEXT_ID)) - assert len(response.services) == 0 + for context_uuid, num_services in descriptor_loader.num_services.items(): + response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) + assert len(response.services) == num_services + + for context_uuid, num_slices in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == num_slices + + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 -def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name # ----- Create Service --------------------------------------------------------------------------------------------- service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS) osm_wim.get_connectivity_service_status(service_uuid) -def test_scenario_service_created(context_client : ContextClient): # pylint: disable=redefined-outer-name # ----- List entities - Ensure service is created ------------------------------------------------------------------ response = context_client.ListContexts(Empty()) - assert len(response.contexts) == len(CONTEXTS) + assert len(response.contexts) == descriptor_loader.num_contexts - response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) - assert len(response.topologies) == len(TOPOLOGIES) + for context_uuid, num_topologies in descriptor_loader.num_topologies.items(): + response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid))) + assert len(response.topologies) == num_topologies response = context_client.ListDevices(Empty()) - assert len(response.devices) == len(DEVICES) + assert len(response.devices) == descriptor_loader.num_devices response = context_client.ListLinks(Empty()) - assert len(response.links) == len(LINKS) + assert len(response.links) == descriptor_loader.num_links - response = context_client.ListServices(ContextId(**CONTEXT_ID)) + 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) == 3 # 1xL2NM + 2xTAPI + for service in response.services: 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))) + if service.service_type == ServiceTypeEnum.SERVICETYPE_L2NM: assert len(response.connections) == 2 # 2 connections per service (primary + backup) elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: assert len(response.connections) == 1 # 1 connection per service + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) diff --git a/src/tests/ecoc22/tests/test_functional_delete_service.py b/src/tests/ecoc22/tests/test_functional_delete_service.py index de152ebb71111c9201dfde18262586b242b04083..5cfdc34733d8ddc6927b52131a187fb097b36d9d 100644 --- a/src/tests/ecoc22/tests/test_functional_delete_service.py +++ b/src/tests/ecoc22/tests/test_functional_delete_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,92 +12,100 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, pytest -from common.DeviceTypes import DeviceTypeEnum -from common.Settings import get_setting +import logging +from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum -from common.tests.EventTools import EVENT_REMOVE, EVENT_UPDATE, check_events -from common.tools.object_factory.Connection import json_connection_id -from common.tools.object_factory.Device import json_device_id -from common.tools.object_factory.Service import json_service_id +from common.tools.descriptor.Loader import DescriptorLoader +from common.tools.object_factory.Context import json_context_id from common.tools.grpc.Tools import grpc_message_to_json_string -from compute.tests.mock_osm.MockOSM import MockOSM from context.client.ContextClient import ContextClient -from tests.Fixtures import context_client -from .Fixtures import osm_wim -#from .Objects_BigNet import ( -# CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) -#from .Objects_DC_CSGW_TN import ( -# CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) -#from .Objects_DC_CSGW_TN_OLS import ( -# CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) -from .Objects_DC_CSGW_OLS import ( - CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE) +from tests.Fixtures import context_client # pylint: disable=unused-import +from tests.tools.mock_osm.MockOSM import MockOSM +from .Fixtures import osm_wim # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -DEVTYPE_EMU_PR = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value -DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value +DESCRIPTOR_FILE = 'ecoc22/descriptors_emulated.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) -def test_scenario_is_correct(context_client : ContextClient): # pylint: disable=redefined-outer-name +def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name # ----- List entities - Ensure service is created ------------------------------------------------------------------ + with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f: + descriptors = f.read() + + descriptor_loader = DescriptorLoader(descriptors) + response = context_client.ListContexts(Empty()) - assert len(response.contexts) == len(CONTEXTS) + assert len(response.contexts) == descriptor_loader.num_contexts - response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) - assert len(response.topologies) == len(TOPOLOGIES) + for context_uuid, num_topologies in descriptor_loader.num_topologies.items(): + response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid))) + assert len(response.topologies) == num_topologies response = context_client.ListDevices(Empty()) - assert len(response.devices) == len(DEVICES) + assert len(response.devices) == descriptor_loader.num_devices response = context_client.ListLinks(Empty()) - assert len(response.links) == len(LINKS) + assert len(response.links) == descriptor_loader.num_links - response = context_client.ListServices(ContextId(**CONTEXT_ID)) + service_uuids = set() + 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) == 3 # 1xL2NM + 2xTAPI + for service in response.services: service_id = service.service_id + + if service.service_type == ServiceTypeEnum.SERVICETYPE_L2NM: + service_uuid = service_id.service_uuid.uuid + service_uuids.add(service_uuid) + osm_wim.conn_info[service_uuid] = {} + 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))) + if service.service_type == ServiceTypeEnum.SERVICETYPE_L2NM: assert len(response.connections) == 2 # 2 connections per service (primary + backup) elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: assert len(response.connections) == 1 # 1 connection per service + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) - -def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name - # ----- Delete Service --------------------------------------------------------------------------------------------- - response = context_client.ListServices(ContextId(**CONTEXT_ID)) - LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) - service_uuids = set() - for service in response.services: - if service.service_type != ServiceTypeEnum.SERVICETYPE_L2NM: continue - service_uuid = service.service_id.service_uuid.uuid - service_uuids.add(service_uuid) - osm_wim.conn_info[service_uuid] = {} - - assert len(service_uuids) == 1 # assume a single service has been created + # Identify service to delete + assert len(service_uuids) == 1 # assume a single L2NM service has been created service_uuid = set(service_uuids).pop() + + # ----- Delete Service --------------------------------------------------------------------------------------------- osm_wim.delete_connectivity_service(service_uuid) -def test_services_removed(context_client : ContextClient): # pylint: disable=redefined-outer-name # ----- List entities - Ensure service is removed ------------------------------------------------------------------ response = context_client.ListContexts(Empty()) - assert len(response.contexts) == len(CONTEXTS) + assert len(response.contexts) == descriptor_loader.num_contexts - response = context_client.ListTopologies(ContextId(**CONTEXT_ID)) - assert len(response.topologies) == len(TOPOLOGIES) + for context_uuid, num_topologies in descriptor_loader.num_topologies.items(): + response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid))) + assert len(response.topologies) == num_topologies response = context_client.ListDevices(Empty()) - assert len(response.devices) == len(DEVICES) + assert len(response.devices) == descriptor_loader.num_devices response = context_client.ListLinks(Empty()) - assert len(response.links) == len(LINKS) + assert len(response.links) == descriptor_loader.num_links + + for context_uuid, num_services in descriptor_loader.num_services.items(): + response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) + assert len(response.services) == num_services + + for context_uuid, num_slices in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == num_slices - response = context_client.ListServices(ContextId(**CONTEXT_ID)) - assert len(response.services) == 0 + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 diff --git a/tutorial/2-3-oeccpsc22.md b/src/tests/oeccpsc22/README.md similarity index 53% rename from tutorial/2-3-oeccpsc22.md rename to src/tests/oeccpsc22/README.md index 2ea7261d8a032b6543b3f3e9ed2fa702d9066616..42e0228a52bdf9dfc21bc0358b78fb98677ed458 100644 --- a/tutorial/2-3-oeccpsc22.md +++ b/src/tests/oeccpsc22/README.md @@ -1,8 +1,8 @@ -# 2.3. OECC/PSC'22 Demo - Interdomain slices (WORK IN PROGRESS) - -This functional test reproduces the experiment in paper "... paper title ..." presented at OECC/PSC'22 conference -[OECC/PSC'22](... demo link ...). - -## 2.3.1. Functional test folder -This functional test can be found in folder `./src/tests/oeccpsc22/`. A convenience alias `./oeccpsc22/` pointing to -that folder has been defined. +# OECC/PSC'22 Paper - Interdomain slices +This functional test reproduces the experiment in paper "... paper title ..." presented at OECC/PSC'22 conference +[OECC/PSC'22](... demo link ...). + +## Functional test folder +This functional test can be found in folder `./src/tests/oeccpsc22/`. A convenience alias `./oeccpsc22/` pointing to that folder has been defined. + +# TO BE WRITTEN diff --git a/src/tests/oeccpsc22/__init__.py b/src/tests/oeccpsc22/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/oeccpsc22/__init__.py +++ b/src/tests/oeccpsc22/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/deploy_in_kubernetes.sh b/src/tests/oeccpsc22/deploy_in_kubernetes.sh index 426e07e1376207065b02db3205e46dd2cbe9a39d..53b6e76a8bb32310945b29c57946435d98a0b8d3 100755 --- a/src/tests/oeccpsc22/deploy_in_kubernetes.sh +++ b/src/tests/oeccpsc22/deploy_in_kubernetes.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -22,7 +22,7 @@ export K8S_HOSTNAME="kubernetes-master" #export GRAFANA_PASSWORD="admin123+" # Constants -GITLAB_REPO_URL="registry.gitlab.com/teraflow-h2020/controller" +GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller" TMP_FOLDER="./tmp" # Create a tmp folder for files modified during the deployment diff --git a/src/tests/oeccpsc22/dump_logs.sh b/src/tests/oeccpsc22/dump_logs.sh index 196002a5fd6b9b208046ba1e22f156f628f60f1d..a2180f6dff3f35cc7d0e9e2011179a6d8b933ea1 100755 --- a/src/tests/oeccpsc22/dump_logs.sh +++ b/src/tests/oeccpsc22/dump_logs.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/expose_services_teraflow_1.yaml b/src/tests/oeccpsc22/expose_services_teraflow_1.yaml index f2b8de0b1629082eab1a5e638c0e712db47ed0bd..d956db1a781147467efd1c4724e0734b579d8f5d 100644 --- a/src/tests/oeccpsc22/expose_services_teraflow_1.yaml +++ b/src/tests/oeccpsc22/expose_services_teraflow_1.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/expose_services_teraflow_2.yaml b/src/tests/oeccpsc22/expose_services_teraflow_2.yaml index 8254c00aa09c9e15a047fd60b6140c68ef1f0e52..d8acb96533f8886afc0fd5c802d3616277676e33 100644 --- a/src/tests/oeccpsc22/expose_services_teraflow_2.yaml +++ b/src/tests/oeccpsc22/expose_services_teraflow_2.yaml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/run_test_01_bootstrap.sh b/src/tests/oeccpsc22/run_test_01_bootstrap.sh index e8df6ffb67f6756f9f757ae12c6a438d0c609853..23a569d4de537c8a0279930ba83186b59770050e 100755 --- a/src/tests/oeccpsc22/run_test_01_bootstrap.sh +++ b/src/tests/oeccpsc22/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh b/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh index b9ab66cb343b31f34b394b00ff7fcabdac22e8d3..e438a2915f4924a41b765f2f449e3704727653b7 100755 --- a/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh +++ b/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh b/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh index b0080ce3759badc047bf218ab9a13c1bea722115..6816ac815fc65f5863608f7303c3d356d12fb52c 100755 --- a/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh +++ b/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/run_test_04_cleanup.sh b/src/tests/oeccpsc22/run_test_04_cleanup.sh index d0420820c487862e5faa469dc4000dda3da71be6..763c5b67eb00f2c4220b286c37c566b96bf3e386 100755 --- a/src/tests/oeccpsc22/run_test_04_cleanup.sh +++ b/src/tests/oeccpsc22/run_test_04_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/show_deploy.sh b/src/tests/oeccpsc22/show_deploy.sh index 90d6914890cfd37db37ed3b3ea8266372c067c20..d5e9346e51cb5bf6ffa442c0b3f9356176efff5c 100755 --- a/src/tests/oeccpsc22/show_deploy.sh +++ b/src/tests/oeccpsc22/show_deploy.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/tests/Objects_Domain_1.py b/src/tests/oeccpsc22/tests/Objects_Domain_1.py index 8b26348c94b827e4e418a458f21b28a863c4cb68..2f35aa76eea8f7adfc89011cbc4822daecbd1d14 100644 --- a/src/tests/oeccpsc22/tests/Objects_Domain_1.py +++ b/src/tests/oeccpsc22/tests/Objects_Domain_1.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, json_device_id) @@ -21,12 +21,12 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from .Tools import get_link_uuid, json_endpoint_ids # ----- Context -------------------------------------------------------------------------------------------------------- -D1_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -D1_CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +D1_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +D1_CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -D1_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=D1_CONTEXT_ID) -D1_TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=D1_CONTEXT_ID) +D1_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=D1_CONTEXT_ID) +D1_TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=D1_CONTEXT_ID) # ----- Devices -------------------------------------------------------------------------------------------------------- # Assume all devices have the same architecture of endpoints diff --git a/src/tests/oeccpsc22/tests/Objects_Domain_2.py b/src/tests/oeccpsc22/tests/Objects_Domain_2.py index f9133809243effc0a7d22c953046a4af4d6bad3e..0e5065c3b6ec3e1d44a16f0ee8231aca28e2c2d1 100644 --- a/src/tests/oeccpsc22/tests/Objects_Domain_2.py +++ b/src/tests/oeccpsc22/tests/Objects_Domain_2.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, json_device_id) @@ -21,12 +21,12 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from .Tools import get_link_uuid, json_endpoint_ids # ----- Context -------------------------------------------------------------------------------------------------------- -D2_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -D2_CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +D2_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +D2_CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -D2_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=D2_CONTEXT_ID) -D2_TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=D2_CONTEXT_ID) +D2_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=D2_CONTEXT_ID) +D2_TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=D2_CONTEXT_ID) # ----- Devices -------------------------------------------------------------------------------------------------------- # Assume all devices have the same architecture of endpoints diff --git a/src/tests/oeccpsc22/tests/Objects_Service.py b/src/tests/oeccpsc22/tests/Objects_Service.py index a9ffadc0fdbe5f464772e195c892112131a2fb69..3cbe7725cf12e8b7535a048465646441269cec00 100644 --- a/src/tests/oeccpsc22/tests/Objects_Service.py +++ b/src/tests/oeccpsc22/tests/Objects_Service.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from .Objects_Domain_1 import D1_DEVICE_D1R1_UUID, D1_ENDPOINT_IDS from .Objects_Domain_2 import D2_DEVICE_D2R4_UUID, D2_ENDPOINT_IDS from .Tools import compose_bearer, compose_service_endpoint_id diff --git a/src/tests/oeccpsc22/tests/Tools.py b/src/tests/oeccpsc22/tests/Tools.py index d26c8ae11468f05dc48cb55dc202b9f0efc1d3b6..30333b6f47b31bda76626545b78aaa3c96bff7c0 100644 --- a/src/tests/oeccpsc22/tests/Tools.py +++ b/src/tests/oeccpsc22/tests/Tools.py @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from typing import Dict, List, Tuple from common.tools.object_factory.EndPoint import json_endpoint_id diff --git a/src/tests/oeccpsc22/tests/__init__.py b/src/tests/oeccpsc22/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/oeccpsc22/tests/__init__.py +++ b/src/tests/oeccpsc22/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/tests/test_functional_bootstrap.py b/src/tests/oeccpsc22/tests/test_functional_bootstrap.py index 452394c0165b268c2defa69b899ba554ef4b1504..921b4a4e99389fae126bc91517981217fd7d0017 100644 --- a/src/tests/oeccpsc22/tests/test_functional_bootstrap.py +++ b/src/tests/oeccpsc22/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/tests/test_functional_cleanup.py b/src/tests/oeccpsc22/tests/test_functional_cleanup.py index eb78a585079e3ee757a836433bf23423a3ad899d..7d2c37779c899ab25a8d9954ed94df572432d402 100644 --- a/src/tests/oeccpsc22/tests/test_functional_cleanup.py +++ b/src/tests/oeccpsc22/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py b/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py index b31e868741a7996494d1f7763a3f7e237ca216a1..8c568cc78480bdae7ffd7b96eab839ae00c29432 100644 --- a/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py +++ b/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py b/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py index 45296d107bcdb14472f05c677ba0c75113fd94cc..929267f78bd6a230cb919ed97fdc4277996b7e61 100644 --- a/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py +++ b/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ofc22/__init__.py b/src/tests/ofc22/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/ofc22/__init__.py +++ b/src/tests/ofc22/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ofc22/deploy_specs.sh b/src/tests/ofc22/deploy_specs.sh old mode 100644 new mode 100755 index ffd91da35186fe21f418950493ef797a9af1b522..874774e1ca50830832e842e49b6fff1114cb85d8 --- a/src/tests/ofc22/deploy_specs.sh +++ b/src/tests/ofc22/deploy_specs.sh @@ -1,18 +1,32 @@ -# Set the URL of your local Docker registry where the images will be uploaded to. -export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" +#!/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. -# Supported components are: -# context device automation policy service compute monitoring webui -# interdomain slice pathcomp dlt -# dbscanserving opticalattackmitigator opticalattackdetector -# l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector +#export TFS_COMPONENTS="context device automation monitoring pathcomp service slice compute webui load_generator" export TFS_COMPONENTS="context device automation monitoring 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 to. +# Set the name of the Kubernetes namespace to deploy TFS to. export TFS_K8S_NAMESPACE="tfs" # Set additional manifest files to be applied after the deployment @@ -21,6 +35,60 @@ export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml" # Set the new Grafana admin password export TFS_GRAFANA_PASSWORD="admin123+" -# If not already set, disable skip-build flag. -# If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used. -export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} +# 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 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" + +# 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 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" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# If not already set, set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb" + +# If not already set, set the database username to be used by Monitoring. +export QDB_USERNAME="admin" + +# If not already set, set the database user's password to be used by Monitoring. +export QDB_PASSWORD="quest" + +# If not already set, set the table name to be used by Monitoring. +export QDB_TABLE="tfs_monitoring" + +## If not already set, disable flag for dropping table if exists. +#export QDB_DROP_TABLE_IF_EXISTS="" + +# If not already set, disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" diff --git a/src/tests/ofc22/descriptors_emulated.json b/src/tests/ofc22/descriptors_emulated.json index a71d454f41f324cabb48a023d6d840a59245800c..aa76edecd116ee7336fc1a2621d2bc3ae95080ce 100644 --- a/src/tests/ofc22/descriptors_emulated.json +++ b/src/tests/ofc22/descriptors_emulated.json @@ -1,28 +1,9 @@ { "contexts": [ - { - "context_id": {"context_uuid": {"uuid": "admin"}}, - "topology_ids": [], - "service_ids": [] - } + {"context_id": {"context_uuid": {"uuid": "admin"}}} ], "topologies": [ - { - "topology_id": {"topology_uuid": {"uuid": "admin"}, "context_id": {"context_uuid": {"uuid": "admin"}}}, - "device_ids": [ - {"device_uuid": {"uuid": "R1-EMU"}}, - {"device_uuid": {"uuid": "R2-EMU"}}, - {"device_uuid": {"uuid": "R3-EMU"}}, - {"device_uuid": {"uuid": "R4-EMU"}}, - {"device_uuid": {"uuid": "O1-OLS"}} - ], - "link_ids": [ - {"link_uuid": {"uuid": "R1-EMU/13/0/0==O1-OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}}, - {"link_uuid": {"uuid": "R2-EMU/13/0/0==O1-OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}, - {"link_uuid": {"uuid": "R3-EMU/13/0/0==O1-OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}, - {"link_uuid": {"uuid": "R4-EMU/13/0/0==O1-OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}} - ] - } + {"topology_id": {"topology_uuid": {"uuid": "admin"}, "context_id": {"context_uuid": {"uuid": "admin"}}}} ], "devices": [ { diff --git a/src/tests/ofc22/descriptors_emulated_xr.json b/src/tests/ofc22/descriptors_emulated_xr.json index 4cb0dbfca891faebf4c812c2fbb77f4ecd91330a..d6a2f023422902bfc3d216771092f6081d8cf6b5 100644 --- a/src/tests/ofc22/descriptors_emulated_xr.json +++ b/src/tests/ofc22/descriptors_emulated_xr.json @@ -79,7 +79,7 @@ "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 1\"}"}} + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": "{\"username\": \"xr-user-1\", \"password\": \"xr-user-1\", \"hub_module_name\": \"XR HUB 1\", \"consistency-mode\": \"lifecycle\"}"}} ]}, "device_operational_status": 1, "device_drivers": [6], diff --git a/src/common/orm/Exceptions.py b/src/tests/ofc22/redeploy.sh old mode 100644 new mode 100755 similarity index 77% rename from src/common/orm/Exceptions.py rename to src/tests/ofc22/redeploy.sh index cf91bd2f7a628a86fa45f7eb687b3292e00d0f8e..e4e24aa8031bb43479db8d6fe5a548e1f958440b --- a/src/common/orm/Exceptions.py +++ b/src/tests/ofc22/redeploy.sh @@ -1,4 +1,5 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +#!/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. @@ -12,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -class ConstraintException(Exception): - pass - -class MutexException(Exception): - pass +source ofc22/deploy_specs.sh +./deploy/all.sh +source tfs_runtime_env_vars.sh diff --git a/src/tests/ofc22/run_test_01_bootstrap.sh b/src/tests/ofc22/run_test_01_bootstrap.sh index 61b49b251f927ffb2e845f0c9094d30ea597abc6..cf57eb977755c85eca32da9b042205e966f42a5f 100755 --- a/src/tests/ofc22/run_test_01_bootstrap.sh +++ b/src/tests/ofc22/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/ofc22/tests/test_functional_bootstrap.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_bootstrap.py diff --git a/src/tests/ofc22/run_test_02_create_service.sh b/src/tests/ofc22/run_test_02_create_service.sh index 135a3f74fe93d0d7a4da6ef0e02371a040fc1eb3..7a86e1a3879f0376d5bb725c8ebafeb97ffc0423 100755 --- a/src/tests/ofc22/run_test_02_create_service.sh +++ b/src/tests/ofc22/run_test_02_create_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/ofc22/tests/test_functional_create_service.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_create_service.py diff --git a/src/tests/ofc22/run_test_03_delete_service.sh b/src/tests/ofc22/run_test_03_delete_service.sh index cbe6714fe91cf1758f62e697e667568d35578181..9981f9e3a4e0eb7185bd6fc569465d754ce319bb 100755 --- a/src/tests/ofc22/run_test_03_delete_service.sh +++ b/src/tests/ofc22/run_test_03_delete_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/ofc22/tests/test_functional_delete_service.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_delete_service.py diff --git a/src/tests/ofc22/run_test_04_cleanup.sh b/src/tests/ofc22/run_test_04_cleanup.sh index e88ddbd3227b3f29dfc7f126d5853e0b1d0e06f1..b08edee18b2ffe7ac601683bc40c54db1d867330 100755 --- a/src/tests/ofc22/run_test_04_cleanup.sh +++ b/src/tests/ofc22/run_test_04_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/ofc22/tests/test_functional_cleanup.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_cleanup.py diff --git a/src/tests/ofc22/run_tests.sh b/src/tests/ofc22/run_tests.sh index 0ad4be313987b8b5069808873f94840521d4284e..fe87a2c548d7c5631aca356b7b95771fa1832b94 100755 --- a/src/tests/ofc22/run_tests.sh +++ b/src/tests/ofc22/run_tests.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,32 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. - -PROJECTDIR=`pwd` - -RCFILE=$PROJECTDIR/coverage/.coveragerc -COVERAGEFILE=$PROJECTDIR/coverage/.coverage - -# Configure the correct folder on the .coveragerc file -cat $PROJECTDIR/coverage/.coveragerc.template | sed s+~/teraflow/controller+$PROJECTDIR/src+g > $RCFILE - -# Destroy old coverage file -rm -f $COVERAGEFILE - -source tfs_runtime_env_vars.sh - -# Force a flush of Context database -kubectl --namespace $TFS_K8S_NAMESPACE exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL - # Run functional tests -pytest --log-level=INFO --verbose \ - src/tests/ofc22/tests/test_functional_bootstrap.py - -pytest --log-level=INFO --verbose \ - src/tests/ofc22/tests/test_functional_create_service.py - -pytest --log-level=INFO --verbose \ - src/tests/ofc22/tests/test_functional_delete_service.py - -pytest --log-level=INFO --verbose \ - src/tests/ofc22/tests/test_functional_cleanup.py +source tfs_runtime_env_vars.sh +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_bootstrap.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_create_service.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_delete_service.py +pytest --verbose --log-level=INFO src/tests/ofc22/tests/test_functional_cleanup.py diff --git a/src/tests/ofc22/tests/Fixtures.py b/src/tests/ofc22/tests/Fixtures.py index 3b35a12e299ba776e909fbdd2739e971431083a6..89dda54cf945d7078cd61c4b94b282f650429309 100644 --- a/src/tests/ofc22/tests/Fixtures.py +++ b/src/tests/ofc22/tests/Fixtures.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ofc22/tests/Objects.py b/src/tests/ofc22/tests/Objects.py index 7bfbe9fce558d6a86d965ecb6421369d7f544d4d..2d2d88419ecad1ca03caff09ef8bb8c44b931a70 100644 --- a/src/tests/ofc22/tests/Objects.py +++ b/src/tests/ofc22/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -18,17 +18,21 @@ from tests.tools.mock_osm.Tools import connection_point, wim_mapping # ----- WIM Service Settings ------------------------------------------------------------------------------------------- -WIM_DC1_SITE_ID = '1' -WIM_DC1_DEVICE_ID = json_device_id('R1-EMU') -WIM_DC1_ENDPOINT_ID = json_endpoint_id(WIM_DC1_DEVICE_ID, '13/1/2') +SITE_ID_DC1 = '1' +DEV_ID_DC1 = json_device_id('R1-EMU') +EP_ID_DC1 = json_endpoint_id(DEV_ID_DC1, '13/1/2') -WIM_DC2_SITE_ID = '2' -WIM_DC2_DEVICE_ID = json_device_id('R3-EMU') -WIM_DC2_ENDPOINT_ID = json_endpoint_id(WIM_DC2_DEVICE_ID, '13/1/2') +SITE_ID_DC2 = '2' +DEV_ID_DC2 = json_device_id('R3-EMU') +EP_ID_DC2 = json_endpoint_id(DEV_ID_DC2, '13/1/2') -WIM_SEP_DC1, WIM_MAP_DC1 = wim_mapping(WIM_DC1_SITE_ID, WIM_DC1_ENDPOINT_ID) -WIM_SEP_DC2, WIM_MAP_DC2 = wim_mapping(WIM_DC2_SITE_ID, WIM_DC2_ENDPOINT_ID) -WIM_MAPPING = [WIM_MAP_DC1, WIM_MAP_DC2] +WIM_SEP_DC1, WIM_MAP_DC1 = wim_mapping(SITE_ID_DC1, EP_ID_DC1) +WIM_SEP_DC2, WIM_MAP_DC2 = wim_mapping(SITE_ID_DC2, EP_ID_DC2) + +WIM_MAPPING = [ + WIM_MAP_DC1, + WIM_MAP_DC2, +] WIM_SRV_VLAN_ID = 300 WIM_SERVICE_TYPE = 'ELINE' diff --git a/src/tests/ofc22/tests/ObjectsXr.py b/src/tests/ofc22/tests/ObjectsXr.py index 0cb223de2ede509443275496ba9ca57158335036..9871a50b8181b53cfbb767be76a1a0978eaf1d27 100644 --- a/src/tests/ofc22/tests/ObjectsXr.py +++ b/src/tests/ofc22/tests/ObjectsXr.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,7 +13,7 @@ # limitations under the License. from typing import Dict, List, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_connect_rules, json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, @@ -24,12 +24,12 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from common.proto.kpi_sample_types_pb2 import KpiSampleType # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- Monitoring Samples --------------------------------------------------------------------------------------------- PACKET_PORT_SAMPLE_TYPES = [ diff --git a/src/tests/ofc22/tests/__init__.py b/src/tests/ofc22/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/ofc22/tests/__init__.py +++ b/src/tests/ofc22/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ofc22/tests/test_functional_bootstrap.py b/src/tests/ofc22/tests/test_functional_bootstrap.py index 71deb9d596b1494e148b140902ca927e5d664dd3..ad2d5703a931c933a9ab4e7162dd1985e5a33d9d 100644 --- a/src/tests/ofc22/tests/test_functional_bootstrap.py +++ b/src/tests/ofc22/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,10 +13,10 @@ # limitations under the License. import logging, time +from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import ContextId, Empty from common.proto.monitoring_pb2 import KpiDescriptorList from common.tests.LoadScenario import load_scenario_from_descriptor -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 @@ -27,6 +27,7 @@ LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def test_scenario_bootstrap( context_client : ContextClient, # pylint: disable=redefined-outer-name @@ -66,6 +67,16 @@ def test_scenario_bootstrap( response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) assert len(response.services) == 0 + for context_uuid, _ in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == 0 + + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 + + def test_scenario_kpis_created( context_client : ContextClient, # pylint: disable=redefined-outer-name monitoring_client: MonitoringClient, # pylint: disable=redefined-outer-name diff --git a/src/tests/ofc22/tests/test_functional_cleanup.py b/src/tests/ofc22/tests/test_functional_cleanup.py index be807eaa0242f2363b5b6c189ce4de264528a54c..d38b653b226639d5c8c831872a64ea1f9140ef8f 100644 --- a/src/tests/ofc22/tests/test_functional_cleanup.py +++ b/src/tests/ofc22/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,9 +13,10 @@ # limitations under the License. import logging +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId from common.tools.descriptor.Loader import DescriptorLoader from common.tools.object_factory.Context import json_context_id -from common.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from tests.Fixtures import context_client, device_client # pylint: disable=unused-import @@ -24,7 +25,7 @@ LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json' - +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def test_services_removed( context_client : ContextClient, # pylint: disable=redefined-outer-name @@ -53,6 +54,15 @@ def test_services_removed( response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) assert len(response.services) == 0 + for context_uuid, _ in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == 0 + + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 + # ----- Delete Links, Devices, Topologies, Contexts ---------------------------------------------------------------- for link in descriptor_loader.links: diff --git a/src/tests/ofc22/tests/test_functional_create_service.py b/src/tests/ofc22/tests/test_functional_create_service.py index e606d060d52631ba72e191d7c025bd7b43048b39..92e0a74f9d291ea49422580fbdfad2c354aeeee2 100644 --- a/src/tests/ofc22/tests/test_functional_create_service.py +++ b/src/tests/ofc22/tests/test_functional_create_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,26 +13,24 @@ # limitations under the License. import logging, random -from common.DeviceTypes import DeviceTypeEnum -from common.proto.context_pb2 import ContextId, Empty +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.descriptor.Loader import DescriptorLoader 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 monitoring.client.MonitoringClient import MonitoringClient -from tests.Fixtures import context_client, device_client, monitoring_client # pylint: disable=unused-import +from tests.Fixtures import context_client, device_client, monitoring_client # pylint: disable=unused-import from tests.tools.mock_osm.MockOSM import MockOSM -from .Fixtures import osm_wim # pylint: disable=unused-import +from .Fixtures import osm_wim # pylint: disable=unused-import from .Objects import WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -DEVTYPE_EMU_PR = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value -DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value - DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json' +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name # ----- List entities - Ensure scenario is ready ------------------------------------------------------------------- @@ -56,7 +54,16 @@ def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # for context_uuid, num_services in descriptor_loader.num_services.items(): response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) - assert len(response.services) == 0 + assert len(response.services) == num_services + + for context_uuid, num_slices in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == num_slices + + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 # ----- Create Service --------------------------------------------------------------------------------------------- @@ -78,18 +85,24 @@ def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # response = context_client.ListLinks(Empty()) assert len(response.links) == descriptor_loader.num_links - for context_uuid, num_services in descriptor_loader.num_services.items(): - response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) - LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) - assert len(response.services) == 2*num_services # OLS & L3NM => (L3NM + TAPI) - - for service in response.services: - 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 # one connection per service + 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) == 2 # OLS & L3NM => (L3NM + TAPI) + + for service in response.services: + 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))) + + if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: + assert len(response.connections) == 1 # 1 connection per service + elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: + assert len(response.connections) == 1 # 1 connection per service + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) + def test_scenario_kpi_values_created( diff --git a/src/tests/ofc22/tests/test_functional_create_service_xr.py b/src/tests/ofc22/tests/test_functional_create_service_xr.py index 6008eaa10702f0491742f6195a5fdf15735e5f14..435098589d0e56dd9d1c6baaec1a0ce23dda3354 100644 --- a/src/tests/ofc22/tests/test_functional_create_service_xr.py +++ b/src/tests/ofc22/tests/test_functional_create_service_xr.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/ofc22/tests/test_functional_delete_service.py b/src/tests/ofc22/tests/test_functional_delete_service.py index 0f8d088012bed164e4603a813bfe9154eda8f568..1811f219acf13b5cc17daf39f1931a6f630f997b 100644 --- a/src/tests/ofc22/tests/test_functional_delete_service.py +++ b/src/tests/ofc22/tests/test_functional_delete_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,8 +13,7 @@ # limitations under the License. import logging -from common.Constants import DEFAULT_CONTEXT_UUID -from common.DeviceTypes import DeviceTypeEnum +from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum from common.tools.descriptor.Loader import DescriptorLoader from common.tools.object_factory.Context import json_context_id @@ -22,17 +21,13 @@ from common.tools.grpc.Tools import grpc_message_to_json_string from context.client.ContextClient import ContextClient from tests.Fixtures import context_client # pylint: disable=unused-import from tests.tools.mock_osm.MockOSM import MockOSM -from .Fixtures import osm_wim # pylint: disable=unused-import - +from .Fixtures import osm_wim # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -DEVTYPE_EMU_PR = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value -DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value - DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json' - +ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name # ----- List entities - Ensure service is created ------------------------------------------------------------------ @@ -54,30 +49,38 @@ def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # p response = context_client.ListLinks(Empty()) assert len(response.links) == descriptor_loader.num_links - l3nm_service_uuids = set() - response = context_client.ListServices(ContextId(**json_context_id(DEFAULT_CONTEXT_UUID))) + service_uuids = set() + 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) == 2 # OLS & L3NM => (L3NM + TAPI) + for service in response.services: service_id = service.service_id if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: service_uuid = service_id.service_uuid.uuid - l3nm_service_uuids.add(service_uuid) + service_uuids.add(service_uuid) osm_wim.conn_info[service_uuid] = {} 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 # one connection per service + grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) + + if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: + assert len(response.connections) == 1 # 1 connection per service + elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: + assert len(response.connections) == 1 # 1 connection per service + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) # Identify service to delete - assert len(l3nm_service_uuids) == 1 # assume a single L3NM service has been created - l3nm_service_uuid = set(l3nm_service_uuids).pop() + assert len(service_uuids) == 1 # assume a single L3NM service has been created + service_uuid = set(service_uuids).pop() # ----- Delete Service --------------------------------------------------------------------------------------------- - osm_wim.delete_connectivity_service(l3nm_service_uuid) + osm_wim.delete_connectivity_service(service_uuid) # ----- List entities - Ensure service is removed ------------------------------------------------------------------ @@ -96,4 +99,13 @@ def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # p for context_uuid, num_services in descriptor_loader.num_services.items(): response = context_client.ListServices(ContextId(**json_context_id(context_uuid))) - assert len(response.services) == 0 + assert len(response.services) == num_services + + for context_uuid, num_slices in descriptor_loader.num_slices.items(): + response = context_client.ListSlices(ContextId(**json_context_id(context_uuid))) + assert len(response.slices) == num_slices + + # This scenario assumes no services are created beforehand + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 diff --git a/src/tests/ofc22/tests/test_functional_delete_service_xr.py b/src/tests/ofc22/tests/test_functional_delete_service_xr.py index 546a8781bee125dd48723c67cddd2aec26dc3ed9..6de788ebd91c25b576b44f95f60fe0340cd64881 100644 --- a/src/tests/ofc22/tests/test_functional_delete_service_xr.py +++ b/src/tests/ofc22/tests/test_functional_delete_service_xr.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/__init__.py b/src/tests/p4/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/p4/__init__.py +++ b/src/tests/p4/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/deploy_specs.sh b/src/tests/p4/deploy_specs.sh old mode 100644 new mode 100755 index b486474e2afad7305409bf410c7b8885b0afe2a8..b988123d5564684bd1bfcb776bab7f187fc628ca --- a/src/tests/p4/deploy_specs.sh +++ b/src/tests/p4/deploy_specs.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/tests/p4/mininet/1switch1path.py b/src/tests/p4/mininet/1switch1path.py old mode 100755 new mode 100644 diff --git a/src/tests/p4/mininet/2switch1path.py b/src/tests/p4/mininet/2switch1path.py old mode 100755 new mode 100644 diff --git a/src/tests/p4/mininet/4switch2path.py b/src/tests/p4/mininet/4switch2path.py old mode 100755 new mode 100644 diff --git a/src/tests/p4/mininet/6switch2path.py b/src/tests/p4/mininet/6switch2path.py old mode 100755 new mode 100644 diff --git a/src/tests/p4/run_test_01_bootstrap.sh b/src/tests/p4/run_test_01_bootstrap.sh index a58fd50a762b99f7c8043931f89e087e8fbda6c3..c08b95b7e3e0fd9237e3a61a461099c323ae728f 100755 --- a/src/tests/p4/run_test_01_bootstrap.sh +++ b/src/tests/p4/run_test_01_bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/run_test_02_create_service.sh b/src/tests/p4/run_test_02_create_service.sh index 203c0d5a6dcac35c5355a3d66da0794aa30ad6cc..a972b66c0e1ea3190c71feef930c1043a5dcb281 100755 --- a/src/tests/p4/run_test_02_create_service.sh +++ b/src/tests/p4/run_test_02_create_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/run_test_03_delete_service.sh b/src/tests/p4/run_test_03_delete_service.sh index 8ac52c6f647b866ada0887f8027d2a92dd230700..4b4dfbfaa538a23c1d49448147da0025c7608bc4 100755 --- a/src/tests/p4/run_test_03_delete_service.sh +++ b/src/tests/p4/run_test_03_delete_service.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/run_test_04_cleanup.sh b/src/tests/p4/run_test_04_cleanup.sh index 64cd60f95dbe092c9be125b53a89a6536b6860e0..b1f2735c2e024dfa23a1b311415ad74aea2f7b37 100755 --- a/src/tests/p4/run_test_04_cleanup.sh +++ b/src/tests/p4/run_test_04_cleanup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/setup.sh b/src/tests/p4/setup.sh index 3ff7e0393d0cd87491bf4ef1db9021351502f5a8..78e7f7372d911623cd541495ab15ad3cd548c3ef 100755 --- a/src/tests/p4/setup.sh +++ b/src/tests/p4/setup.sh @@ -1,4 +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. + export POD_NAME=$(kubectl get pods -n=tfs | grep device | awk '{print $1}') diff --git a/src/tests/p4/tests/BuildDescriptors.py b/src/tests/p4/tests/BuildDescriptors.py index 5c5419190487eb5089e4a30f523dca43fa3870f2..98b78863318a7ad682fc5f970d44d02240b45a26 100644 --- a/src/tests/p4/tests/BuildDescriptors.py +++ b/src/tests/p4/tests/BuildDescriptors.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/tests/LoadDescriptors.py b/src/tests/p4/tests/LoadDescriptors.py index 33bc699af933601e4c6d4b8dbc7b0c51206241ef..b232935f4675d718d55e67fe3a76012a39398dda 100644 --- a/src/tests/p4/tests/LoadDescriptors.py +++ b/src/tests/p4/tests/LoadDescriptors.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/tests/Objects.py b/src/tests/p4/tests/Objects.py index 0473207a87ba9ea5c74b45d983db185f8c541cbf..29f01cd61aca58712cb0bc27b7f80c04b2f37d52 100644 --- a/src/tests/p4/tests/Objects.py +++ b/src/tests/p4/tests/Objects.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,7 @@ import os from typing import Dict, List, Tuple -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import ( json_device_connect_rules, json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, @@ -30,12 +30,12 @@ from common.tools.object_factory.Topology import json_topology, json_topology_id from common.proto.kpi_sample_types_pb2 import KpiSampleType # ----- Context -------------------------------------------------------------------------------------------------------- -CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) -CONTEXT = json_context(DEFAULT_CONTEXT_UUID) +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +CONTEXT = json_context(DEFAULT_CONTEXT_NAME) # ----- Topology ------------------------------------------------------------------------------------------------------- -TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) -TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID) +TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) +TOPOLOGY = json_topology(DEFAULT_TOPOLOGY_NAME, context_id=CONTEXT_ID) # ----- Monitoring Samples --------------------------------------------------------------------------------------------- PACKET_PORT_SAMPLE_TYPES = [ diff --git a/src/tests/p4/tests/__init__.py b/src/tests/p4/tests/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/p4/tests/__init__.py +++ b/src/tests/p4/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/tests/test_functional_bootstrap.py b/src/tests/p4/tests/test_functional_bootstrap.py index 793d80c7bf97e9f01a7ba968c8ea1c654d1f4a93..11b24adf137f0b06d1176b440a7fd93b5ad24e80 100644 --- a/src/tests/p4/tests/test_functional_bootstrap.py +++ b/src/tests/p4/tests/test_functional_bootstrap.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/tests/test_functional_cleanup.py b/src/tests/p4/tests/test_functional_cleanup.py index 3dab4f84fdabbc7370de9af0f8e9a69754d310f6..852f2a655dd5ba6cc80902a09d3b118b34d8da47 100644 --- a/src/tests/p4/tests/test_functional_cleanup.py +++ b/src/tests/p4/tests/test_functional_cleanup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/tests/test_functional_create_service.py b/src/tests/p4/tests/test_functional_create_service.py index 96d16a29990b857f83ec946cbdee9ac3b88de717..f160d3c6fbe4d560f821d0d70e90a2b3e44e4e8b 100644 --- a/src/tests/p4/tests/test_functional_create_service.py +++ b/src/tests/p4/tests/test_functional_create_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/p4/tests/test_functional_delete_service.py b/src/tests/p4/tests/test_functional_delete_service.py index 8630686c84259abd242c7b9c2ee65c45b61eb8d4..4d637cf88d840a20f38855beb7839e2b704016d4 100644 --- a/src/tests/p4/tests/test_functional_delete_service.py +++ b/src/tests/p4/tests/test_functional_delete_service.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/scenario2/__init__.py b/src/tests/scenario2/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/scenario2/__init__.py +++ b/src/tests/scenario2/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/scenario2/delete_all.sh b/src/tests/scenario2/delete_all.sh index 5d3e55831c85a3ef547d8e02a29f507663bfa789..6a838d98553870242985ed6858145a2d998dfbdc 100755 --- a/src/tests/scenario2/delete_all.sh +++ b/src/tests/scenario2/delete_all.sh @@ -1,4 +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-dom1 tfs-dom2 tfs-dom3 tfs-dom4 tfs-bchain diff --git a/src/tests/scenario2/deploy_all.sh b/src/tests/scenario2/deploy_all.sh index 582a97ac57f624de93e5865b7dcb190a6797bd5b..19ea0e6db16af66c716927074112da6f18e83b01 100755 --- a/src/tests/scenario2/deploy_all.sh +++ b/src/tests/scenario2/deploy_all.sh @@ -1,4 +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-dom1 tfs-dom2 tfs-dom3 tfs-dom4 diff --git a/src/tests/scenario2/deploy_specs_dom1.sh b/src/tests/scenario2/deploy_specs_dom1.sh old mode 100644 new mode 100755 index 06d32e005f36d883c44d195ccfd20ec9b7e9a4b8..cfe8a3bf63d875b4c579e36ff6a904e0f4b62e02 --- a/src/tests/scenario2/deploy_specs_dom1.sh +++ b/src/tests/scenario2/deploy_specs_dom1.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/tests/scenario2/deploy_specs_dom2.sh b/src/tests/scenario2/deploy_specs_dom2.sh old mode 100644 new mode 100755 index df1726cd31606ada5d2a33d50550b52c02ccbee4..7034c22cdcdc93b6c6fc0e5227e0ef38bda95a55 --- a/src/tests/scenario2/deploy_specs_dom2.sh +++ b/src/tests/scenario2/deploy_specs_dom2.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/tests/scenario2/deploy_specs_dom3.sh b/src/tests/scenario2/deploy_specs_dom3.sh old mode 100644 new mode 100755 index 027762e3e70d0d1cd76b8d3303ae17c97ea781c7..044301418405ba20dfaf00cd58f9a1a15e7e62a7 --- a/src/tests/scenario2/deploy_specs_dom3.sh +++ b/src/tests/scenario2/deploy_specs_dom3.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/tests/scenario2/deploy_specs_dom4.sh b/src/tests/scenario2/deploy_specs_dom4.sh old mode 100644 new mode 100755 index a09e9fa899a0ca9fc941fd09496113a20aebbe59..9e26ace470c81b0bdccfa83bf4eb7369970c981b --- a/src/tests/scenario2/deploy_specs_dom4.sh +++ b/src/tests/scenario2/deploy_specs_dom4.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/tests/scenario2/dump_logs.sh b/src/tests/scenario2/dump_logs.sh index c2298fd8ef735eab102d463391004a818c874b42..7b1dc9d17aabcf8866b76ed1acdb367eee0e3b51 100755 --- a/src/tests/scenario2/dump_logs.sh +++ b/src/tests/scenario2/dump_logs.sh @@ -1,4 +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. + rm -rf tmp/exec diff --git a/src/tests/scenario2/fast_redeploy.sh b/src/tests/scenario2/fast_redeploy.sh old mode 100644 new mode 100755 index c4880a5afb1e5f40f0848437f51d39447c2c0673..87eef3651e2be7a31068c7f418dd7bf815c2e471 --- a/src/tests/scenario2/fast_redeploy.sh +++ b/src/tests/scenario2/fast_redeploy.sh @@ -1,4 +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. + kubectl delete namespace tfs-dom1 tfs-dom2 tfs-dom3 tfs-dom4 diff --git a/src/tests/scenario2/nginx-ingress-controller-dom1.yaml b/src/tests/scenario2/nginx-ingress-controller-dom1.yaml index 1aa1ba48be1bc78e5b0b349dd821e18f80b6953a..1815bfbaa481ef269c513f8b55d949127f10bc30 100644 --- a/src/tests/scenario2/nginx-ingress-controller-dom1.yaml +++ b/src/tests/scenario2/nginx-ingress-controller-dom1.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/nginx-ingress-controller-dom2.yaml b/src/tests/scenario2/nginx-ingress-controller-dom2.yaml index 2dac1ecd26a5fd1c679b8e92ae28b51797987b71..dede032850092733aa9b3136f20ecf078b2ce05a 100644 --- a/src/tests/scenario2/nginx-ingress-controller-dom2.yaml +++ b/src/tests/scenario2/nginx-ingress-controller-dom2.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/nginx-ingress-controller-dom3.yaml b/src/tests/scenario2/nginx-ingress-controller-dom3.yaml index 06eb6b75342e2b6340f6868404c82504da8e09ec..10896ddd0aa335db947a9b072b722e57729253b0 100644 --- a/src/tests/scenario2/nginx-ingress-controller-dom3.yaml +++ b/src/tests/scenario2/nginx-ingress-controller-dom3.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/nginx-ingress-controller-dom4.yaml b/src/tests/scenario2/nginx-ingress-controller-dom4.yaml index c5c2e2f7004cd5ec8b5856b185c4c9de937a7d3f..07df5b1638803f0ec2bb23758c14d4fc6fdf6103 100644 --- a/src/tests/scenario2/nginx-ingress-controller-dom4.yaml +++ b/src/tests/scenario2/nginx-ingress-controller-dom4.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/reset.sh b/src/tests/scenario2/reset.sh index 2bf2cd05559f632b960a5674ea59e334f5123a53..5f4a3b8e5b8a58d8f2acf7c60cde1e77c2e1873a 100755 --- a/src/tests/scenario2/reset.sh +++ b/src/tests/scenario2/reset.sh @@ -1,4 +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. + kubectl --namespace tfs-dom1 scale --replicas=0 \ deployment/contextservice deployment/deviceservice deployment/pathcompservice deployment/serviceservice \ diff --git a/src/tests/scenario2/show_deploy.sh b/src/tests/scenario2/show_deploy.sh index 081b5d3f9430cc3f68b0c1abdf39f0b05eeefae5..2aa8de873cf22e75be830c713fc379df9df154a4 100755 --- a/src/tests/scenario2/show_deploy.sh +++ b/src/tests/scenario2/show_deploy.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/scenario2/tfs-ingress-dom1.yaml b/src/tests/scenario2/tfs-ingress-dom1.yaml index bf2e40352d5acd85fcf9ee446df1a312a40556d6..c638377ee5469d861b22908af0e2b7c1d5d0abf6 100644 --- a/src/tests/scenario2/tfs-ingress-dom1.yaml +++ b/src/tests/scenario2/tfs-ingress-dom1.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/tfs-ingress-dom2.yaml b/src/tests/scenario2/tfs-ingress-dom2.yaml index 40d9480d75dfad817bb1ffe2052a9a71dbb7322d..d07b73ee2a94d6ed54b4b5658c595e1ce635bddb 100644 --- a/src/tests/scenario2/tfs-ingress-dom2.yaml +++ b/src/tests/scenario2/tfs-ingress-dom2.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/tfs-ingress-dom3.yaml b/src/tests/scenario2/tfs-ingress-dom3.yaml index 28668b424aa8bd957e12e53583317f336e3b0640..1c28c0eba275f3ce605c3824e0f2281081d28d7f 100644 --- a/src/tests/scenario2/tfs-ingress-dom3.yaml +++ b/src/tests/scenario2/tfs-ingress-dom3.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/scenario2/tfs-ingress-dom4.yaml b/src/tests/scenario2/tfs-ingress-dom4.yaml index 3774c327ca9ff6d46d538c7a2530a744187b957d..48718d775583e83e55ee3ab3a3b794ce8f0c43ef 100644 --- a/src/tests/scenario2/tfs-ingress-dom4.yaml +++ b/src/tests/scenario2/tfs-ingress-dom4.yaml @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: diff --git a/src/tests/tools/__init__.py b/src/tests/tools/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/tools/__init__.py +++ b/src/tests/tools/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/load_gen/__init__.py b/src/tests/tools/load_gen/__init__.py deleted file mode 100644 index 70a33251242c51f49140e596b8208a19dd5245f7..0000000000000000000000000000000000000000 --- a/src/tests/tools/load_gen/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/tests/tools/load_scenario/__init__.py b/src/tests/tools/load_scenario/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/tools/load_scenario/__init__.py +++ b/src/tests/tools/load_scenario/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/load_scenario/__main__.py b/src/tests/tools/load_scenario/__main__.py index f2cd11919ab8afd116e6cab8d7d9a6d4fd3ce54b..3559f778d7cf850c3bbb4f2d516f45f18423d28c 100644 --- a/src/tests/tools/load_scenario/__main__.py +++ b/src/tests/tools/load_scenario/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/load_scenario/run.sh b/src/tests/tools/load_scenario/run.sh index 0ec0c3725d27c1246b776fef8f89a57beb561555..98ebc6c1790ae256c592408ff731e347ec8ebb0e 100755 --- a/src/tests/tools/load_scenario/run.sh +++ b/src/tests/tools/load_scenario/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/mock_osm/Constants.py b/src/tests/tools/mock_osm/Constants.py index 44d74169f0fd68073ca4ed5272f3dc7ef3ebf958..8d4145e89274927069a56830c2ed7bef92ced08c 100644 --- a/src/tests/tools/mock_osm/Constants.py +++ b/src/tests/tools/mock_osm/Constants.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/mock_osm/MockOSM.py b/src/tests/tools/mock_osm/MockOSM.py index b4e629d5845fd7115fa0fa2c0887eca1c7c816c4..338db0e19becc8a9dd277beec7f3b4ceb2e765a3 100644 --- a/src/tests/tools/mock_osm/MockOSM.py +++ b/src/tests/tools/mock_osm/MockOSM.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/mock_osm/Tools.py b/src/tests/tools/mock_osm/Tools.py index 25a8b6111443424e8bfd2b35501b96a9a762325f..45dfa23c984e175c01efa77371e94454b98ea94e 100644 --- a/src/tests/tools/mock_osm/Tools.py +++ b/src/tests/tools/mock_osm/Tools.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/mock_osm/WimconnectorIETFL2VPN.py b/src/tests/tools/mock_osm/WimconnectorIETFL2VPN.py index e1273b4e483a06df23d94bdf107005ce7585fb5e..aa4ca045f41ffdc69d2ebf2fcd9b5db99ce45dbe 100644 --- a/src/tests/tools/mock_osm/WimconnectorIETFL2VPN.py +++ b/src/tests/tools/mock_osm/WimconnectorIETFL2VPN.py @@ -73,7 +73,7 @@ class WimconnectorIETFL2VPN(SdnConnectorBase): response = requests.get(endpoint, auth=self.auth) http_code = response.status_code except requests.exceptions.RequestException as e: - raise SdnConnectorError(e.message, http_code=503) + raise SdnConnectorError(e.response, http_code=503) if http_code != 200: raise SdnConnectorError("Failed while authenticating", http_code=http_code) diff --git a/src/tests/tools/mock_osm/__init__.py b/src/tests/tools/mock_osm/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/tests/tools/mock_osm/__init__.py +++ b/src/tests/tools/mock_osm/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py b/src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py index 61eec6fe674a0348a92cb84af439c6fbf8668f28..63be214b671c2ee9b222d92e6f964a4203b8a587 100644 --- a/src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py +++ b/src/tests/tools/mock_sdn_ctrl/MockMWSdnCtrl.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/tests/tools/mock_sdn_ctrl/microwave_deploy.sh b/src/tests/tools/mock_sdn_ctrl/microwave_deploy.sh old mode 100644 new mode 100755 index 2da884899c84491e36d87b87c502d2773cdf7f69..fb0629dc4ce600f7bea058a7bcfbbd261ac157cb --- a/src/tests/tools/mock_sdn_ctrl/microwave_deploy.sh +++ b/src/tests/tools/mock_sdn_ctrl/microwave_deploy.sh @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 URL of your local Docker registry where the images will be uploaded to. export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/" diff --git a/src/webui/.gitlab-ci.yml b/src/webui/.gitlab-ci.yml index e939d834761834f60e13045f7ce941f41887b956..26af10f4e5b3ab23fcd0802ba6df9d2ad3bf7a19 100644 --- a/src/webui/.gitlab-ci.yml +++ b/src/webui/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/Config.py b/src/webui/Config.py index f7573f681aa4da3046850676aaeabe694cf490de..9f104e8d3e6d943dc0fec7f7791d9f30c6407ded 100644 --- a/src/webui/Config.py +++ b/src/webui/Config.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/Dockerfile b/src/webui/Dockerfile index a17d2bd9aea9c6948262dcf17776f75c0be351b8..7c718890fcf3f07b32f66eca2ecab41f2eb30fbb 100644 --- a/src/webui/Dockerfile +++ b/src/webui/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -77,6 +77,8 @@ COPY --chown=webui:webui src/context/__init__.py context/__init__.py COPY --chown=webui:webui src/context/client/. context/client/ COPY --chown=webui:webui src/device/__init__.py device/__init__.py COPY --chown=webui:webui src/device/client/. device/client/ +COPY --chown=webui:webui src/load_generator/__init__.py load_generator/__init__.py +COPY --chown=webui:webui src/load_generator/client/. load_generator/client/ COPY --chown=webui:webui src/service/__init__.py service/__init__.py COPY --chown=webui:webui src/service/client/. service/client/ COPY --chown=webui:webui src/slice/__init__.py slice/__init__.py diff --git a/src/webui/__init__.py b/src/webui/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/__init__.py +++ b/src/webui/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/grafana_dashboard_psql.json b/src/webui/grafana_dashboard_psql.json index aa2676e26a0336c8279a658dbbdabaafa9c6b4d0..ec89c1647cc1086140b0bbd35354546c405ce910 100644 --- a/src/webui/grafana_dashboard_psql.json +++ b/src/webui/grafana_dashboard_psql.json @@ -26,14 +26,14 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "iteration": 1664814762635, + "iteration": 1675103296430, "links": [], "liveNow": false, "panels": [ { "datasource": { "type": "postgres", - "uid": "monitoringdb" + "uid": "questdb" }, "fieldConfig": { "defaults": { @@ -162,14 +162,14 @@ { "datasource": { "type": "postgres", - "uid": "monitoringdb" + "uid": "questdb" }, "format": "time_series", "group": [], "hide": false, "metricColumn": "kpi_value", "rawQuery": true, - "rawSql": "SELECT\r\n $__time(timestamp), kpi_value AS metric, device_id, endpoint_id, kpi_sample_type\r\nFROM\r\n monitoring\r\nWHERE\r\n $__timeFilter(timestamp) AND device_id IN ($device_id) AND endpoint_id IN ($endpoint_id) AND kpi_sample_type IN ($kpi_sample_type)\r\nGROUP BY\r\n device_id, endpoint_id, kpi_sample_type\r\nORDER BY\r\n timestamp\r\n", + "rawSql": "SELECT\r\n $__time(timestamp), kpi_value AS metric, device_name, endpoint_name, kpi_sample_type\r\nFROM\r\n tfs_monitoring\r\nWHERE\r\n $__timeFilter(timestamp) AND device_name IN (${device_name}) AND endpoint_name IN (${endpoint_name}) AND kpi_sample_type IN (${kpi_sample_type})\r\nGROUP BY\r\n device_name, endpoint_name, kpi_sample_type\r\nORDER BY\r\n timestamp", "refId": "A", "select": [ [ @@ -201,8 +201,8 @@ { "id": "renameByRegex", "options": { - "regex": "metric {device_id=\\\"([^\\\"]+)\\\", endpoint_id=\\\"([^\\\"]+)\\\", kpi_sample_type=\\\"([^\\\"]+)\\\"}", - "renamePattern": "$3 ($1 $2)" + "regex": "metric {device_name=\\\"([^\\\"]+)\\\", endpoint_name=\\\"([^\\\"]+)\\\", kpi_sample_type=\\\"([^\\\"]+)\\\"}", + "renamePattern": "$3 ($1 : $2)" } } ], @@ -227,16 +227,16 @@ }, "datasource": { "type": "postgres", - "uid": "monitoringdb" + "uid": "questdb" }, - "definition": "SELECT DISTINCT device_id FROM monitoring;", + "definition": "SELECT DISTINCT device_name FROM tfs_monitoring;", "hide": 0, "includeAll": true, "label": "Device", "multi": true, - "name": "device_id", + "name": "device_name", "options": [], - "query": "SELECT DISTINCT device_id FROM monitoring;", + "query": "SELECT DISTINCT device_name FROM tfs_monitoring;", "refresh": 2, "regex": "", "skipUrlSync": false, @@ -245,22 +245,26 @@ }, { "current": { - "selected": false, - "text": "All", - "value": "$__all" + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] }, "datasource": { "type": "postgres", - "uid": "monitoringdb" + "uid": "questdb" }, - "definition": "SELECT DISTINCT endpoint_id FROM monitoring WHERE device_id IN (${device_id})", + "definition": "SELECT DISTINCT endpoint_name FROM tfs_monitoring WHERE device_name IN (${device_name})", "hide": 0, "includeAll": true, "label": "EndPoint", "multi": true, - "name": "endpoint_id", + "name": "endpoint_name", "options": [], - "query": "SELECT DISTINCT endpoint_id FROM monitoring WHERE device_id IN (${device_id})", + "query": "SELECT DISTINCT endpoint_name FROM tfs_monitoring WHERE device_name IN (${device_name})", "refresh": 2, "regex": "", "skipUrlSync": false, @@ -271,26 +275,24 @@ "current": { "selected": true, "text": [ - "PACKETS_RECEIVED", - "PACKETS_TRANSMITTED" + "All" ], "value": [ - "PACKETS_RECEIVED", - "PACKETS_TRANSMITTED" + "$__all" ] }, "datasource": { "type": "postgres", - "uid": "monitoringdb" + "uid": "questdb" }, - "definition": "SELECT DISTINCT kpi_sample_type FROM monitoring;", + "definition": "SELECT DISTINCT kpi_sample_type FROM tfs_monitoring;", "hide": 0, "includeAll": true, "label": "Kpi Sample Type", "multi": true, "name": "kpi_sample_type", "options": [], - "query": "SELECT DISTINCT kpi_sample_type FROM monitoring;", + "query": "SELECT DISTINCT kpi_sample_type FROM tfs_monitoring;", "refresh": 2, "regex": "", "skipUrlSync": false, @@ -300,14 +302,14 @@ ] }, "time": { - "from": "now-15m", + "from": "now-5m", "to": "now" }, "timepicker": {}, - "timezone": "", + "timezone": "utc", "title": "L3 Monitoring", "uid": "tf-l3-monit", - "version": 1, + "version": 6, "weekStart": "" } } diff --git a/src/webui/requirements.in b/src/webui/requirements.in index fc13bdc5d79f8a8e703638c923e8dc76a4e1a063..b4a158d394bc2de67af1e0e99e922df08104f736 100644 --- a/src/webui/requirements.in +++ b/src/webui/requirements.in @@ -1,3 +1,17 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + Flask==2.1.3 Flask-WTF==1.0.0 flask-healthz==0.0.3 diff --git a/src/webui/service/__init__.py b/src/webui/service/__init__.py index d60cca6597ced52db8e320f3ba1beb2b032be65b..d5b40b486dd7772cea29fd7d71db949b2954155c 100644 --- a/src/webui/service/__init__.py +++ b/src/webui/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,6 +13,7 @@ # limitations under the License. import json +from typing import List, Tuple, Union from flask import Flask, request, session from flask_healthz import healthz, HealthError from context.client.ContextClient import ContextClient @@ -36,10 +37,20 @@ def readiness(): device_client.connect() device_client.close() except Exception as e: - raise HealthError('Can\'t connect with the service: ' + e.details()) + raise HealthError("Can't connect with the service: {:s}".format(str(e))) from e -def from_json(json_str): - return json.loads(json_str) +def json_to_list(json_str : str) -> List[Union[str, Tuple[str, str]]]: + try: + data = json.loads(json_str) + except: # pylint: disable=bare-except + return [('item', str(json_str))] + + if isinstance(data, dict): + return [('kv', (key, value)) for key, value in data.items()] + elif isinstance(data, list): + return [('item', ', '.join(data))] + else: + return [('item', str(data))] class SetSubAppMiddleware(): def __init__(self, app, web_app_root): @@ -63,29 +74,32 @@ def create_app(use_config=None, web_app_root=None): app.register_blueprint(healthz, url_prefix='/healthz') - from webui.service.js.routes import js + from webui.service.js.routes import js # pylint: disable=import-outside-toplevel app.register_blueprint(js) - from webui.service.main.routes import main + from webui.service.main.routes import main # pylint: disable=import-outside-toplevel app.register_blueprint(main) - from webui.service.service.routes import service + from webui.service.load_gen.routes import load_gen # pylint: disable=import-outside-toplevel + app.register_blueprint(load_gen) + + from webui.service.service.routes import service # pylint: disable=import-outside-toplevel app.register_blueprint(service) - from webui.service.slice.routes import slice + from webui.service.slice.routes import slice # pylint: disable=import-outside-toplevel,redefined-builtin app.register_blueprint(slice) - from webui.service.device.routes import device + from webui.service.device.routes import device # pylint: disable=import-outside-toplevel app.register_blueprint(device) - from webui.service.link.routes import link + from webui.service.link.routes import link # pylint: disable=import-outside-toplevel app.register_blueprint(link) - - app.jinja_env.filters['from_json'] = from_json - - app.jinja_env.globals.update(get_working_context=get_working_context) - app.jinja_env.globals.update(get_working_topology=get_working_topology) + app.jinja_env.globals.update({ # pylint: disable=no-member + 'json_to_list' : json_to_list, + 'get_working_context' : get_working_context, + 'get_working_topology': get_working_topology, + }) if web_app_root is not None: app.wsgi_app = SetSubAppMiddleware(app.wsgi_app, web_app_root) diff --git a/src/webui/service/__main__.py b/src/webui/service/__main__.py index ddbda9c511eac4554c168128b3318b3107d892d7..f07056d509552f0d2db92468f9785446f56ce421 100644 --- a/src/webui/service/__main__.py +++ b/src/webui/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/context/__init__.py b/src/webui/service/context/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/service/context/__init__.py +++ b/src/webui/service/context/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/context/routes.py b/src/webui/service/context/routes.py index 29910cbc34509f1dc0848359fd7367a07174b6dc..7c45f136db195c1581c7de7e92d4a0df907ad869 100644 --- a/src/webui/service/context/routes.py +++ b/src/webui/service/context/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/device/__init__.py b/src/webui/service/device/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/service/device/__init__.py +++ b/src/webui/service/device/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/device/forms.py b/src/webui/service/device/forms.py index d1880d321c4cb2cc825baed5353b892aae90aae9..e496c4d432c7c9d02227141ea6d618984378c185 100644 --- a/src/webui/service/device/forms.py +++ b/src/webui/service/device/forms.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,41 +14,45 @@ # external imports from flask_wtf import FlaskForm -from wtforms import StringField, SelectField, TextAreaField, SubmitField +from wtforms import StringField, SelectField, TextAreaField, SubmitField, BooleanField, Form from wtforms.validators import DataRequired, Length, NumberRange, Regexp, ValidationError -from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum +from common.proto.context_pb2 import DeviceOperationalStatusEnum from webui.utils.form_validators import key_value_validator class AddDeviceForm(FlaskForm): device_id = StringField('ID', validators=[DataRequired(), Length(min=5)]) - device_type = StringField('Type', - validators=[DataRequired(), Length(min=5)]) - device_config = TextAreaField('Configurations', validators=[key_value_validator()]) + device_type = SelectField('Type', choices = []) operational_status = SelectField('Operational Status', # choices=[(-1, 'Select...'), (0, 'Undefined'), (1, 'Disabled'), (2, 'Enabled')], coerce=int, validators=[NumberRange(min=0)]) - device_drivers = TextAreaField('Drivers', validators=[DataRequired(), Regexp(r'^\d+(,\d+)*$')]) + device_drivers_undefined = BooleanField('UNDEFINED / EMULATED') + device_drivers_openconfig = BooleanField('OPENCONFIG') + device_drivers_transport_api = BooleanField('TRANSPORT_API') + device_drivers_p4 = BooleanField('P4') + device_drivers_ietf_network_topology = BooleanField('IETF_NETWORK_TOPOLOGY') + device_drivers_onf_tr_352 = BooleanField('ONF_TR_352') + device_drivers_xr = BooleanField('XR') + device_config_address = StringField('connect/address',default='127.0.0.1',validators=[DataRequired(), Length(min=5)]) + device_config_port = StringField('connect/port',default='0',validators=[DataRequired(), Length(min=1)]) + device_config_settings = TextAreaField('connect/settings',default='{}',validators=[DataRequired(), Length(min=2)]) submit = SubmitField('Add') def validate_operational_status(form, field): if field.data not in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_number: raise ValidationError('The operational status value selected is incorrect!') - def validate_device_drivers(form, field): - if ',' not in field.data: - data = str(field.data) + ',' - else: - data = field.data - for value in data.split(','): - value = value.strip() - if len(value) == 0: - continue - try: - value_int = int(value) - except: - raise ValidationError(f'The value "{value}" is not a valid driver identified.') - if value_int not in DeviceDriverEnum.DESCRIPTOR.values_by_number: - values = ', '.join([str(x) for x in DeviceDriverEnum.DESCRIPTOR.values_by_number]) - raise ValidationError(f'The device driver {value_int} is not correct. Allowed values are: {values}.') +class ConfigForm(FlaskForm): + device_key_config = StringField('Key configuration') + device_value_config = StringField('Value configuration') + submit = SubmitField('Add') + + +class UpdateDeviceForm(FlaskForm): + update_operational_status = SelectField('Operational Status', + choices=[(-1, 'Select...'), (0, 'Undefined'), (1, 'Disabled'), (2, 'Enabled')], + coerce=int, + validators=[NumberRange(min=0)]) + + submit = SubmitField('Update') diff --git a/src/webui/service/device/routes.py b/src/webui/service/device/routes.py index b57c5735d4b26c541d60a885512fe37a2fd626bc..ce3edcfda45859c3e5db83c62fd328ee546762a5 100644 --- a/src/webui/service/device/routes.py +++ b/src/webui/service/device/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,16 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for from common.proto.context_pb2 import ( - ConfigActionEnum, ConfigRule, - Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, - Empty, TopologyId) + ConfigActionEnum, Device, DeviceDriverEnum, DeviceId, DeviceList, DeviceOperationalStatusEnum, Empty, TopologyId) 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 device.client.DeviceClient import DeviceClient from webui.service.device.forms import AddDeviceForm +from common.DeviceTypes import DeviceTypeEnum +from webui.service.device.forms import ConfigForm +from webui.service.device.forms import UpdateDeviceForm device = Blueprint('device', __name__, url_prefix='/device') context_client = ContextClient() @@ -29,7 +31,7 @@ device_client = DeviceClient() @device.get('/') def home(): - if 'context_topology_uuid' not in session: + if 'context_uuid' not in session or 'topology_uuid' not in session: flash("Please select a context!", "warning") return redirect(url_for("main.home")) @@ -57,60 +59,78 @@ def add(): form = AddDeviceForm() # listing enum values - form.operational_status.choices = [(-1, 'Select...')] - for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): + form.operational_status.choices = [] + for key, _ in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): form.operational_status.choices.append( (DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', ''))) - # device driver ids - device_driver_ids = [] - for key in DeviceDriverEnum.DESCRIPTOR.values_by_name: - device_driver_ids.append(f"{DeviceDriverEnum.Value(key)}={key.replace('DEVICEDRIVER_', '')}") - device_driver_ids = ', '.join(device_driver_ids) + # items for Device Type field + for device_type in DeviceTypeEnum: + form.device_type.choices.append((device_type.value,device_type.value)) if form.validate_on_submit(): - device = Device() - device.device_id.device_uuid.uuid = form.device_id.data - device.device_type = form.device_type.data - if '\n' not in form.device_config.data: - data = form.device_config.data.strip() + '\n' - else: - data = form.device_config.data.strip() - - for config in data.split('\n'): - if len(config.strip()) > 0: - parts = config.strip().split('=') - config_rule: ConfigRule = ConfigRule() - config_rule.action = ConfigActionEnum.CONFIGACTION_SET - config_rule.custom.resource_key = parts[0].strip() - config_rule.custom.resource_value = parts[1].strip() - device.device_config.config_rules.append(config_rule) - - device.device_operational_status = form.operational_status.data - - if ',' not in form.device_drivers.data: - data = form.device_drivers.data.strip() + ',' + device_obj = Device() + # Device UUID: + device_obj.device_id.device_uuid.uuid = form.device_id.data + + # Device type: + device_obj.device_type = str(form.device_type.data) + + # Device configurations: + config_rule = device_obj.device_config.config_rules.add() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = '_connect/address' + config_rule.custom.resource_value = form.device_config_address.data + + config_rule = device_obj.device_config.config_rules.add() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = '_connect/port' + config_rule.custom.resource_value = form.device_config_port.data + + config_rule = device_obj.device_config.config_rules.add() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = '_connect/settings' + + try: + device_config_settings = json.loads(form.device_config_settings.data) + except: # pylint: disable=bare-except + device_config_settings = form.device_config_settings.data + + if isinstance(device_config_settings, dict): + config_rule.custom.resource_value = json.dumps(device_config_settings) else: - data = form.device_drivers.data.strip() - - for driver in data.split(','): - driver = driver.strip() - if len(driver) == 0: - continue - device.device_drivers.append(int(driver)) + config_rule.custom.resource_value = str(device_config_settings) + + # Device status: + device_obj.device_operational_status = form.operational_status.data + + # Device drivers: + if form.device_drivers_undefined.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_UNDEFINED) + if form.device_drivers_openconfig.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG) + if form.device_drivers_transport_api.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API) + if form.device_drivers_p4.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_P4) + if form.device_drivers_ietf_network_topology.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY) + if form.device_drivers_onf_tr_352.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352) + if form.device_drivers_xr.data: + device_obj.device_drivers.append(DeviceDriverEnum.DEVICEDRIVER_XR) + try: device_client.connect() - response: DeviceId = device_client.AddDevice(device) + response: DeviceId = device_client.AddDevice(device_obj) device_client.close() - flash(f'New device was created with ID "{response.device_uuid.uuid}".', 'success') return redirect(url_for('device.home')) except Exception as e: flash(f'Problem adding the device. {e.details()}', 'danger') return render_template('device/add.html', form=form, - submit_text='Add New Device', - device_driver_ids=device_driver_ids) + submit_text='Add New Device') @device.route('detail/', methods=['GET', 'POST']) def detail(device_uuid: str): @@ -144,3 +164,67 @@ def delete(device_uuid): flash(f'Problem deleting device "{device_uuid}": {e.details()}', 'danger') current_app.logger.exception(e) return redirect(url_for('device.home')) + +@device.route('/addconfig', methods=['GET', 'POST']) +def addconfig(device_uuid): + form = ConfigForm() + request = DeviceId() + request.device_uuid.uuid = device_uuid + context_client.connect() + response = context_client.GetDevice(request) + context_client.close() + + if form.validate_on_submit(): + device = Device() + device.CopyFrom(response) + config_rule = device.device_config.config_rules.add() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = form.device_key_config.data + config_rule.custom.resource_value = form.device_value_config.data + try: + device_client.connect() + response: DeviceId = device_client.ConfigureDevice(device) + device_client.close() + flash(f'New configuration was created with ID "{response.device_uuid.uuid}".', 'success') + return redirect(url_for('device.home')) + except Exception as e: + flash(f'Problem adding the device. {e.details()}', 'danger') + + return render_template('device/addconfig.html', form=form, submit_text='Add New Configuration') + +@device.route('updateconfig', methods=['GET', 'POST']) +def updateconfig(): + + + return render_template('device/updateconfig.html') + + +@device.route('/update', methods=['GET', 'POST']) +def update(device_uuid): + form = UpdateDeviceForm() + request = DeviceId() + request.device_uuid.uuid = device_uuid + context_client.connect() + response = context_client.GetDevice(request) + context_client.close() + + # listing enum values + form.update_operational_status.choices = [] + for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items(): + form.update_operational_status.choices.append((DeviceOperationalStatusEnum.Value(key), key.replace('DEVICEOPERATIONALSTATUS_', ''))) + + form.update_operational_status.default = response.device_operational_status + + if form.validate_on_submit(): + device = Device() + device.CopyFrom(response) + device.device_operational_status = form.update_operational_status.data + try: + device_client.connect() + response: DeviceId = device_client.ConfigureDevice(device) + device_client.close() + flash(f'Status of device with ID "{response.device_uuid.uuid}" was updated.', 'success') + return redirect(url_for('device.home')) + except Exception as e: + flash(f'Problem updating the device. {e.details()}', 'danger') + return render_template('device/update.html', device=response, form=form, submit_text='Update Device') diff --git a/src/webui/service/js/__init__.py b/src/webui/service/js/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/service/js/__init__.py +++ b/src/webui/service/js/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/js/routes.py b/src/webui/service/js/routes.py index fee4109df048a29954ce924ef57ec62d6adc27fb..68e0af893a9f82197d18ee4d6632c934ff17ef35 100644 --- a/src/webui/service/js/routes.py +++ b/src/webui/service/js/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/link/__init__.py b/src/webui/service/link/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..355dcdb04bdddd352966a9567a7a63117666e619 100644 --- a/src/webui/service/link/__init__.py +++ b/src/webui/service/link/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/webui/service/link/routes.py b/src/webui/service/link/routes.py index 5b8831b7732443830a6f9b1ef8f7da92b4c41cc0..9324ad0be6d9e72dfd3413863f0590f6ec595c3b 100644 --- a/src/webui/service/link/routes.py +++ b/src/webui/service/link/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -13,8 +13,9 @@ # limitations under the License. -from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for -from common.proto.context_pb2 import Empty, Link, LinkEvent, LinkId, LinkIdList, LinkList, DeviceId, TopologyId +from flask import render_template, Blueprint, flash, session, redirect, url_for +from common.proto.context_pb2 import Empty, LinkId, LinkList, TopologyId +from common.tools.context_queries.EndPoint import get_endpoint_names 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 @@ -25,7 +26,7 @@ context_client = ContextClient() @link.get('/') def home(): - if 'context_topology_uuid' not in session: + if 'context_uuid' not in session or 'topology_uuid' not in session: flash("Please select a context!", "warning") return redirect(url_for("main.home")) @@ -37,22 +38,26 @@ def home(): grpc_topology = context_client.GetTopology(TopologyId(**json_topo_id)) topo_link_uuids = {link_id.link_uuid.uuid for link_id in grpc_topology.link_ids} grpc_links: LinkList = context_client.ListLinks(Empty()) - context_client.close() - links = [ - link for link in grpc_links.links - if link.link_id.link_uuid.uuid in topo_link_uuids - ] + endpoint_ids = [] + links = [] + for link_ in grpc_links.links: + if link_.link_id.link_uuid.uuid not in topo_link_uuids: continue + links.append(link_) + endpoint_ids.extend(link_.link_endpoint_ids) + + device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) + context_client.close() - return render_template( - 'link/home.html', links=links) + return render_template('link/home.html', links=links, device_names=device_names, endpoints_data=endpoints_data) @link.route('detail/', methods=('GET', 'POST')) def detail(link_uuid: str): request = LinkId() - request.link_uuid.uuid = link_uuid + request.link_uuid.uuid = link_uuid # pylint: disable=no-member context_client.connect() response = context_client.GetLink(request) + device_names, endpoints_data = get_endpoint_names(context_client, response.link_endpoint_ids) context_client.close() - return render_template('link/detail.html',link=response) + return render_template('link/detail.html',link=response, device_names=device_names, endpoints_data=endpoints_data) diff --git a/src/webui/service/load_gen/__init__.py b/src/webui/service/load_gen/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/webui/service/load_gen/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/webui/service/load_gen/routes.py b/src/webui/service/load_gen/routes.py new file mode 100644 index 0000000000000000000000000000000000000000..3118b6de0e061adac65be178163623cd2d1d8fff --- /dev/null +++ b/src/webui/service/load_gen/routes.py @@ -0,0 +1,45 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from flask import render_template, Blueprint, flash +from common.proto.context_pb2 import Empty +from load_generator.client.LoadGeneratorClient import LoadGeneratorClient + +load_gen = Blueprint('load_gen', __name__, url_prefix='/load_gen') + +@load_gen.route('start', methods=['GET']) +def start(): + load_gen_client = LoadGeneratorClient() + try: + load_gen_client.connect() + load_gen_client.Start(Empty()) + load_gen_client.close() + flash('Load Generator Started.', 'success') + except Exception as e: # pylint: disable=broad-except + flash('Problem starting Load Generator. {:s}'.format(str(e)), 'danger') + + return render_template('main/debug.html') + +@load_gen.route('stop', methods=['GET']) +def stop(): + load_gen_client = LoadGeneratorClient() + try: + load_gen_client.connect() + load_gen_client.Stop(Empty()) + load_gen_client.close() + flash('Load Generator Stoped.', 'success') + except Exception as e: # pylint: disable=broad-except + flash('Problem stopping Load Generator. {:s}'.format(str(e)), 'danger') + + return render_template('main/debug.html') diff --git a/src/webui/service/main/__init__.py b/src/webui/service/main/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/service/main/__init__.py +++ b/src/webui/service/main/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/main/forms.py b/src/webui/service/main/forms.py index b138592fccd3f65831673912d04aba79f2dd3c72..9d628e072fe271b11c79df9845fa18c532a81407 100644 --- a/src/webui/service/main/forms.py +++ b/src/webui/service/main/forms.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py index 0e008734730867bca741d748c49e3b0589b40e48..38d13aad562f3e55490952db84ef784f87697739 100644 --- a/src/webui/service/main/routes.py +++ b/src/webui/service/main/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json, logging, re +import base64, json, logging, re from flask import jsonify, redirect, render_template, Blueprint, flash, session, url_for, request -from common.proto.context_pb2 import Empty, ContextIdList, TopologyId, TopologyIdList +from common.proto.context_pb2 import ContextList, Empty, TopologyId, TopologyList from common.tools.descriptor.Loader import DescriptorLoader, compose_notifications from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id @@ -32,7 +32,7 @@ device_client = DeviceClient() service_client = ServiceClient() slice_client = SliceClient() -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) def process_descriptors(descriptors): try: @@ -46,6 +46,7 @@ def process_descriptors(descriptors): descriptor_loader = DescriptorLoader(descriptors) results = descriptor_loader.process() for message,level in compose_notifications(results): + if level == 'error': LOGGER.warning('ERROR message={:s}'.format(str(message))) flash(message, level) @main.route('/', methods=['GET', 'POST']) @@ -55,28 +56,45 @@ def home(): context_topology_form: ContextTopologyForm = ContextTopologyForm() context_topology_form.context_topology.choices.append(('', 'Select...')) - ctx_response: ContextIdList = context_client.ListContextIds(Empty()) - for context_id in ctx_response.context_ids: - context_uuid = context_id.context_uuid.uuid - topo_response: TopologyIdList = context_client.ListTopologyIds(context_id) - for topology_id in topo_response.topology_ids: - topology_uuid = topology_id.topology_uuid.uuid - context_topology_uuid = 'ctx[{:s}]/topo[{:s}]'.format(context_uuid, topology_uuid) - context_topology_name = 'Context({:s}):Topology({:s})'.format(context_uuid, topology_uuid) + contexts : ContextList = context_client.ListContexts(Empty()) + for context_ in contexts.contexts: + #context_uuid : str = context_.context_id.context_uuid.uuid + context_name : str = context_.name + topologies : TopologyList = context_client.ListTopologies(context_.context_id) + for topology_ in topologies.topologies: + #topology_uuid : str = topology_.topology_id.topology_uuid.uuid + topology_name : str = topology_.name + raw_values = context_name, topology_name + b64_values = [base64.b64encode(v.encode('utf-8')).decode('utf-8') for v in raw_values] + context_topology_uuid = ','.join(b64_values) + context_topology_name = 'Context({:s}):Topology({:s})'.format(context_name, topology_name) context_topology_entry = (context_topology_uuid, context_topology_name) context_topology_form.context_topology.choices.append(context_topology_entry) if context_topology_form.validate_on_submit(): context_topology_uuid = context_topology_form.context_topology.data if len(context_topology_uuid) > 0: - match = re.match('ctx\[([^\]]+)\]\/topo\[([^\]]+)\]', context_topology_uuid) - if match is not None: - session['context_topology_uuid'] = context_topology_uuid = match.group(0) - session['context_uuid'] = context_uuid = match.group(1) - session['topology_uuid'] = topology_uuid = match.group(2) - MSG = f'Context({context_uuid})/Topology({topology_uuid}) successfully selected.' - flash(MSG, 'success') - return redirect(url_for("main.home")) + b64_values = context_topology_uuid.split(',') + raw_values = [base64.b64decode(v.encode('utf-8')).decode('utf-8') for v in b64_values] + context_name, topology_name = raw_values + #session.clear() + session['context_topology_uuid'] = context_topology_uuid + session['context_uuid'] = context_name + #session['context_name'] = context_name + session['topology_uuid'] = topology_name + #session['topology_name'] = topology_name + MSG = f'Context({context_name})/Topology({topology_name}) successfully selected.' + flash(MSG, 'success') + return redirect(url_for('main.home')) + + #match = re.match('ctx\[([^\]]+)\]\/topo\[([^\]]+)\]', context_topology_uuid) + #if match is not None: + # session['context_topology_uuid'] = context_topology_uuid = match.group(0) + # session['context_uuid'] = context_uuid = match.group(1) + # session['topology_uuid'] = topology_uuid = match.group(2) + # MSG = f'Context({context_uuid})/Topology({topology_uuid}) successfully selected.' + # flash(MSG, 'success') + # return redirect(url_for('main.home')) if 'context_topology_uuid' in session: context_topology_form.context_topology.data = session['context_topology_uuid'] @@ -87,7 +105,7 @@ def home(): process_descriptors(descriptor_form.descriptors) return redirect(url_for("main.home")) except Exception as e: # pylint: disable=broad-except - logger.exception('Descriptor load failed') + LOGGER.exception('Descriptor load failed') flash(f'Descriptor load failed: `{str(e)}`', 'danger') finally: context_client.close() @@ -100,7 +118,7 @@ def home(): def topology(): context_client.connect() try: - if 'context_topology_uuid' not in session: + if 'context_uuid' not in session or 'topology_uuid' not in session: return jsonify({'devices': [], 'links': []}) context_uuid = session['context_uuid'] @@ -118,7 +136,7 @@ def topology(): if device.device_id.device_uuid.uuid not in topo_device_uuids: continue devices.append({ 'id': device.device_id.device_uuid.uuid, - 'name': device.device_id.device_uuid.uuid, + 'name': device.name, 'type': device.device_type, }) @@ -128,17 +146,19 @@ def topology(): if link.link_id.link_uuid.uuid not in topo_link_uuids: continue if len(link.link_endpoint_ids) != 2: str_link = grpc_message_to_json_string(link) - logger.warning('Unexpected link with len(endpoints) != 2: {:s}'.format(str_link)) + LOGGER.warning('Unexpected link with len(endpoints) != 2: {:s}'.format(str_link)) continue links.append({ 'id': link.link_id.link_uuid.uuid, + 'name': link.name, 'source': link.link_endpoint_ids[0].device_id.device_uuid.uuid, 'target': link.link_endpoint_ids[1].device_id.device_uuid.uuid, }) return jsonify({'devices': devices, 'links': links}) - except: - logger.exception('Error retrieving topology') + except: # pylint: disable=bare-except + LOGGER.exception('Error retrieving topology') + return jsonify({'devices': [], 'links': []}) finally: context_client.close() diff --git a/src/webui/service/service/__init__.py b/src/webui/service/service/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/service/service/__init__.py +++ b/src/webui/service/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/service/routes.py b/src/webui/service/service/routes.py index bc05daee3e4ff8795c26bed9e0707b9a3ab2be7c..ee9b092ae6828d7e2a82c66b1461c2f90853a803 100644 --- a/src/webui/service/service/routes.py +++ b/src/webui/service/service/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,7 +14,8 @@ import grpc from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for -from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceList, ServiceTypeEnum, ServiceStatusEnum, Connection +from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection +from common.tools.context_queries.EndPoint import get_endpoint_names from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient @@ -39,18 +40,25 @@ def home(): service_list = context_client.ListServices(request) # print(service_list) services = service_list.services - context_not_found = False + context_found = True except grpc.RpcError as e: if e.code() != grpc.StatusCode.NOT_FOUND: raise if e.details() != 'Context({:s}) not found'.format(context_uuid): raise services = [] - context_not_found = True + context_found = False + + if context_found: + endpoint_ids = [] + for service_ in services: + endpoint_ids.extend(service_.service_endpoint_ids) + device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) + else: + device_names, endpoints_data = [],[] context_client.close() - return render_template('service/home.html', services=services, - context_not_found=context_not_found, - ste=ServiceTypeEnum, - sse=ServiceStatusEnum) + return render_template( + 'service/home.html', services=services, device_names=device_names, endpoints_data=endpoints_data, + context_not_found=not context_found, ste=ServiceTypeEnum, sse=ServiceStatusEnum) @service.route('add', methods=['GET', 'POST']) @@ -74,13 +82,22 @@ def detail(service_uuid: str): context_client.connect() response: Service = context_client.GetService(request) connections: Connection = context_client.ListConnections(request) + connections = connections.connections + + endpoint_ids = [] + endpoint_ids.extend(response.service_endpoint_ids) + for connection in connections: + endpoint_ids.extend(connection.path_hops_endpoint_ids) + device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) + context_client.close() except Exception as e: flash('The system encountered an error and cannot show the details of this service.', 'warning') current_app.logger.exception(e) return redirect(url_for('service.home')) - return render_template('service/detail.html', service=response, connections=connections,ste=ServiceTypeEnum, - sse=ServiceStatusEnum) + return render_template( + 'service/detail.html', service=response, connections=connections, device_names=device_names, + endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum) @service.get('/delete') @@ -102,4 +119,4 @@ def delete(service_uuid: str): except Exception as e: flash('Problem deleting service "{:s}": {:s}'.format(service_uuid, str(e.details())), 'danger') current_app.logger.exception(e) - return redirect(url_for('service.home')) \ No newline at end of file + return redirect(url_for('service.home')) diff --git a/src/webui/service/slice/__init__.py b/src/webui/service/slice/__init__.py index 70a33251242c51f49140e596b8208a19dd5245f7..1549d9811aa5d1c193a44ad45d0d7773236c0612 100644 --- a/src/webui/service/slice/__init__.py +++ b/src/webui/service/slice/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/slice/routes.py b/src/webui/service/slice/routes.py index c5287501362db88edaf334426ca6e6d0e3331ef2..222508418a187bcab18f7d44fccf896c917c6821 100644 --- a/src/webui/service/slice/routes.py +++ b/src/webui/service/slice/routes.py @@ -1,4 +1,4 @@ -# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -14,22 +14,18 @@ # import grpc from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for -from common.proto.context_pb2 import ContextId, Slice, SliceId, SliceList, Connection, SliceStatusEnum +from common.proto.context_pb2 import ContextId, Slice, SliceId, SliceStatusEnum +from common.tools.context_queries.EndPoint import get_endpoint_names from context.client.ContextClient import ContextClient -#from slice.client.SliceClient import SliceClient - - +from slice.client.SliceClient import SliceClient slice = Blueprint('slice', __name__, url_prefix='/slice') context_client = ContextClient() -#slice_client = SliceClient() +slice_client = SliceClient() @slice.get('/') def home(): - # flash('This is an info message', 'info') - # flash('This is a danger message', 'danger') - context_uuid = session.get('context_uuid', '-') if context_uuid == "-": flash("Please select a context!", "warning") @@ -39,25 +35,36 @@ def home(): context_client.connect() try: slice_list = context_client.ListSlices(request) - # print(slice_list) slices = slice_list.slices - context_not_found = False + context_found = True except grpc.RpcError as e: if e.code() != grpc.StatusCode.NOT_FOUND: raise if e.details() != 'Context({:s}) not found'.format(context_uuid): raise slices = [] - context_not_found = True + context_found = False + + if context_found: + endpoint_ids = [] + for slice_ in slices: + endpoint_ids.extend(slice_.slice_endpoint_ids) + device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) + else: + device_names, endpoints_data = [],[] + context_client.close() - return render_template('slice/home.html',slices=slices, context_not_found=context_not_found, sse=SliceStatusEnum) -# -#@slice.route('add', methods=['GET', 'POST']) -#def add(): -# flash('Add slice route called', 'danger') -# raise NotImplementedError() -# return render_template('slice/home.html') -# -# + return render_template( + 'slice/home.html', slices=slices, device_names=device_names, endpoints_data=endpoints_data, + context_not_found=not context_found, sse=SliceStatusEnum) + + +@slice.route('add', methods=['GET', 'POST']) +def add(): + flash('Add slice route called', 'danger') + raise NotImplementedError() + return render_template('slice/home.html') + + @slice.get('/detail') def detail(slice_uuid: str): context_uuid = session.get('context_uuid', '-') @@ -74,13 +81,20 @@ def detail(slice_uuid: str): context_client.connect() response: Slice = context_client.GetSlice(request) services = context_client.ListServices(req) + + endpoint_ids = [] + endpoint_ids.extend(response.slice_endpoint_ids) + device_names, endpoints_data = get_endpoint_names(context_client, endpoint_ids) + context_client.close() except Exception as e: flash('The system encountered an error and cannot show the details of this slice.', 'warning') current_app.logger.exception(e) return redirect(url_for('slice.home')) - return render_template('slice/detail.html', slice=response, sse=SliceStatusEnum, services=services) -# + return render_template( + 'slice/detail.html', slice=response, device_names=device_names, endpoints_data=endpoints_data, + sse=SliceStatusEnum, services=services) + #@slice.get('/delete') #def delete(slice_uuid: str): # context_uuid = session.get('context_uuid', '-') @@ -100,4 +114,4 @@ def detail(slice_uuid: str): # except Exception as e: # flash('Problem deleting slice "{:s}": {:s}'.format(slice_uuid, str(e.details())), 'danger') # current_app.logger.exception(e) -# return redirect(url_for('slice.home')) \ No newline at end of file +# return redirect(url_for('slice.home')) diff --git a/src/webui/service/templates/base.html b/src/webui/service/templates/base.html index bee98ee82da3482caf1fad930d03d30572ba287d..0aa022f1453eaa33a67212174cf9687a942b10f0 100644 --- a/src/webui/service/templates/base.html +++ b/src/webui/service/templates/base.html @@ -1,7 +1,7 @@ + +{% extends 'base.html' %} + +{% block content %} +

Add New Configuration

+
+
+ {{ form.hidden_tag() }} +
+
+ {{ form.device_key_config.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_key_config.errors %} + {{ form.device_key_config(class="form-control is-invalid") }} +
+ {% for error in form.device_key_config.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.device_key_config(class="form-control") }} + {% endif %} +
+
+
+
+ {{ form.device_value_config.label(class="col-sm-2 col-form-label") }} +
+ {% if form.device_value_config.errors %} + {{ form.device_value_config(class="form-control is-invalid") }} +
+ {% for error in form.device_value_config.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.device_value_config(class="form-control") }} + {% endif %} +
+
+
+
+ + +
+
+
+{% endblock %} \ 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 69ca93727310db7f89034f56510ceb5df504083f..de8bb4a81da5e595f33297070697b528dff26ff4 100644 --- a/src/webui/service/templates/device/detail.html +++ b/src/webui/service/templates/device/detail.html @@ -1,5 +1,5 @@ - - {% extends 'base.html' %} - - {% block content %} -

Device {{ device.device_id.device_uuid.uuid }}

- -
-
- -
- -
- - -
-
-
-
-
- UUID: {{ device.device_id.device_uuid.uuid }}

- Type: {{ device.device_type }}

- Status: {{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }}
- Drivers: -
    - {% for driver in device.device_drivers %} -
  • {{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}
  • - {% endfor %} -
-
-
- - - - - - - - - {% for endpoint in device.device_endpoints %} - - - - - {% endfor %} - -
EndpointsType
- {{ endpoint.endpoint_id.endpoint_uuid.uuid }} - - {{ endpoint.endpoint_type }} -
-
-
- +{% extends 'base.html' %} - Configurations: +{% block content %} +

Device {{ device.name }} ({{ device.device_id.device_uuid.uuid }})

+ +
+
+ +
+ +
+ + +
+
+ +
+
+
+ UUID: {{ device.device_id.device_uuid.uuid }}
+ Name: {{ device.name }}
+ Type: {{ device.device_type }}
+ Status: {{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }}
+ Drivers: +
    + {% for driver in device.device_drivers %} +
  • {{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}
  • + {% endfor %} +
+
+
- - + + + - {% for config in device.device_config.config_rules %} - {% if config.WhichOneof('config_rule') == 'custom' %} + {% for endpoint in device.device_endpoints %} + - {% endif %} {% endfor %}
KeyValueEndpoint UUIDNameType
- {{ config.custom.resource_key }} + {{ endpoint.endpoint_id.endpoint_uuid.uuid }} + + {{ endpoint.name }} -
    - {% for key, value in (config.custom.resource_value | from_json).items() %} -
  • {{ key }}: {{ value }}
  • - {% endfor %} -
+ {{ endpoint.endpoint_type }}
+
+
+ +Configurations: - - - - {% endblock %} - \ No newline at end of file + + + + + + + + + + + {% for config in device.device_config.config_rules %} + {% if config.WhichOneof('config_rule') == 'custom' %} + + + + + + + {% endif %} + {% endfor %} + +
KeyValue
+ {{ config.custom.resource_key }} + +
    + {% for item_type, item in json_to_list(config.custom.resource_value) %} + {% if item_type == 'kv' %} +
  • {{ item[0] }}: {{ item[1] }}
  • + {% else %} +
  • {{ item }}
  • + {% endif %} + {% endfor %} +
+
+ + + + + + +
+ + + + + + +{% endblock %} diff --git a/src/webui/service/templates/device/home.html b/src/webui/service/templates/device/home.html index 2c108add96df7de413f5310d4bd9e3c3fb69a6ed..53434196f85c3a8c79fe9b861204e9bd8c6a5d8f 100644 --- a/src/webui/service/templates/device/home.html +++ b/src/webui/service/templates/device/home.html @@ -1,5 +1,5 @@ + Config Rules @@ -55,39 +56,16 @@ {% if devices %} {% for device in devices %} - - - {{ device.device_id.device_uuid.uuid }} - - - - {{ device.device_type }} - - -
    - {% for end_point in device.device_endpoints %} -
  • {{ end_point.endpoint_id.endpoint_uuid.uuid }}
  • - {% endfor %} -
- - -
    - {% for driver in device.device_drivers %} -
  • {{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}
  • - {% endfor %} -
- + {{ device.device_id.device_uuid.uuid }} + {{ device.name }} + {{ device.device_type }} + {{ device.device_endpoints | length }} +
    {% for driver in device.device_drivers %} +
  • {{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}
  • + {% endfor %} +
{{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }} - + {{ device.device_config.config_rules | length }} diff --git a/src/webui/service/templates/device/update.html b/src/webui/service/templates/device/update.html new file mode 100644 index 0000000000000000000000000000000000000000..9fe53fa02360d7eaa41eec761f6dd4743ff2e229 --- /dev/null +++ b/src/webui/service/templates/device/update.html @@ -0,0 +1,51 @@ + + +{% extends 'base.html' %} + +{% block content %} +

Update Device {{ device.device_id.device_uuid.uuid }}

+
+
+ {{ form.hidden_tag() }} +
+
+ {{ form.update_operational_status.label(class="col-sm-2 col-form-label") }} +
+ {% if form.update_operational_status.errors %} + {{ form.update_operational_status(class="form-control is-invalid") }} +
+ {% for error in form.update_operational_status.errors %} + {{ error }} + {% endfor %} +
+ {% else %} + {{ form.update_operational_status(class="form-select") }} + {% endif %} +
+
+ + + +
+
+{% endblock %} \ No newline at end of file diff --git a/src/webui/service/templates/device/updateconfig.html b/src/webui/service/templates/device/updateconfig.html new file mode 100644 index 0000000000000000000000000000000000000000..84df4e51c7477c1faa92894c02495f9e28cfc25f --- /dev/null +++ b/src/webui/service/templates/device/updateconfig.html @@ -0,0 +1,18 @@ + + + +{% extends 'base.html' %} \ No newline at end of file diff --git a/src/webui/service/templates/js/site.js b/src/webui/service/templates/js/site.js index 1cd015f17cf87a6efe319d8d7090d81889e03062..06e6ff0a3b416d1f1bdc5e197ce2a8dbfccc93aa 100644 --- a/src/webui/service/templates/js/site.js +++ b/src/webui/service/templates/js/site.js @@ -1,5 +1,5 @@ /** - * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. diff --git a/src/webui/service/templates/js/topology.js b/src/webui/service/templates/js/topology.js index 69de0445dac24bf2f7f16ec21da4a6d35133e9da..50486d2a6826fedace55f7a62592fa083e7256a6 100644 --- a/src/webui/service/templates/js/topology.js +++ b/src/webui/service/templates/js/topology.js @@ -1,4 +1,4 @@ -// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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. @@ -88,7 +88,9 @@ d3.json("{{ url_for('main.topology') }}", function(data) { .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended)); // node tooltip - node.append("title").text(function(d) { return d.id; }); + node.append("title").text(function(n) { return n.name; }); + // link tooltip + link.append("title").text(function(l) { return l.name; }); // link style link diff --git a/src/webui/service/templates/link/detail.html b/src/webui/service/templates/link/detail.html index 7df9ddce6bdddd511f3b50313cafa1374990b99e..acac4a55392c2bf7f6261707ae1627a486affd10 100644 --- a/src/webui/service/templates/link/detail.html +++ b/src/webui/service/templates/link/detail.html @@ -1,5 +1,5 @@
- {{ links | length }} links found + {{ links | length }} links found in context {{ session['context_uuid'] }}
- {{ link.link_id.link_uuid.uuid }} - + {{ link.link_id.link_uuid.uuid }} - + + {{ link.name }} + +